Fix incorrect leaf MAC tracking

pull/13/head
Ken 2021-02-10 23:01:54 -05:00
parent aa8745535e
commit d9ceeefc3c
2 changed files with 29 additions and 10 deletions

View File

@ -302,7 +302,8 @@ class netNode():
self.logger.info("+ Updated links %s", self.links)
def update_leaf_ports(self):
self._leaf_prts = set(pno for pno in self.port_state if pno not in self.links)
# self._leaf_prts = set(pno for pno in self.port_state if pno not in self.links)
self._leaf_prts = {1, 4294967294}
self.logger.info("+ Updated leaf ports: %s", str(self._leaf_prts))
def add_port(self, ofpport):
@ -385,6 +386,9 @@ class PeerSwitch():
format(self.rnid[:7], self.port_no, self.hop_count, self.leaf_macs)
class LearningTable():
NoTrackMac = ["00:00:00:00:00:00", "ff:ff:ff:ff:ff:ff", "01:00:5e:00:00:00",
"ff:ff:ff:ff:ff:00", "33:33:00:00:00:00", "ff:ff:00:00:00:00"]
def __init__(self, ryu):
self._dpid = None
self._nid = None # local node id
@ -433,6 +437,9 @@ class LearningTable():
return self.ingress_tbl.get(key_mac, None)
def __setitem__(self, key_mac, value):
if key_mac in self.NoTrackMac:
self.logger.debug("Ignoring source mac {0} from {1}".format(key_mac, value))
return
self._ts_tbl[key_mac] = time.time()
if isinstance(value, tuple):
self.learn(src_mac=key_mac, in_port=value[0], rnid=value[1])
@ -484,10 +491,12 @@ class LearningTable():
"""
self.ingress_tbl[src_mac] = in_port
if in_port in self.leaf_ports:
self.logger.debug("learn: add loocal leaf mac %s", src_mac)
self.peersw_tbl[self._nid].leaf_macs.add(src_mac)
elif rnid:
if rnid not in self.peersw_tbl:
self.peersw_tbl[rnid] = PeerSwitch(rnid)
self.logger.debug("learn: peerid: %s, leaf_mac %s", rnid, src_mac)
self.peersw_tbl[rnid].leaf_macs.add(src_mac)
self.rootsw_tbl[src_mac] = self.peersw_tbl[rnid]
@ -515,7 +524,7 @@ class LearningTable():
self.peersw_tbl[peer_id].port_no = None
def remote_leaf_macs(self, rnid):
return self.peersw_tbl[rnid]
return self.peersw_tbl[rnid].leaf_macs
def clear(self):
self._dpid = None
@ -702,6 +711,9 @@ class BoundedFlood(app_manager.RyuApp):
# this dst mac is not in our LT
self.logger.debug("Default packet in %s %s %s %s", dpid, src, dst, in_port)
self.lt[src] = in_port
frb_type=0
if in_port != 1:
frb_type=2 # this node did not initiate the frame but it has no data on how to switch it so it must brdcast with an FRB
# check if this is a multicast frame
if eth.dst.split(':')[0] == '01':
if self._handle_multicast_frame(msg,is_igmp,is_dvmrp):
@ -711,7 +723,7 @@ class BoundedFlood(app_manager.RyuApp):
if not fld:
fld = FloodingBounds(self.nodes[dpid])
self.flooding_bounds[dpid] = fld
out_bounds = fld.bounds(None, [in_port])
out_bounds = fld.bounds(None, [in_port], frb_type)
self.logger.info("<--\nGenerated FRB(s)=%s", out_bounds)
if out_bounds:
self.do_bounded_flood(datapath, in_port, out_bounds, src, msg.data)
@ -1238,12 +1250,14 @@ class BoundedFlood(app_manager.RyuApp):
in_port=datapath.ofproto.OFPP_LOCAL,
actions=actions, data=graft_msg.data)
datapath.send_msg(out)
#learn src mac and rnid
self.lt[src] = (in_port, rcvd_frb.root_nid)
if rcvd_frb.frb_type == FloodRouteBound.FRB_LEAF_TX:
self.update_leaf_macs_and_flows(datapath, rcvd_frb.root_nid, payload,
rcvd_frb.pl_count, in_port)
else:
if rcvd_frb.frb_type == FloodRouteBound.FRB_BRDCST:
#learn src mac and rnid only for frb_type == 1
self.lt[src] = (in_port, rcvd_frb.root_nid)
self.lt.peersw_tbl[rcvd_frb.root_nid].hop_count = rcvd_frb.hop_count
if rcvd_frb.hop_count > self.nodes[dpid].counters.get("MaxFloodingHopCount", 1):
self.nodes[dpid].counters["MaxFloodingHopCount"] = rcvd_frb.hop_count
@ -1272,8 +1286,9 @@ class BoundedFlood(app_manager.RyuApp):
mlen = num_items*6
for mactup in struct.iter_unpack("!6s", macs[:mlen]):
macstr = mac_lib.haddr_to_str(mactup[0])
self.logger.debug("update_leaf_macs_and_flows: add leaf mac %s", macstr)
self.lt.peersw_tbl[rnid].leaf_macs.add(macstr)
for mac in self.lt.remote_leaf_macs(rnid).leaf_macs:
for mac in self.lt.remote_leaf_macs(rnid):
self.update_flow_match_dstmac(datapath, mac, ingress, tblid=0)
###################################################################################################
@ -1345,7 +1360,7 @@ class FloodingBounds():
self._hops = None
self._net_node = net_node
def bounds(self, prev_frb=None, exclude_ports=None):
def bounds(self, prev_frb=None, exclude_ports=None, frb_type=0):
"""
Creates a list of tuples in the format (egress, frb) which indicates the output port
number that the frb should be sent.
@ -1380,7 +1395,7 @@ class FloodingBounds():
bound_nid = my_nid
if not prev_frb:
bound_nid = peer2
frb_hdr = FloodRouteBound(root_nid, bound_nid, hops)
frb_hdr = FloodRouteBound(root_nid, bound_nid, hops, frb_type)
if frb_hdr:
prtno = self._net_node.query_port_no(peer1)
if prtno and prtno not in exclude_ports:
@ -1413,7 +1428,7 @@ class FloodingBounds():
bound_nid = prev_frb.bound_nid
else:
bound_nid = peer2
frb_hdr = FloodRouteBound(root_nid, bound_nid, hops)
frb_hdr = FloodRouteBound(root_nid, bound_nid, hops, frb_type)
if frb_hdr:
prtno = self._net_node.query_port_no(peer1)
if prtno and prtno not in exclude_ports:

View File

@ -91,7 +91,9 @@ class OvsBridge(BridgeABC):
net = "{0}/{1}".format(ip_addr, prefix_len)
Modlib.runshell([OvsBridge.iptool, "addr", "flush", "dev", self.name])
Modlib.runshell([OvsBridge.iptool, "addr", "add", net, "dev", self.name])
else:
Modlib.runshell(["sysctl", "net.ipv6.conf.{}.disable_ipv6=1".format(self.name)])
Modlib.runshell([OvsBridge.iptool, "addr", "flush", self.name])
try:
Modlib.runshell([OvsBridge.brctl, "set", "int", self.name,
"mtu_request=" + str(self.mtu)])
@ -128,6 +130,8 @@ class OvsBridge(BridgeABC):
def add_port(self, port_name):
Modlib.runshell([OvsBridge.iptool, "link", "set", "dev", port_name, "mtu",
str(self.mtu)])
Modlib.runshell(["sysctl", "net.ipv6.conf.{}.disable_ipv6=1".format(port_name)])
Modlib.runshell([OvsBridge.iptool, "addr", "flush", port_name])
Modlib.runshell([OvsBridge.brctl,
"--may-exist", "add-port", self.name, port_name])
self.ports.add(port_name)