先看Ml2Plugin:

class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,external_net_db.External_net_db_mixin,sg_db_rpc.SecurityGroupServerRpcMixin,agentschedulers_db.DhcpAgentSchedulerDbMixin,addr_pair_db.AllowedAddressPairsMixin,extradhcpopt_db.ExtraDhcpOptMixin):......def start_rpc_listener(self):self.callbacks = rpc.RpcCallbacks(self.notifier, self.type_manager)self.topic = topics.PLUGIN # q-pluginself.conn = c_rpc.create_connection(new=True)self.dispatcher = self.callbacks.create_rpc_dispatcher()self.conn.create_consumer(self.topic, self.dispatcher,fanout=False)return self.conn.consume_in_thread()......

看一看RpcCallbacks:

class RpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin,sg_db_rpc.SecurityGroupServerRpcCallbackMixin,type_tunnel.TunnelRpcCallbackMixin):RPC_API_VERSION = '1.1'# history#   1.0 Initial version (from openvswitch/linuxbridge)#   1.1 Support Security Group RPCdef __init__(self, notifier, type_manager):super(RpcCallbacks, self).__init__(notifier, type_manager)def create_rpc_dispatcher(self):'''Get the rpc dispatcher for this manager.If a manager would like to set an rpc API version, or support more thanone class as the target of rpc messages, override this method.'''return q_rpc.PluginRpcDispatcher([self,agents_db.AgentExtRpcCallback()])

其中比较重要的几个回调函数:

1.get_device_details(self, rpc_context, **kwargs):

    def get_device_details(self, rpc_context, **kwargs):"""Agent requests device details."""agent_id = kwargs.get('agent_id')device = kwargs.get('device')LOG.debug(_("Device %(device)s details requested by agent ""%(agent_id)s"),{'device': device, 'agent_id': agent_id})port_id = self._device_to_port_id(device)session = db_api.get_session()with session.begin(subtransactions=True):port = db.get_port(session, port_id)if not port:LOG.warning(_("Device %(device)s requested by agent ""%(agent_id)s not found in database"),{'device': device, 'agent_id': agent_id})return {'device': device}segments = db.get_network_segments(session, port.network_id)if not segments:LOG.warning(_("Device %(device)s requested by agent ""%(agent_id)s has network %(network_id)s with ""no segments"),{'device': device,'agent_id': agent_id,'network_id': port.network_id})return {'device': device}binding = db.ensure_port_binding(session, port.id)if not binding.segment:LOG.warning(_("Device %(device)s requested by agent ""%(agent_id)s on network %(network_id)s not ""bound, vif_type: %(vif_type)s"),{'device': device,'agent_id': agent_id,'network_id': port.network_id,'vif_type': binding.vif_type})return {'device': device}segment = self._find_segment(segments, binding.segment)if not segment:LOG.warning(_("Device %(device)s requested by agent ""%(agent_id)s on network %(network_id)s ""invalid segment, vif_type: %(vif_type)s"),{'device': device,'agent_id': agent_id,'network_id': port.network_id,'vif_type': binding.vif_type})return {'device': device}new_status = (q_const.PORT_STATUS_BUILD if port.admin_state_upelse q_const.PORT_STATUS_DOWN)if port.status != new_status:plugin = manager.NeutronManager.get_plugin()plugin.update_port_status(rpc_context,port_id,new_status)port.status = new_statusentry = {'device': device,'network_id': port.network_id,'port_id': port.id,'admin_state_up': port.admin_state_up,'network_type': segment[api.NETWORK_TYPE],'segmentation_id': segment[api.SEGMENTATION_ID],'physical_network': segment[api.PHYSICAL_NETWORK]}LOG.debug(_("Returning: %s"), entry)return entry

注意返回的内容

