Detect source port for DNAT ingress

Detect the source port when a packet with a floating port source IP
arrives from br-ex.

Change-Id: Ia417212a48c68614877d97a749e5dcae8b6e88c8
Related-Bug: #1740739
This commit is contained in:
Omer Anson 2018-01-17 13:53:39 +02:00
parent cb2540392b
commit e1a15a07e5
3 changed files with 47 additions and 1 deletions

View File

@ -314,8 +314,45 @@ class DNATApp(df_base_app.DFlowApp):
match=self._get_ingress_icmp_flow_match(floatingip, icmp_type),
)
def _get_source_port_detector_match(self, floatingip):
match = self.parser.OFPMatch(
eth_type=ether.ETH_TYPE_IP,
ipv4_src=floatingip.floating_ip_address,
reg6=0,
)
return match
def _install_source_port_detector(self, floatingip):
parser = self.parser
match = self._get_source_port_detector_match(floatingip)
actions = [
parser.OFPActionSetField(reg6=floatingip.lport.unique_key),
]
inst_type = self.datapath.ofproto.OFPIT_APPLY_ACTIONS
inst = [
parser.OFPInstructionActions(inst_type, actions),
parser.OFPInstructionGotoTable(const.L2_LOOKUP_TABLE),
]
self.mod_flow(
table_id=const.EXTERNAL_INGRESS_DETECT_SOURCE_TABLE,
priority=const.PRIORITY_HIGH,
match=match,
inst=inst,
)
def _uninstall_source_port_detector(self, floatingip):
match = self._get_source_port_detector_match(floatingip)
self.mod_flow(
command=self.ofproto.OFPFC_DELETE_STRICT,
table_id=const.EXTERNAL_INGRESS_DETECT_SOURCE_TABLE,
priority=const.PRIORITY_HIGH,
match=match,
)
def _install_ingress_nat_flows(self, floatingip):
self._get_arp_responder(floatingip).add()
self._install_source_port_detector(floatingip)
self._install_ingress_capture_flow(floatingip)
self._install_ingress_translate_flow(floatingip)
self._install_ingress_icmp_flows(floatingip)
@ -325,6 +362,7 @@ class DNATApp(df_base_app.DFlowApp):
self._uninstall_ingress_capture_flow(floatingip)
self._uninstall_ingress_translate_flow(floatingip)
self._uninstall_ingress_icmp_flows(floatingip)
self._uninstall_source_port_detector(floatingip)
def _get_dnat_egress_match(self, floatingip, **kwargs):
return self.parser.OFPMatch(

View File

@ -112,6 +112,11 @@ class ProviderApp(df_base_app.DFlowApp):
def switch_features_handler(self, ev):
self._setup_physical_bridges(self.bridge_mappings)
self.add_flow_go_to_table(
const.EXTERNAL_INGRESS_DETECT_SOURCE_TABLE,
const.PRIORITY_DEFAULT,
const.L2_LOOKUP_TABLE
)
@df_base_app.register_event(l2.LogicalPort, l2.EVENT_BIND_LOCAL)
def _add_local_port(self, lport):
@ -286,7 +291,8 @@ class ProviderApp(df_base_app.DFlowApp):
action_inst = self.parser.OFPInstructionActions(
self.ofproto.OFPIT_APPLY_ACTIONS, actions)
goto_inst = self.parser.OFPInstructionGotoTable(const.L2_LOOKUP_TABLE)
goto_inst = self.parser.OFPInstructionGotoTable(
const.EXTERNAL_INGRESS_DETECT_SOURCE_TABLE)
inst = [action_inst, goto_inst]
self.mod_flow(

View File

@ -26,6 +26,8 @@
# translated to network id and the packet is forwarded to
# INGRESS_DESTINATION_PORT_LOOKUP_TABLE.
INGRESS_CLASSIFICATION_DISPATCH_TABLE = 0
# Detect reg6 (provider network and dNAT)
EXTERNAL_INGRESS_DETECT_SOURCE_TABLE = 2
# All packets from unknown ovs ports are dropped here. Other packets
# are forwarded to table EGRESS_CONNTRACK_TABLE.
EGRESS_PORT_SECURITY_TABLE = 5