neutron ml(openvswitch) agent初始化并创建br的过程
文件neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.py
agent守护进程的init
class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
l2population_rpc.L2populationRpcCallBackTunnelMixin,
dvr_rpc.DVRAgentRpcCallbackMixin):
target = oslo_messaging.Target(version='1.4')
def __init__(self, bridge_classes, conf=None):
super(OVSNeutronAgent, self).__init__()
self.conf = conf or cfg.CONF
self.ovs = ovs_lib.BaseOVS()
agent_conf = self.conf.AGENT
ovs_conf = self.conf.OVS
# ....略过部分代码
# 通过tunnel_types设置判断当天agent是否启动tun
self.tunnel_types = agent_conf.tunnel_types or []
if self.tunnel_types:
self.enable_tunneling = True
else:
self.enable_tunneling = False
# 初始化br_int, br_int类的实例不在setup_integration_br里生成
# 目的应该是为了reload的时候self.int_br不重新初始化
self.int_br = self.br_int_cls(ovs_conf.integration_bridge)
self.setup_integration_br()
# 初始化physical br
self.bridge_mappings = self._parse_bridge_mappings(
ovs_conf.bridge_mappings)
self.setup_physical_bridges(self.bridge_mappings)
# 初始化br_tun
if self.enable_tunneling:
self.setup_tunnel_br(ovs_conf.tunnel_bridge)
# ....略过其余代码
下面是是br_int的初始化
def setup_integration_br(self):
'''Setup the integration bridge.
'''
# Ensure the integration bridge is created.
# ovs_lib.OVSBridge.create() will run
# ovs-vsctl -- --may-exist add-br BRIDGE_NAME
# which does nothing if bridge already exists.
# br_int是完全由neutron-agent管理的
self.int_br.create()
self.int_br.set_secure_mode()
self.int_br.setup_controllers(self.conf)
if self.conf.AGENT.drop_flows_on_start:
# Delete the patch port between br-int and br-tun if we're deleting
# the flows on br-int, so that traffic doesn't get flooded over
# while flows are missing.
self.int_br.delete_port(self.conf.OVS.int_peer_patch_port)
self.int_br.delete_flows()
self.int_br.setup_default_table()
下面是br_tun的初始化
def setup_tunnel_br(self, tun_br_name=None):
'''(re)initialize the tunnel bridge.
Creates tunnel bridge, and links it to the integration bridge
using a patch port.
:param tun_br_name: the name of the tunnel bridge.
'''
if not self.tun_br:
self.tun_br = self.br_tun_cls(tun_br_name)
# tun_br.create() won't recreate bridge if it exists, but will handle
# cases where something like datapath_type has changed
# 注意看上面注释,在tun_br存在的情况下不会创建,只修改datapath_type
# 就目前代码来看,tun_br没有外链到具体物理网卡的过程
# 所以,应该是在系统层面设置好br_tun和并链接到物理网卡
# neutron只会重新设置br_tun的datapath_type
# 这里的处理方式和setup_physical_bridges是一样的
# 都是在neutron外部管理br和物理网卡的关联
# 只有br_int是完全由neutron agent管理的
# (注意,当时的上面关于br_tun的理解是错的,br_tun和br_ex不一样,
# 不要在系统层设置好br-tun, br-tun和br-int一样完全由openstack管理)
self.tun_br.create(secure_mode=True)
self.tun_br.setup_controllers(self.conf)
# 在br_int和br_tun上创建br_int和bt_tun相连的端口
# 做法是通过ovsdb分别在br_int和br_tun上设置local port和peer remote port
if (not self.int_br.port_exists(self.conf.OVS.int_peer_patch_port) or
self.patch_tun_ofport == ovs_lib.INVALID_OFPORT):
self.patch_tun_ofport = self.int_br.add_patch_port(
self.conf.OVS.int_peer_patch_port,
self.conf.OVS.tun_peer_patch_port)
if (not self.tun_br.port_exists(self.conf.OVS.tun_peer_patch_port) or
self.patch_int_ofport == ovs_lib.INVALID_OFPORT):
self.patch_int_ofport = self.tun_br.add_patch_port(
self.conf.OVS.tun_peer_patch_port,
self.conf.OVS.int_peer_patch_port)
if ovs_lib.INVALID_OFPORT in (self.patch_tun_ofport,
self.patch_int_ofport):
LOG.error(_LE("Failed to create OVS patch port. Cannot have "
"tunneling enabled on this agent, since this "
"version of OVS does not support tunnels or patch "
"ports. Agent terminated!"))
sys.exit(1)
if self.conf.AGENT.drop_flows_on_start:
self.tun_br.delete_flows()
下面是root的启动函数
def daemon_loop(self):
# Start everything.
LOG.info(_LI("Agent initialized successfully, now running... "))
signal.signal(signal.SIGTERM, self._handle_sigterm)
if hasattr(signal, 'SIGHUP'):
signal.signal(signal.SIGHUP, self._handle_sighup)
with polling.get_polling_manager(
self.minimize_polling,
self.ovsdb_monitor_respawn_interval) as pm:
self.rpc_loop(polling_manager=pm)