然后到了检查新的或者增加的端口信息的时候。。

    def process_network_ports(self, port_info, ovs_restarted):resync_a = Falseresync_b = Falseself.sg_agent.setup_port_filters(port_info.get('added', set()),port_info.get('updated', set()))devices_added_updated = (port_info.get('added', set()) |port_info.get('updated', set()))if devices_added_updated:start = time.time()try:skipped_devices = self.treat_devices_added_or_updated(devices_added_updated, ovs_restarted) # 注意这一句port_info['current'] = (port_info['current'] -set(skipped_devices))except DeviceListRetrievalError:LOG.exception(_("process_network_ports - iteration:%d - ""failure while retrieving port details ""from server"), self.iter_num)resync_a = Trueif 'removed' in port_info:start = time.time()resync_b = self.treat_devices_removed(port_info['removed'])return (resync_a | resync_b)

然后是注意的这句:

    def treat_devices_added_or_updated(self, devices, ovs_restarted):skipped_devices = []devices_details_list = []for device in devices:try:devices_details_list.append(self.plugin_rpc.get_device_details(self.context, device, self.agent_id)) ## 这句会返回detailsexcept Exception as e:raise DeviceListRetrievalError(devices=devices, error=e)for details in devices_details_list:device = details['device']LOG.debug(_("Processing port %s"), device)port = self.int_br.get_vif_port_by_id(device)if not port:skipped_devices.append(device)continueif 'port_id' in details:self.treat_vif_port(port, details['port_id'],details['network_id'],details['network_type'],details['physical_network'],details['segmentation_id'],details['admin_state_up'],ovs_restarted)if details.get('admin_state_up'):self.plugin_rpc.update_device_up(self.context, device, self.agent_id, cfg.CONF.host)else:LOG.debug(_("Setting status for %s to DOWN"), device)self.plugin_rpc.update_device_down(self.context, device, self.agent_id, cfg.CONF.host)LOG.info(_("Configuration for device %s completed."), device)else:LOG.warn(_("Device %s not defined on plugin"), device)if (port and port.ofport != -1):self.port_dead(port)return skipped_devices

然后是 treat_vif_port:

    def treat_vif_port(self, vif_port, port_id, network_id, network_type,physical_network, segmentation_id, admin_state_up,ovs_restarted):if not vif_port.ofport:LOG.warn(_("VIF port: %s has no ofport configured, and might not ""be able to transmit"), vif_port.vif_id)if vif_port:if admin_state_up:self.port_bound(vif_port, network_id, network_type,physical_network, segmentation_id,ovs_restarted)else:self.port_dead(vif_port)else:LOG.debug(_("No VIF port for port %s defined on agent."), port_id)

然后是port_bound:

    def port_bound(self, port, net_uuid,network_type, physical_network, segmentation_id,ovs_restarted):if net_uuid not in self.local_vlan_map or ovs_restarted:self.provision_local_vlan(net_uuid, network_type,physical_network, segmentation_id)lvm = self.local_vlan_map[net_uuid]lvm.vif_ports[port.vif_id] = port# Do not bind a port if it's already boundcur_tag = self.int_br.db_get_val("Port", port.port_name, "tag")if cur_tag != str(lvm.vlan):self.int_br.set_db_attribute("Port", port.port_name, "tag",str(lvm.vlan))if port.ofport != -1:self.int_br.delete_flows(in_port=port.ofport)

然后就是self.provision_local_vlan:

