Merge "Divide-and-conquer local bridge flows beasts" into stable/queens

This commit is contained in:
Zuul 2019-04-09 00:38:14 +00:00 committed by Gerrit Code Review
commit af0ffb3de4
8 changed files with 70 additions and 16 deletions

View File

@ -78,6 +78,23 @@ DROPPED_TRAFFIC_TABLE = 93
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)
# Various tables for tunneling flows
@ -93,6 +110,19 @@ UCAST_TO_TUN = 20
ARP_RESPONDER = 21
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)
# Various tables for DVR use of physical bridge flows
@ -100,6 +130,12 @@ DVR_PROCESS_VLAN = 1
LOCAL_VLAN_TRANSLATION = 2
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
# type for ARP reply in ARP header

View File

@ -38,6 +38,8 @@ LOG = logging.getLogger(__name__)
class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
"""openvswitch agent br-int specific logic."""
of_tables = constants.INT_BR_ALL_TABLES
def setup_default_table(self):
self.setup_canary_table()
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE)

View File

@ -28,6 +28,7 @@ class OVSPhysicalBridge(ovs_bridge.OVSAgentBridge,
# Used by OVSDVRProcessMixin
dvr_process_table_id = constants.DVR_PROCESS_VLAN
dvr_process_next_table_id = constants.LOCAL_VLAN_TRANSLATION
of_tables = constants.PHY_BR_ALL_TABLES
def setup_default_table(self):
self.install_normal()

View File

@ -46,6 +46,7 @@ class OVSTunnelBridge(ovs_bridge.OVSAgentBridge,
# Used by OVSDVRProcessMixin
dvr_process_table_id = constants.DVR_PROCESS
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):
(dp, ofp, ofpp) = self._get_dp()

View File

@ -150,11 +150,9 @@ class OpenFlowSwitchMixin(object):
flows += rep.body
return flows
def cleanup_flows(self):
cookies = set([f.cookie for f in self.dump_flows()]) - \
self.reserved_cookies
LOG.debug("Reserved cookies for %s: %s", self.br_name,
self.reserved_cookies)
def _dump_and_clean(self, table_id=None):
cookies = set([f.cookie for f in self.dump_flows(table_id)]) - \
self.reserved_cookies
for c in cookies:
LOG.warning("Deleting flow with cookie 0x%(cookie)x",
{'cookie': c})
@ -163,6 +161,13 @@ class OpenFlowSwitchMixin(object):
def install_goto_next(self, table_id):
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,
match=None, **match_kwargs):
(_dp, ofp, ofpp) = self._get_dp()

View File

@ -1879,13 +1879,15 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
return port_stats
def cleanup_stale_flows(self):
bridges = [self.int_br]
bridges.extend(self.phys_brs.values())
LOG.info("Cleaning stale %s flows", self.int_br.br_name)
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:
bridges.append(self.tun_br)
for bridge in bridges:
LOG.info("Cleaning stale %s flows", bridge.br_name)
bridge.cleanup_flows()
LOG.info("Cleaning stale %s flows", self.tun_br.br_name)
self.tun_br.cleanup_flows()
def process_port_info(self, start, polling_manager, sync, ovs_restarted,
ports, ancillary_ports, updated_ports_copy,

View File

@ -2288,21 +2288,28 @@ class TestOvsNeutronAgentRyu(TestOvsNeutronAgent,
mock.patch.object(self.agent.int_br,
'uninstall_flows') as uninstall_flows:
self.agent.int_br.set_agent_uuid_stamp(1234)
dump_flows.return_value = [
fake_flows = [
# mock ryu.ofproto.ofproto_v1_3_parser.OFPFlowStats
mock.Mock(cookie=1234, table_id=0),
mock.Mock(cookie=17185, table_id=2),
mock.Mock(cookie=9029, table_id=2),
mock.Mock(cookie=1234, table_id=3),
]
dump_flows.return_value = fake_flows
self.agent.iter_num = 3
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,
cookie_mask=uint64_max),
mock.call(cookie=9029,
cookie_mask=uint64_max)]
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):

View File

@ -573,10 +573,10 @@ class TunnelTest(object):
mock.call.cleanup_flows(),
mock.call.check_canary_table()
]
self.mock_tun_bridge_expected += [
mock.call.cleanup_flows()
]
self.mock_map_tun_bridge_expected += [
mock.call.cleanup_flows(),
]
self.mock_tun_bridge_expected += [
mock.call.cleanup_flows()
]
# No cleanup is expected on ancillary bridge