Add legacy sNAT rule to l3_proactive_app

Add a default rule to l3_proactive_app, that will pass the packet to the
router interface. The router interface will then route the packet out
using sNAT.

Move PUBLIC_BRIDGE (and related) configuration to settings, so that they
will be picked up by devstack when setting up the l3 agent, so that the
outgoing router interface in the namespace will be connected to the
external bridge.

Future patches on this bug will include:
* Same fix for l3_app.py (reactive)
* Fullstack tests
* Move relevant code to its own application

This patch is partial to allow sNAT to work again.

Related-Bug: #1651988
Change-Id: Ic3054632272ee2bfdfeba2f9f696b512f884b9ef
This commit is contained in:
Omer Anson 2016-12-22 10:48:39 +02:00
parent 35d022027a
commit 64feb55f95
4 changed files with 64 additions and 7 deletions

View File

@ -30,3 +30,10 @@ NEUTRON_CONFIG_ARG+=" --config-file $DRAGONFLOW_CONF"
Q_ML2_PLUGIN_MECHANISM_DRIVERS=${Q_ML2_PLUGIN_MECHANISM_DRIVERS:-"df"}
ML2_L3_PLUGIN=${ML2_L3_PLUGIN:-"df-l3"}
# OVS bridge definition
Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
INTEGRATION_BRIDGE=${INTEGRATION_BRIDGE:-br-int}
INTEGRATION_PEER_PORT=${INTEGRATION_PEER_PORT:-patch-ex}
PUBLIC_PEER_PORT=${PUBLIC_PEER_PORT:-patch-int}

View File

@ -30,12 +30,6 @@ REMOTE_DB_IP=${REMOTE_DB_IP:-$HOST_IP}
REMOTE_DB_PORT=${REMOTE_DB_PORT:-4001}
REMOTE_DB_HOSTS=${REMOTE_DB_HOSTS:-"$REMOTE_DB_IP:$REMOTE_DB_PORT"}
# OVS bridge definition
PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
INTEGRATION_BRIDGE=${INTEGRATION_BRIDGE:-br-int}
INTEGRATION_PEER_PORT=${INTEGRATION_PEER_PORT:-patch-ex}
PUBLIC_PEER_PORT=${PUBLIC_PEER_PORT:-patch-int}
# OVS related pid files
#----------------------
OVS_DB_SERVICE="ovsdb-server"

View File

@ -186,7 +186,10 @@ class L3ProactiveApp(df_base_app.DFlowApp):
router_port.get_cidr_netmask(),
tunnel_key,
local_network_id,
router_port.get_mac())
mac)
# Fall through to sNAT
self._add_subnet_send_to_snat(local_network_id, mac, tunnel_key)
def _get_port(self, ip, lswitch_id, topic):
ports = self.db_store.get_ports(topic)
@ -440,6 +443,35 @@ class L3ProactiveApp(df_base_app.DFlowApp):
priority=const.PRIORITY_MEDIUM,
match=match)
def _add_subnet_send_to_snat(self, network_id, mac, tunnel_key):
datapath = self.get_datapath()
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPMatch(metadata=network_id, eth_dst=mac)
actions = [parser.OFPActionSetField(reg7=tunnel_key)]
inst = [
parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions),
parser.OFPInstructionGotoTable(const.EGRESS_TABLE),
]
self.mod_flow(
datapath,
inst=inst,
table_id=const.L3_LOOKUP_TABLE,
priority=const.PRIORITY_LOW,
match=match)
def _delete_subnet_send_to_snat(self, network_id, mac):
datapath = self.get_datapath()
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPMatch(metadata=network_id, eth_dst=mac)
self.mod_flow(
datapath,
command=ofproto.OFPFC_DELETE_STRICT,
table_id=const.L3_LOOKUP_TABLE,
priority=const.PRIORITY_LOW,
match=match)
def _delete_router_port(self, router, router_port):
LOG.info(_LI("Removing logical router interface = %s"),
router_port)
@ -452,6 +484,8 @@ class L3ProactiveApp(df_base_app.DFlowApp):
ip = router_port.get_ip()
mac = router_port.get_mac()
self._delete_subnet_send_to_snat(local_network_id, mac)
if netaddr.IPAddress(ip).version == 4:
arp_responder.ArpResponder(self, local_network_id, ip).remove()
icmp_responder.ICMPResponder(

View File

@ -31,6 +31,19 @@ class TestL3ProactiveApp(test_app_base.DFAppTestBase):
self.router = test_app_base.fake_logic_router1
def test_add_del_route(self):
_add_subnet_send_to_snat = mock.patch.object(
self.app,
'_add_subnet_send_to_snat'
)
self.addCleanup(_add_subnet_send_to_snat.stop)
_add_subnet_send_to_snat.start()
_del_subnet_send_to_snat = mock.patch.object(
self.app,
'_delete_subnet_send_to_snat'
)
self.addCleanup(_del_subnet_send_to_snat.stop)
_del_subnet_send_to_snat.start()
# delete router
self.controller.delete_lrouter(self.router.get_id())
self.assertEqual(5, self.mock_mod_flow.call_count)
@ -41,6 +54,11 @@ class TestL3ProactiveApp(test_app_base.DFAppTestBase):
self.assertEqual(4, self.mock_mod_flow.call_count)
args, kwargs = self.mock_mod_flow.call_args
self.assertEqual(const.L2_LOOKUP_TABLE, kwargs['table_id'])
self.app._add_subnet_send_to_snat.assert_called_once_with(
test_app_base.fake_logic_switch1.get_unique_key(),
self.router.get_ports()[0].get_mac(),
self.router.get_ports()[0].get_unique_key()
)
self.mock_mod_flow.reset_mock()
# add route
@ -59,3 +77,7 @@ class TestL3ProactiveApp(test_app_base.DFAppTestBase):
self.router.inner_obj['version'] += 2
self.controller.update_lrouter(self.router)
self.assertEqual(1, self.mock_mod_flow.call_count)
self.app._delete_subnet_send_to_snat.assert_called_once_with(
test_app_base.fake_logic_switch1.get_unique_key(),
self.router.get_ports()[0].get_mac(),
)