]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add new ovs DB API to inquire interfaces name list in a bridge
authorYalei Wang <yalei.wang@intel.com>
Tue, 9 Jun 2015 05:46:57 +0000 (13:46 +0800)
committerYalei Wang <yalei.wang@intel.com>
Wed, 22 Jul 2015 07:15:12 +0000 (15:15 +0800)
In OVS, ports don't equal to interfaces when a bond port created. This patch
add the new API get_iface_name_list to get the interfaces' name, and it's
supplementary to the current get_port_name_list API.

Change-Id: I29c220e099b8dcf78248e2d660c435578bb2932d
Partial-Bug: #1460494

neutron/agent/common/ovs_lib.py
neutron/agent/ovsdb/api.py
neutron/agent/ovsdb/impl_idl.py
neutron/agent/ovsdb/impl_vsctl.py
neutron/agent/ovsdb/native/commands.py
neutron/tests/functional/agent/test_ovs_lib.py

index 49c7a6e9c19d0c8efb688dd954d0c895f2fa2ea4..a26f16e51322e2774e0ad6cfeafb335600983b95 100644 (file)
@@ -304,7 +304,12 @@ class OVSBridge(BaseOVS):
                  ('options', {'peer': remote_name})]
         return self.add_port(local_name, *attrs)
 
+    def get_iface_name_list(self):
+        # get the interface name list for this bridge
+        return self.ovsdb.list_ifaces(self.br_name).execute(check_error=True)
+
     def get_port_name_list(self):
+        # get the port name list for this bridge
         return self.ovsdb.list_ports(self.br_name).execute(check_error=True)
 
     def get_port_stats(self, port_name):
index e696f8e85d60da4df14529a33bac0bae2e6d2d25..58fb135f552ec5b4b2a46bf01658b227ca1cfe86 100644 (file)
@@ -308,13 +308,22 @@ class API(object):
 
     @abc.abstractmethod
     def list_ports(self, bridge):
-        """Create a command to list the names of porsts on a bridge
+        """Create a command to list the names of ports on a bridge
 
         :param bridge: The name of the bridge
         :type bridge:  string
         :returns:      :class:`Command` with list of port names result
         """
 
+    @abc.abstractmethod
+    def list_ifaces(self, bridge):
+        """Create a command to list the names of interfaces on a bridge
+
+        :param bridge: The name of the bridge
+        :type bridge:  string
+        :returns:      :class:`Command` with list of interfaces names result
+        """
+
 
 def val_to_py(val):
     """Convert a json ovsdb return value to native python object"""
index 5b15472874d666442a9837afc845e3c771389bc4..4edb407c3666cf6fbd75d6b60a3345a76be33e62 100644 (file)
@@ -157,8 +157,7 @@ class OvsdbIdl(api.API):
         return cmd.PortToBridgeCommand(self, name)
 
     def iface_to_br(self, name):
-        # For our purposes, ports and interfaces always have the same name
-        return cmd.PortToBridgeCommand(self, name)
+        return cmd.InterfaceToBridgeCommand(self, name)
 
     def list_br(self):
         return cmd.ListBridgesCommand(self)
@@ -204,3 +203,6 @@ class OvsdbIdl(api.API):
 
     def list_ports(self, bridge):
         return cmd.ListPortsCommand(self, bridge)
+
+    def list_ifaces(self, bridge):
+        return cmd.ListIfacesCommand(self, bridge)
index 15f52529b52daadf59f137599a9a68f071d55e05..aa00922979fbd9a7bf188edc8667b3067e6207c0 100644 (file)
@@ -241,6 +241,9 @@ class OvsdbVsctl(ovsdb.API):
     def list_ports(self, bridge):
         return MultiLineCommand(self.context, 'list-ports', args=[bridge])
 
+    def list_ifaces(self, bridge):
+        return MultiLineCommand(self.context, 'list-ifaces', args=[bridge])
+
 
 def _set_colval_args(*col_values):
     args = []
index 973c4cac1f4c26bd5fbff8097c8bf7a09b720202..76bb8ae78bcadf8a07e1aa55189860ea02a092c9 100644 (file)
@@ -332,6 +332,17 @@ class ListPortsCommand(BaseCommand):
         self.result = [p.name for p in br.ports if p.name != self.bridge]
 
 
+class ListIfacesCommand(BaseCommand):
+    def __init__(self, api, bridge):
+        super(ListIfacesCommand, self).__init__(api)
+        self.bridge = bridge
+
+    def run_idl(self, txn):
+        br = idlutils.row_by_value(self.api.idl, 'Bridge', 'name', self.bridge)
+        self.result = [i.name for p in br.ports if p.name != self.bridge
+                       for i in p.interfaces]
+
+
 class PortToBridgeCommand(BaseCommand):
     def __init__(self, api, name):
         super(PortToBridgeCommand, self).__init__(api)
@@ -340,7 +351,7 @@ class PortToBridgeCommand(BaseCommand):
     def run_idl(self, txn):
         # TODO(twilson) This is expensive!
         # This traversal of all ports could be eliminated by caching the bridge
-        # name on the Port's (or Interface's for iface_to_br) external_id field
+        # name on the Port's external_id field
         # In fact, if we did that, the only place that uses to_br functions
         # could just add the external_id field to the conditions passed to find
         port = idlutils.row_by_value(self.api.idl, 'Port', 'name', self.name)
@@ -348,6 +359,22 @@ class PortToBridgeCommand(BaseCommand):
         self.result = next(br.name for br in bridges if port in br.ports)
 
 
+class InterfaceToBridgeCommand(BaseCommand):
+    def __init__(self, api, name):
+        super(InterfaceToBridgeCommand, self).__init__(api)
+        self.name = name
+
+    def run_idl(self, txn):
+        interface = idlutils.row_by_value(self.api.idl, 'Interface', 'name',
+                                          self.name)
+        ports = self.api._tables['Port'].rows.values()
+        pname = next(
+                port for port in ports if interface in port.interfaces)
+
+        bridges = self.api._tables['Bridge'].rows.values()
+        self.result = next(br.name for br in bridges if pname in br.ports)
+
+
 class DbListCommand(BaseCommand):
     def __init__(self, api, table, records, columns, if_exists):
         super(DbListCommand, self).__init__(api)
index 5c5409a605d11e5c7a407e7b968fe938dd166fe8..b81e6a526658fb4a4d57ec07f8e6775c0be83126 100644 (file)
@@ -174,6 +174,10 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
         ports = {self.create_ovs_port()[0] for i in range(5)}
         self.assertSetEqual(ports, set(self.br.get_port_name_list()))
 
+    def test_get_iface_name_list(self):
+        ifaces = {self.create_ovs_port()[0] for i in range(5)}
+        self.assertSetEqual(ifaces, set(self.br.get_iface_name_list()))
+
     def test_get_port_stats(self):
         # Nothing seems to use this function?
         (port_name, ofport) = self.create_ovs_port()