self.provision_local_vlan(self, net_uuid, network_type, physical_network, segmentation_id):

    def provision_local_vlan(self, net_uuid, network_type, physical_network,segmentation_id):lvm = self.local_vlan_map.get(net_uuid)if lvm:lvid = lvm.vlanelse:if not self.available_local_vlans:LOG.error(_("No local VLAN available for net-id=%s"), net_uuid)returnlvid = self.available_local_vlans.pop()self.local_vlan_map[net_uuid] = LocalVLANMapping(lvid,network_type,physical_network,segmentation_id)LOG.info(_("Assigning %(vlan_id)s as local vlan for ""net-id=%(net_uuid)s"),{'vlan_id': lvid, 'net_uuid': net_uuid})if network_type in constants.TUNNEL_NETWORK_TYPES:if self.enable_tunneling:ofports = ','.join(self.tun_br_ofports[network_type].values())if ofports:self.tun_br.mod_flow(table=constants.FLOOD_TO_TUN,dl_vlan=lvid,actions="strip_vlan,""set_tunnel:%s,output:%s" %(segmentation_id, ofports))self.tun_br.add_flow(table=constants.TUN_TABLE[network_type],priority=1,tun_id=segmentation_id,actions="mod_vlan_vid:%s,resubmit(,%s)" %(lvid, constants.LEARN_FROM_TUN))else:LOG.error(_("Cannot provision %(network_type)s network for ""net-id=%(net_uuid)s - tunneling disabled"),{'network_type': network_type,'net_uuid': net_uuid})elif network_type == p_const.TYPE_FLAT:if physical_network in self.phys_brs:# outboundbr = self.phys_brs[physical_network]br.add_flow(priority=4,in_port=self.phys_ofports[physical_network],dl_vlan=lvid,actions="strip_vlan,normal") # string vlan# inboundself.int_br.add_flow(priority=3,in_port=self.int_ofports[physical_network],dl_vlan=0xffff,actions="mod_vlan_vid:%s,normal" % lvid) ## flat网络也是有内部vlan号的else:LOG.error(_("Cannot provision flat network for ""net-id=%(net_uuid)s - no bridge for ""physical_network %(physical_network)s"),{'net_uuid': net_uuid,'physical_network': physical_network})elif network_type == p_const.TYPE_VLAN: # 重点是vlan这块的。。if physical_network in self.phys_brs:# outboundbr = self.phys_brs[physical_network]br.add_flow(priority=4,in_port=self.phys_ofports[physical_network],dl_vlan=lvid,actions="mod_vlan_vid:%s,normal" % segmentation_id) # 内部vlan改成外部vlan# inboundself.int_br.add_flow(priority=3,in_port=self.int_ofports[physical_network],dl_vlan=segmentation_id,actions="mod_vlan_vid:%s,normal" % lvid) # 外部vlan改成内部vlanelse:LOG.error(_("Cannot provision VLAN network for ""net-id=%(net_uuid)s - no bridge for ""physical_network %(physical_network)s"),{'net_uuid': net_uuid,'physical_network': physical_network})elif network_type == p_const.TYPE_LOCAL:# no flows needed for local networkspasselse:LOG.error(_("Cannot provision unknown network type ""%(network_type)s for net-id=%(net_uuid)s"),{'network_type': network_type,'net_uuid': net_uuid})

