I know there's a longstanding issue with some switches that use more
than 48 bits for their DPIDs.  This problem stemming from the fact that
discovery stuffs the DPID into a MAC subtype chassis ID TLV in the LLDP
packet it sends out, which obviously only has 48 bits.  Thus, when we
get the LLDP packet back, the MAC/DPID in it doesn't match one of our
DPIDs because the top bits have been stripped off.

I notice that the chassis ID TLV also has a "local" subtype.  According
to 802.1AB-2005 (which isn't the current version), this is "an
alpha-numeric string and is locally assigned".  Can we just stuff the
DPID in there as a string?  Maybe prepend "dpid:" to weed out anything
else that may use it and to look nice for other tools?

I've attached a patch.  Maybe someone would tell me what they think?  I
don't have any of the problematic switches to play with, though I did
specify large dpids in OVS and had them work now.

-- Murphy
diff --git a/src/nox/netapps/discovery/discovery.py b/src/nox/netapps/discovery/discovery.py
index 426d9b2..a68e839 100644
--- a/src/nox/netapps/discovery/discovery.py
+++ b/src/nox/netapps/discovery/discovery.py
@@ -62,7 +62,7 @@ def create_discovery_packet(dpid, portno, ttl_):
     cid = chassis_id()
 
     # nbo 
-    cid.fill(4, array.array('B', struct.pack('!Q',dpid))[2:8])
+    cid.fill(chassis_id.SUB_LOCAL, array.array('B', 'dpid:' + hex(long(dpid))[2:-1]))
     discovery_packet.add_tlv(cid)
 
     pid = port_id()
@@ -264,16 +264,17 @@ class discovery(Component):
             return
 
         # parse out chassis id 
-        if lldph.tlvs[0].subtype != chassis_id.SUB_MAC:
-            lg.error("lldp chassis ID subtype is not MAC, ignoring")
+        if lldph.tlvs[0].subtype != chassis_id.SUB_LOCAL:
+            lg.error("lldp chassis ID subtype is not 'local', ignoring")
+            return
+        if not lldph.tlvs[0].id.tostring().startswith('dpid:'):
+            lg.error("lldp chassis ID is not a dpid, ignoring")
+            return
+        try:
+            chassid = int(lldph.tlvs[0].id.tostring()[5:], 16)
+        except:
+            lg.error("lldp chassis ID is not numeric', ignoring")
             return
-        assert(len(lldph.tlvs[0].id) == 6)
-        cid = lldph.tlvs[0].id
-    
-        # convert 48bit cid (in nbo) to longlong
-        chassid = cid[5]       | cid[4] << 8  | \
-                  cid[3] << 16 | cid[2] << 24 |  \
-                  cid[1] << 32 | cid[0] << 40 
 
         # if chassid is from a switch we're not connected to, ignore
         if chassid not in self.dps:
_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev_noxrepo.org

Reply via email to