Merge "Divide-and-conquer local bridge flows beasts" into stable/queens
This commit is contained in:
commit
af0ffb3de4
@ -78,6 +78,23 @@ DROPPED_TRAFFIC_TABLE = 93
|
|||||||
|
|
||||||
ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE = 94
|
ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE = 94
|
||||||
|
|
||||||
|
INT_BR_ALL_TABLES = (
|
||||||
|
LOCAL_SWITCHING,
|
||||||
|
DVR_TO_SRC_MAC,
|
||||||
|
DVR_TO_SRC_MAC_VLAN,
|
||||||
|
CANARY_TABLE,
|
||||||
|
ARP_SPOOF_TABLE,
|
||||||
|
MAC_SPOOF_TABLE,
|
||||||
|
TRANSIENT_TABLE,
|
||||||
|
BASE_EGRESS_TABLE,
|
||||||
|
RULES_EGRESS_TABLE,
|
||||||
|
ACCEPT_OR_INGRESS_TABLE,
|
||||||
|
BASE_INGRESS_TABLE,
|
||||||
|
RULES_INGRESS_TABLE,
|
||||||
|
ACCEPTED_EGRESS_TRAFFIC_TABLE,
|
||||||
|
ACCEPTED_INGRESS_TRAFFIC_TABLE,
|
||||||
|
DROPPED_TRAFFIC_TABLE)
|
||||||
|
|
||||||
# --- Tunnel bridge (tun_br)
|
# --- Tunnel bridge (tun_br)
|
||||||
|
|
||||||
# Various tables for tunneling flows
|
# Various tables for tunneling flows
|
||||||
@ -93,6 +110,19 @@ UCAST_TO_TUN = 20
|
|||||||
ARP_RESPONDER = 21
|
ARP_RESPONDER = 21
|
||||||
FLOOD_TO_TUN = 22
|
FLOOD_TO_TUN = 22
|
||||||
|
|
||||||
|
TUN_BR_ALL_TABLES = (
|
||||||
|
LOCAL_SWITCHING,
|
||||||
|
DVR_PROCESS,
|
||||||
|
PATCH_LV_TO_TUN,
|
||||||
|
GRE_TUN_TO_LV,
|
||||||
|
VXLAN_TUN_TO_LV,
|
||||||
|
GENEVE_TUN_TO_LV,
|
||||||
|
DVR_NOT_LEARN,
|
||||||
|
LEARN_FROM_TUN,
|
||||||
|
UCAST_TO_TUN,
|
||||||
|
ARP_RESPONDER,
|
||||||
|
FLOOD_TO_TUN)
|
||||||
|
|
||||||
# --- Physical Bridges (phys_brs)
|
# --- Physical Bridges (phys_brs)
|
||||||
|
|
||||||
# Various tables for DVR use of physical bridge flows
|
# Various tables for DVR use of physical bridge flows
|
||||||
@ -100,6 +130,12 @@ DVR_PROCESS_VLAN = 1
|
|||||||
LOCAL_VLAN_TRANSLATION = 2
|
LOCAL_VLAN_TRANSLATION = 2
|
||||||
DVR_NOT_LEARN_VLAN = 3
|
DVR_NOT_LEARN_VLAN = 3
|
||||||
|
|
||||||
|
PHY_BR_ALL_TABLES = (
|
||||||
|
LOCAL_SWITCHING,
|
||||||
|
DVR_PROCESS_VLAN,
|
||||||
|
LOCAL_VLAN_TRANSLATION,
|
||||||
|
DVR_NOT_LEARN_VLAN)
|
||||||
|
|
||||||
# --- end of OpenFlow table IDs
|
# --- end of OpenFlow table IDs
|
||||||
|
|
||||||
# type for ARP reply in ARP header
|
# type for ARP reply in ARP header
|
||||||
|
@ -38,6 +38,8 @@ LOG = logging.getLogger(__name__)
|
|||||||
class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
||||||
"""openvswitch agent br-int specific logic."""
|
"""openvswitch agent br-int specific logic."""
|
||||||
|
|
||||||
|
of_tables = constants.INT_BR_ALL_TABLES
|
||||||
|
|
||||||
def setup_default_table(self):
|
def setup_default_table(self):
|
||||||
self.setup_canary_table()
|
self.setup_canary_table()
|
||||||
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE)
|
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE)
|
||||||
|
@ -28,6 +28,7 @@ class OVSPhysicalBridge(ovs_bridge.OVSAgentBridge,
|
|||||||
# Used by OVSDVRProcessMixin
|
# Used by OVSDVRProcessMixin
|
||||||
dvr_process_table_id = constants.DVR_PROCESS_VLAN
|
dvr_process_table_id = constants.DVR_PROCESS_VLAN
|
||||||
dvr_process_next_table_id = constants.LOCAL_VLAN_TRANSLATION
|
dvr_process_next_table_id = constants.LOCAL_VLAN_TRANSLATION
|
||||||
|
of_tables = constants.PHY_BR_ALL_TABLES
|
||||||
|
|
||||||
def setup_default_table(self):
|
def setup_default_table(self):
|
||||||
self.install_normal()
|
self.install_normal()
|
||||||
|
@ -46,6 +46,7 @@ class OVSTunnelBridge(ovs_bridge.OVSAgentBridge,
|
|||||||
# Used by OVSDVRProcessMixin
|
# Used by OVSDVRProcessMixin
|
||||||
dvr_process_table_id = constants.DVR_PROCESS
|
dvr_process_table_id = constants.DVR_PROCESS
|
||||||
dvr_process_next_table_id = constants.PATCH_LV_TO_TUN
|
dvr_process_next_table_id = constants.PATCH_LV_TO_TUN
|
||||||
|
of_tables = constants.TUN_BR_ALL_TABLES
|
||||||
|
|
||||||
def setup_default_table(self, patch_int_ofport, arp_responder_enabled):
|
def setup_default_table(self, patch_int_ofport, arp_responder_enabled):
|
||||||
(dp, ofp, ofpp) = self._get_dp()
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
|
@ -150,11 +150,9 @@ class OpenFlowSwitchMixin(object):
|
|||||||
flows += rep.body
|
flows += rep.body
|
||||||
return flows
|
return flows
|
||||||
|
|
||||||
def cleanup_flows(self):
|
def _dump_and_clean(self, table_id=None):
|
||||||
cookies = set([f.cookie for f in self.dump_flows()]) - \
|
cookies = set([f.cookie for f in self.dump_flows(table_id)]) - \
|
||||||
self.reserved_cookies
|
self.reserved_cookies
|
||||||
LOG.debug("Reserved cookies for %s: %s", self.br_name,
|
|
||||||
self.reserved_cookies)
|
|
||||||
for c in cookies:
|
for c in cookies:
|
||||||
LOG.warning("Deleting flow with cookie 0x%(cookie)x",
|
LOG.warning("Deleting flow with cookie 0x%(cookie)x",
|
||||||
{'cookie': c})
|
{'cookie': c})
|
||||||
@ -163,6 +161,13 @@ class OpenFlowSwitchMixin(object):
|
|||||||
def install_goto_next(self, table_id):
|
def install_goto_next(self, table_id):
|
||||||
self.install_goto(table_id=table_id, dest_table_id=table_id + 1)
|
self.install_goto(table_id=table_id, dest_table_id=table_id + 1)
|
||||||
|
|
||||||
|
def cleanup_flows(self):
|
||||||
|
LOG.info("Reserved cookies for %s: %s", self.br_name,
|
||||||
|
self.reserved_cookies)
|
||||||
|
|
||||||
|
for table_id in self.of_tables:
|
||||||
|
self._dump_and_clean(table_id)
|
||||||
|
|
||||||
def install_output(self, port, table_id=0, priority=0,
|
def install_output(self, port, table_id=0, priority=0,
|
||||||
match=None, **match_kwargs):
|
match=None, **match_kwargs):
|
||||||
(_dp, ofp, ofpp) = self._get_dp()
|
(_dp, ofp, ofpp) = self._get_dp()
|
||||||
|
@ -1879,13 +1879,15 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
return port_stats
|
return port_stats
|
||||||
|
|
||||||
def cleanup_stale_flows(self):
|
def cleanup_stale_flows(self):
|
||||||
bridges = [self.int_br]
|
LOG.info("Cleaning stale %s flows", self.int_br.br_name)
|
||||||
bridges.extend(self.phys_brs.values())
|
self.int_br.cleanup_flows()
|
||||||
|
for pby_br in self.phys_brs.values():
|
||||||
|
LOG.info("Cleaning stale %s flows", pby_br.br_name)
|
||||||
|
pby_br.cleanup_flows()
|
||||||
|
|
||||||
if self.enable_tunneling:
|
if self.enable_tunneling:
|
||||||
bridges.append(self.tun_br)
|
LOG.info("Cleaning stale %s flows", self.tun_br.br_name)
|
||||||
for bridge in bridges:
|
self.tun_br.cleanup_flows()
|
||||||
LOG.info("Cleaning stale %s flows", bridge.br_name)
|
|
||||||
bridge.cleanup_flows()
|
|
||||||
|
|
||||||
def process_port_info(self, start, polling_manager, sync, ovs_restarted,
|
def process_port_info(self, start, polling_manager, sync, ovs_restarted,
|
||||||
ports, ancillary_ports, updated_ports_copy,
|
ports, ancillary_ports, updated_ports_copy,
|
||||||
|
@ -2288,21 +2288,28 @@ class TestOvsNeutronAgentRyu(TestOvsNeutronAgent,
|
|||||||
mock.patch.object(self.agent.int_br,
|
mock.patch.object(self.agent.int_br,
|
||||||
'uninstall_flows') as uninstall_flows:
|
'uninstall_flows') as uninstall_flows:
|
||||||
self.agent.int_br.set_agent_uuid_stamp(1234)
|
self.agent.int_br.set_agent_uuid_stamp(1234)
|
||||||
dump_flows.return_value = [
|
fake_flows = [
|
||||||
# mock ryu.ofproto.ofproto_v1_3_parser.OFPFlowStats
|
# mock ryu.ofproto.ofproto_v1_3_parser.OFPFlowStats
|
||||||
mock.Mock(cookie=1234, table_id=0),
|
mock.Mock(cookie=1234, table_id=0),
|
||||||
mock.Mock(cookie=17185, table_id=2),
|
mock.Mock(cookie=17185, table_id=2),
|
||||||
mock.Mock(cookie=9029, table_id=2),
|
mock.Mock(cookie=9029, table_id=2),
|
||||||
mock.Mock(cookie=1234, table_id=3),
|
mock.Mock(cookie=1234, table_id=3),
|
||||||
]
|
]
|
||||||
|
dump_flows.return_value = fake_flows
|
||||||
self.agent.iter_num = 3
|
self.agent.iter_num = 3
|
||||||
self.agent.cleanup_stale_flows()
|
self.agent.cleanup_stale_flows()
|
||||||
|
|
||||||
|
dump_flows_expected = [
|
||||||
|
mock.call(tid) for tid in constants.INT_BR_ALL_TABLES]
|
||||||
|
dump_flows.assert_has_calls(dump_flows_expected)
|
||||||
|
|
||||||
expected = [mock.call(cookie=17185,
|
expected = [mock.call(cookie=17185,
|
||||||
cookie_mask=uint64_max),
|
cookie_mask=uint64_max),
|
||||||
mock.call(cookie=9029,
|
mock.call(cookie=9029,
|
||||||
cookie_mask=uint64_max)]
|
cookie_mask=uint64_max)]
|
||||||
uninstall_flows.assert_has_calls(expected, any_order=True)
|
uninstall_flows.assert_has_calls(expected, any_order=True)
|
||||||
self.assertEqual(len(expected), len(uninstall_flows.mock_calls))
|
self.assertEqual(len(constants.INT_BR_ALL_TABLES) * len(expected),
|
||||||
|
len(uninstall_flows.mock_calls))
|
||||||
|
|
||||||
|
|
||||||
class AncillaryBridgesTest(object):
|
class AncillaryBridgesTest(object):
|
||||||
|
@ -573,10 +573,10 @@ class TunnelTest(object):
|
|||||||
mock.call.cleanup_flows(),
|
mock.call.cleanup_flows(),
|
||||||
mock.call.check_canary_table()
|
mock.call.check_canary_table()
|
||||||
]
|
]
|
||||||
self.mock_tun_bridge_expected += [
|
|
||||||
mock.call.cleanup_flows()
|
|
||||||
]
|
|
||||||
self.mock_map_tun_bridge_expected += [
|
self.mock_map_tun_bridge_expected += [
|
||||||
|
mock.call.cleanup_flows(),
|
||||||
|
]
|
||||||
|
self.mock_tun_bridge_expected += [
|
||||||
mock.call.cleanup_flows()
|
mock.call.cleanup_flows()
|
||||||
]
|
]
|
||||||
# No cleanup is expected on ancillary bridge
|
# No cleanup is expected on ancillary bridge
|
||||||
|
Loading…
Reference in New Issue
Block a user