dvr.py


AgentMixin类

这个类实现的什么功能呢?

floating ip的namespace,即变量_fip_namespaces采用弱引用,方便垃圾回收

self._fip_namespaces = weakref.WeakValueDictionary()

get_fip_ns()

主要用来获取floating IP的namespace,

    def get_fip_ns(self, ext_net_id):
        # TODO(Carl) is this necessary?  Code that this replaced was careful to
        # convert these to string like this so I preserved that.
        # 这里应该是外部网络分配的floating IP的ID,相当于key来进行查询
        ext_net_id = str(ext_net_id)

        # 弱引用中的get方法,根据ext_net_id获取到fip_ns
        fip_ns = self._fip_namespaces.get(ext_net_id)
        # 如果不是需要回收的就直接返回fip_ns
        if fip_ns and not fip_ns.destroyed:
            return fip_ns

        # 如果当做弱引用已经被垃圾回收了,那么就根据ext_net_id和配置文件的信息重新获得fip_ns,并返回
        # FipNamespace类是namespaces.Namespace的子类
        fip_ns = dvr_fip_ns.FipNamespace(ext_net_id,
                                         self.conf,
                                         self.driver,
                                         self.use_ipv6)
        self._fip_namespaces[ext_net_id] = fip_ns

        return fip_ns

get_ports_by_subnet()

相当于client端的RPC调用,即L3PluginApi的get_ports_by_subnet()来根据subnet_id得到端口信息。

    def get_ports_by_subnet(self, subnet_id):
        return self.plugin_rpc.get_ports_by_subnet(self.context, subnet_id)

add_arp_entry()

主要是根据subnet在route的ns中添加ARP实体


    def add_arp_entry(self, context, payload):
        """Add arp entry into router namespace.  Called from RPC."""
        router_id = payload['router_id']
        ri = self.router_info.get(router_id)
        if not ri:
            return

        arp_table = payload['arp_table']
        ip = arp_table['ip_address']
        mac = arp_table['mac_address']
        subnet_id = arp_table['subnet_id']
        ri._update_arp_entry(ip, mac, subnet_id, 'add')

del_arp_entry()

主要是根据subnet在route的ns中删除ARP实体


    def del_arp_entry(self, context, payload):
        """Delete arp entry from router namespace.  Called from RPC."""
        router_id = payload['router_id']
        ri = self.router_info.get(router_id)
        if not ri:
            return

        arp_table = payload['arp_table']
        ip = arp_table['ip_address']
        mac = arp_table['mac_address']
        subnet_id = arp_table['subnet_id']
        ri._update_arp_entry(ip, mac, subnet_id, 'delete')

_update_arp_entry方法可以根据不同的操作,来进行添加和删除,这个方法位于DvrLocalRouter类中

def _update_arp_entry(self, ip, mac, subnet_id, operation):
        """Add or delete arp entry into router namespace for the subnet."""
        # 得到port信息
        port = self._get_internal_port(subnet_id)
        # update arp entry only if the subnet is attached to the router
        if not port:
            return False

        try:
            # TODO(mrsmith): optimize the calls below for bulk calls
            # 根据port信息得到device,并利用Linux包中的方法对device进行操作
            interface_name = self.get_internal_device_name(port['id'])
            device = ip_lib.IPDevice(interface_name, namespace=self.ns_name)
            if ip_lib.device_exists(interface_name, self.ns_name):
                if operation == 'add':
                    device.neigh.add(ip, mac)
                elif operation == 'delete':
                    device.neigh.delete(ip, mac)
                return True
            else:
                if operation == 'add':
                    LOG.warn(_LW("Device %s does not exist so ARP entry "
                                 "cannot be updated, will cache information "
                                 "to be applied later when the device exists"),
                             device)
                    self._cache_arp_entry(ip, mac, subnet_id, operation)
                return False
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE("DVR: Failed updating arp entry"))

python学习小结:python中的weakref(弱引用) 使用weakref模块的WeakKeyDictionary和WeakValueDictionary类对对象进行弱引用,则可以减少资源占用,方便进行内存回收。

results matching ""

    No results matching ""