mirror of https://github.com/EdgeVPNio/evio.git
Action only on ARP FRB
parent
85a47f1b66
commit
c58721ba7d
|
@ -425,6 +425,10 @@ class PortDescriptor:
|
||||||
def is_peer(self):
|
def is_peer(self):
|
||||||
return bool(self.rmt_nd_type == NodeTypes.PEER and self.peer_data is not None)
|
return bool(self.rmt_nd_type == NodeTypes.PEER and self.peer_data is not None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_adjacent_peer(self):
|
||||||
|
return bool(self.is_peer and self.peer_data.port_no is not None)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_categorized(self):
|
def is_categorized(self):
|
||||||
return bool(self.rmt_nd_type != NodeTypes.UNKNOWN)
|
return bool(self.rmt_nd_type != NodeTypes.UNKNOWN)
|
||||||
|
@ -666,7 +670,7 @@ class EvioSwitch:
|
||||||
else:
|
else:
|
||||||
port.dataplane_type = DATAPLANE_TYPES.Patch
|
port.dataplane_type = DATAPLANE_TYPES.Patch
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"Categorized port %s:%s, port_no=%i, dp=%s ",
|
"Categorized port %s:%s, port_no=%i, dp=%s",
|
||||||
self.name,
|
self.name,
|
||||||
port.name,
|
port.name,
|
||||||
port.port_no,
|
port.port_no,
|
||||||
|
@ -1135,8 +1139,13 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
MAC"""
|
MAC"""
|
||||||
# learn MAC address
|
# learn MAC address
|
||||||
sw.set_ingress_port(eth.src, in_port)
|
sw.set_ingress_port(eth.src, in_port)
|
||||||
if eth.dst in sw.local_leaf_macs: # incoming to local pendant
|
if eth.dst in sw.local_leaf_macs:
|
||||||
self._update_outbound_flow_rules(ev_msg.datapath, eth.src, in_port)
|
self._update_outbound_flow_rules(
|
||||||
|
ev_msg.datapath,
|
||||||
|
eth.src,
|
||||||
|
in_port,
|
||||||
|
reason="Packet for local pendant",
|
||||||
|
)
|
||||||
elif eth.src in sw.local_leaf_macs: # outgoing from local pendant
|
elif eth.src in sw.local_leaf_macs: # outgoing from local pendant
|
||||||
peer: PeerData = self._lt[dpid].get_root_sw(eth.dst)
|
peer: PeerData = self._lt[dpid].get_root_sw(eth.dst)
|
||||||
if peer and peer.port_no: # remote is adjacent
|
if peer and peer.port_no: # remote is adjacent
|
||||||
|
@ -1230,7 +1239,7 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
tnl_data[op.olid]
|
tnl_data[op.olid]
|
||||||
)
|
)
|
||||||
for port in updated_prts:
|
for port in updated_prts:
|
||||||
if port.is_peer:
|
if port.is_adjacent_peer:
|
||||||
if port.is_tincan_tunnel:
|
if port.is_tincan_tunnel:
|
||||||
self._update_flow_rules_to_peer(
|
self._update_flow_rules_to_peer(
|
||||||
self.dpset.dps[op.dpid],
|
self.dpset.dps[op.dpid],
|
||||||
|
@ -1436,12 +1445,12 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
ofproto = datapath.ofproto
|
ofproto = datapath.ofproto
|
||||||
parser = datapath.ofproto_parser
|
parser = datapath.ofproto_parser
|
||||||
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||||
self.logger.debug(
|
# self.logger.info(
|
||||||
"Adding flow rule %s: %s, %s",
|
# "Adding flow rule %s/%s to egress %s",
|
||||||
self._lt[datapath.id].name,
|
# self._lt[datapath.id].name,
|
||||||
match,
|
# match,
|
||||||
actions,
|
# actions,
|
||||||
)
|
# )
|
||||||
mod = parser.OFPFlowMod(
|
mod = parser.OFPFlowMod(
|
||||||
datapath=datapath,
|
datapath=datapath,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
|
@ -1498,10 +1507,16 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
for eth_dst in sw.local_leaf_macs:
|
for eth_dst in sw.local_leaf_macs:
|
||||||
local_port_no = sw.get_ingress_port(eth_dst)
|
local_port_no = sw.get_ingress_port(eth_dst)
|
||||||
actions = [parser.OFPActionOutput(local_port_no)]
|
actions = [parser.OFPActionOutput(local_port_no)]
|
||||||
match = parser.OFPMatch(in_port=ingress, eth_src=eth_src, eth_dst=eth_dst)
|
mt = parser.OFPMatch(in_port=ingress, eth_src=eth_src, eth_dst=eth_dst)
|
||||||
|
self.logger.info(
|
||||||
|
"Adding inflow rule %s/%s to egress %s",
|
||||||
|
self._lt[datapath.id].name,
|
||||||
|
f"in_port: {mt['in_port']}, eth_dst: {mt['eth_dst']}, eth_src:{mt['eth_src']}",
|
||||||
|
local_port_no,
|
||||||
|
)
|
||||||
self._create_flow_rule(
|
self._create_flow_rule(
|
||||||
datapath,
|
datapath,
|
||||||
match,
|
mt,
|
||||||
actions,
|
actions,
|
||||||
priority=1,
|
priority=1,
|
||||||
tblid=tblid,
|
tblid=tblid,
|
||||||
|
@ -1509,7 +1524,9 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
hard_timeout=sw.hard_timeout,
|
hard_timeout=sw.hard_timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _update_outbound_flow_rules(self, datapath, dst_mac, new_egress, tblid=None):
|
def _update_outbound_flow_rules(
|
||||||
|
self, datapath, dst_mac, new_egress, tblid=None, reason=None
|
||||||
|
):
|
||||||
"""Updates existing flow rules from all local pendant eth src to @param dst_mac
|
"""Updates existing flow rules from all local pendant eth src to @param dst_mac
|
||||||
- a remote pendant device"""
|
- a remote pendant device"""
|
||||||
sw: EvioSwitch = self._lt[datapath.id]
|
sw: EvioSwitch = self._lt[datapath.id]
|
||||||
|
@ -1540,10 +1557,11 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
hard_timeout=sw.hard_timeout,
|
hard_timeout=sw.hard_timeout,
|
||||||
)
|
)
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"Updating outflow matching %s/%s to egress %s",
|
"Updating outflow matching %s/%s to egress %s. %s",
|
||||||
sw.name,
|
sw.name,
|
||||||
mt,
|
f"in_port: {mt['in_port']}, eth_dst: {mt['eth_dst']}, eth_src:{mt['eth_src']}",
|
||||||
new_egress,
|
new_egress,
|
||||||
|
reason,
|
||||||
)
|
)
|
||||||
datapath.send_msg(mod)
|
datapath.send_msg(mod)
|
||||||
|
|
||||||
|
@ -1560,7 +1578,10 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
for mac in sw.leaf_macs(peer.node_id):
|
for mac in sw.leaf_macs(peer.node_id):
|
||||||
# update existing flows going out to the remote peer
|
# update existing flows going out to the remote peer
|
||||||
self._update_outbound_flow_rules(
|
self._update_outbound_flow_rules(
|
||||||
datapath=datapath, dst_mac=mac, new_egress=peer.port_no
|
datapath=datapath,
|
||||||
|
dst_mac=mac,
|
||||||
|
new_egress=peer.port_no,
|
||||||
|
reason="New port connected",
|
||||||
)
|
)
|
||||||
self._create_inbound_flow_rules(
|
self._create_inbound_flow_rules(
|
||||||
datapath=datapath, eth_src=mac, ingress=peer.port_no
|
datapath=datapath, eth_src=mac, ingress=peer.port_no
|
||||||
|
@ -1929,10 +1950,6 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
self._update_flow_rules_to_peer(datapath, port.peer)
|
self._update_flow_rules_to_peer(datapath, port.peer)
|
||||||
return
|
return
|
||||||
# case (rcvd_frb.frb_type == FloodRouteBound.FRB_BRDCST)
|
# case (rcvd_frb.frb_type == FloodRouteBound.FRB_BRDCST)
|
||||||
# learn a mac address
|
|
||||||
sw.set_ingress_port(eth.src, (in_port, rcvd_frb.root_nid))
|
|
||||||
sw.peer(rcvd_frb.root_nid).hop_count = rcvd_frb.hop_count
|
|
||||||
sw.max_hops = rcvd_frb.hop_count
|
|
||||||
inner_pkt = packet.Packet(payload)
|
inner_pkt = packet.Packet(payload)
|
||||||
arp_pkt = inner_pkt.get_protocol(arp.arp)
|
arp_pkt = inner_pkt.get_protocol(arp.arp)
|
||||||
if arp_pkt and arp_pkt.opcode == arp.ARP_REQUEST:
|
if arp_pkt and arp_pkt.opcode == arp.ARP_REQUEST:
|
||||||
|
@ -1941,7 +1958,13 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
"Received ARP %s",
|
"Received ARP %s",
|
||||||
str(arp_pkt),
|
str(arp_pkt),
|
||||||
)
|
)
|
||||||
self._update_outbound_flow_rules(datapath, eth.src, in_port)
|
# learn a mac address but only for ARPs - reduce the occurence of path flips
|
||||||
|
sw.set_ingress_port(eth.src, (in_port, rcvd_frb.root_nid))
|
||||||
|
sw.peer(rcvd_frb.root_nid).hop_count = rcvd_frb.hop_count
|
||||||
|
sw.max_hops = rcvd_frb.hop_count
|
||||||
|
self._update_outbound_flow_rules(
|
||||||
|
datapath, eth.src, in_port, reason="ARP received"
|
||||||
|
)
|
||||||
# deliver the broadcast frame to leaf devices
|
# deliver the broadcast frame to leaf devices
|
||||||
if payload:
|
if payload:
|
||||||
for out_port in sw.leaf_ports:
|
for out_port in sw.leaf_ports:
|
||||||
|
@ -1977,10 +2000,16 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
if out_port:
|
if out_port:
|
||||||
# create new flow rule
|
# create new flow rule
|
||||||
actions = [parser.OFPActionOutput(out_port)]
|
actions = [parser.OFPActionOutput(out_port)]
|
||||||
match = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst, eth_src=eth.src)
|
mt = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst, eth_src=eth.src)
|
||||||
|
self.logger.info(
|
||||||
|
"Adding flow & fwding %s/%s to egress %s",
|
||||||
|
self._lt[datapath.id].name,
|
||||||
|
f"in_port: {mt['in_port']}, eth_dst: {mt['eth_dst']}, eth_src:{mt['eth_src']}",
|
||||||
|
out_port,
|
||||||
|
)
|
||||||
self._create_flow_rule(
|
self._create_flow_rule(
|
||||||
datapath,
|
datapath,
|
||||||
match,
|
mt,
|
||||||
actions,
|
actions,
|
||||||
priority=1,
|
priority=1,
|
||||||
tblid=0,
|
tblid=0,
|
||||||
|
@ -1999,6 +2028,11 @@ class BoundedFlood(app_manager.RyuApp):
|
||||||
data=data,
|
data=data,
|
||||||
)
|
)
|
||||||
datapath.send_msg(out)
|
datapath.send_msg(out)
|
||||||
|
else:
|
||||||
|
self.logger.warning(
|
||||||
|
"Failed to add flow and forward frame, no LT ingress exists for the eth dst. pkt=%s",
|
||||||
|
str(pkt),
|
||||||
|
)
|
||||||
|
|
||||||
def _broadcast_frame(self, datapath, in_port, evmsg):
|
def _broadcast_frame(self, datapath, in_port, evmsg):
|
||||||
"""@param pkt is always an eth frame originating from a local pendant.
|
"""@param pkt is always an eth frame originating from a local pendant.
|
||||||
|
|
Loading…
Reference in New Issue