[总结篇4] l2-agent的细节相关推荐

  1. 【面试篇】ConcurrentHashMap1.8 扩容细节

    ConcurrentHashMap1.8 扩容细节 [面试篇]数据结构-哈希表 [面试篇]HashMap常见面试题目 [面试篇]HashMap1.7和HashMap1.8的详细区别对比 [面试篇]Co ...

  2. 修身修心的1000+篇文章总结

    修身修心的1000+篇文章总结 本文收集和总结了有关修身修心的1000+篇文章,由于篇幅有限只能总结近期的内容,想了解更多内容可以访问:http://www.ai2news.com/, 其分享了有关A ...

  3. 零基础学习openstack【完整中级篇】及openstack资源汇总

    1.你是如何学习openstack的? 2.你对openstack的组件了解多少? 3.你认为openstack该如何学习? 一直想写关于openstack的方面的内容,今天终于整理完成.算是完成一桩 ...

  4. 14篇论文拿捏Diffusion

    本文转载于底部链接,只作为学习使用 扩散模型自2020年的DDPM以来,以其种种优异的特性(如训练简便,对数据分布拟合效果极好,本身的构造体系使得性质调控更加优雅直接等),在两年来横扫整个学术界,甚至 ...

  5. Python从入门到精通 - 入门篇 (上)

    转载自微信公众号:王的机器 0 引言 微信公众号终于可以插代码了,Python 可以走一波了.首先我承认不是硬核搞 IT 的,太高级的玩法也玩不来,讲讲下面基本的还可以,之后带点机器学习.金融工程和量 ...

  6. 5加载stm32 keil_快速入门STM32单片机-软件篇

    关于这个STM32的编程开发环境Keil,网上有太多相关的资源了,而且大都讲解的非常详细.所以本篇文章无意于深入细节,只会提供我学习时候的一些体会,帮助你更好的掌握相关知识. 1.标准外设库(Stan ...

  7. Steve Lin:如何撰写一篇优秀的SIGGRAPH论文

     英文原版 PPT下载:http://vdisk.weibo.com/s/z7VKRh2i3R4YO 一篇优秀的论文应该是这样的 广大的研究同仁介绍了这篇论文所包含的重要想法和所获得的结果 在论文中描 ...

  8. Spring+SpringMVC+MyBatis+easyUI整合基础篇(十)SVN搭建

    前言 前面一篇文章讲了一下版本控制,但其实这一篇并没有打算讲细节的,感觉应该自己去动手弄一下,后来考虑了一下,版本控制真的挺重要的,如果自己实在搭建不好反而不去使用的话,真的有点可惜,当然这些话是针对 ...

  9. SQL2005性能分析一些细节功能你是否有用到?(二)

    上一篇:SQL2005性能分析一些细节功能你是否有用到? 我简单的提到了些关于SQL性能分析最基本的一些方法,下面的文章我会陆续补充.前面提到了根据SQL的执行IO和执行计划来分析,还有一个特别重要的 ...

  10. 【面试篇】ConcurrentHashMap1.7和1.8详解对比

    ConcurrentHashMap1.7和1.8详解对比 [面试篇]数据结构-哈希表 [面试篇]HashMap常见面试题目 [面试篇]HashMap1.7和HashMap1.8的详细区别对比 [面试篇 ...

最新文章

  1. 学习Python遇到的热门问题整理
  2. 【转】Docker —— 从入门到实践
  3. 浅谈a标签属性href的mailto更多用法
  4. FB面经Prepare: Email User
  5. AIMS/MapGuide API二次开发从入门到精通视频课程系列--2
  6. mysqld install mysql default_MySQL安装默认配置
  7. IIS7中使用集成模式时出现HttpException
  8. OPPO K9 Pro将于9月26日登场:搭载天玑1200旗舰游戏芯
  9. catia文本时怎么换行_【二次开发】CATIA二维图 环形文字工具
  10. 添加库文件_S7200的库文件导至200SMART正确操作
  11. matlab工具箱使用50hz低通滤波器设计 和FFT 变化截取50hz工频信号幅值
  12. Windows Forms Programming In C# 读书笔记 - 第三章 Dialogs (2)
  13. 最近使用VirtualBox安装虚拟机,频繁崩溃。是不是有什么隐藏限制?
  14. 控制网平差(C++实现)
  15. 小程序 | 微信小程序实现倒计时(节日校庆日等倒计时)
  16. iphone模拟器目录
  17. Mysql存储过程-新增数据时多条件判定是否已经存在某值
  18. 笔记本电脑性能分析记
  19. 200套工作室设计行业响应式Html5模板HTML5+CSS3设计网站模板简洁设计师作品展示响应式模板整洁扁平宽屏CSS3网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机se
  20. 产业区块链一周动态丨深圳龙华区与腾讯共建产业区块链联盟,新四板试水区块链...

热门文章

  1. ubuntu 10.04 常用 设置
  2. windows 7 在使用无线路由或者插线出现×××感叹号排除方法
  3. 做最好的自己,人生十件事(事业,人生,情感)
  4. Windows Phone 7 XNA开发之关于图形的配置
  5. 【转】校园网综合布线系统设计方案
  6. Redis介绍使用及进阶
  7. 学习 PixiJS — 碰撞检测
  8. REST POST PUT差别
  9. 01.MyBatis快速入门
  10. CoFun 1612 单词分组(容斥)