OVS firewall: do strip_vlan in TRANSIENT_TABLE

This change moves the strip_vlan action from RULES_INGRESS/82 to
TRANSIENT_TABLE after the point where the traffic from local VM ports
has been moved to BASE_EGRESS. A reason for this move is that strip_vlan
is only needed for traffic *not* coming from VM ports and coming on a
patch  port from br-*, and that it is hence simpler do do the strip_vlan
in TRANSIENT_TABLE rather than in mutliple places that also happen to be
common with traffic from local VMs.

This change also addresses another need:
I16a35b5d6c54901899d24fc94bd3438c1f1be05e results in add_flow being
possibly done with an Openflow version higher than OF1.0. The
strip_action as currently done is not compatible with OF>1.0, because
later versions require matching on dl_vlan first (the "strip vlan if
there is one" behavior of OF1.0 is not supported anymore). For this
reason this change adds a match on dl_vlan for the strip_vlan rule.

Change-Id: I76ee34a614237bbc99989ce9c1b96a30456be282
This commit is contained in:
Thomas Morin 2017-04-07 11:30:59 +02:00 committed by Thomas Morin
parent 3ebbe44b70
commit f2caa7c823
4 changed files with 10 additions and 10 deletions

View File

@ -561,7 +561,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
dl_dst=port.mac, dl_dst=port.mac,
actions='set_field:{:d}->reg{:d},' actions='set_field:{:d}->reg{:d},'
'set_field:{:d}->reg{:d},' 'set_field:{:d}->reg{:d},'
'resubmit(,{:d})'.format( 'strip_vlan,resubmit(,{:d})'.format(
port.ofport, port.ofport,
ovsfw_consts.REG_PORT, ovsfw_consts.REG_PORT,
port.vlan_tag, port.vlan_tag,
@ -777,7 +777,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
dl_type=constants.ETHERTYPE_IPV6, dl_type=constants.ETHERTYPE_IPV6,
nw_proto=lib_const.PROTO_NUM_IPV6_ICMP, nw_proto=lib_const.PROTO_NUM_IPV6_ICMP,
icmp_type=icmp_type, icmp_type=icmp_type,
actions='strip_vlan,output:{:d}'.format(port.ofport), actions='output:{:d}'.format(port.ofport),
) )
def _initialize_ingress(self, port): def _initialize_ingress(self, port):
@ -788,7 +788,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
dl_type=constants.ETHERTYPE_ARP, dl_type=constants.ETHERTYPE_ARP,
reg_port=port.ofport, reg_port=port.ofport,
dl_dst=port.mac, dl_dst=port.mac,
actions='strip_vlan,output:{:d}'.format(port.ofport), actions='output:{:d}'.format(port.ofport),
) )
self._initialize_ingress_ipv6_icmp(port) self._initialize_ingress_ipv6_icmp(port)
@ -804,7 +804,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
nw_proto=lib_const.PROTO_NUM_UDP, nw_proto=lib_const.PROTO_NUM_UDP,
tp_src=src_port, tp_src=src_port,
tp_dst=dst_port, tp_dst=dst_port,
actions='strip_vlan,output:{:d}'.format(port.ofport), actions='output:{:d}'.format(port.ofport),
) )
# Track untracked # Track untracked
@ -856,7 +856,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
ct_state=state, ct_state=state,
ct_mark=ovsfw_consts.CT_MARK_NORMAL, ct_mark=ovsfw_consts.CT_MARK_NORMAL,
ct_zone=port.vlan_tag, ct_zone=port.vlan_tag,
actions='strip_vlan,output:{:d}'.format(port.ofport) actions='output:{:d}'.format(port.ofport)
) )
self._add_flow( self._add_flow(
table=ovs_consts.RULES_INGRESS_TABLE, table=ovs_consts.RULES_INGRESS_TABLE,

View File

@ -78,7 +78,7 @@ def populate_flow_common(direction, flow_template, port):
if direction == firewall.INGRESS_DIRECTION: if direction == firewall.INGRESS_DIRECTION:
flow_template['table'] = ovs_consts.RULES_INGRESS_TABLE flow_template['table'] = ovs_consts.RULES_INGRESS_TABLE
flow_template['dl_dst'] = port.mac flow_template['dl_dst'] = port.mac
flow_template['actions'] = "strip_vlan,output:{:d}".format(port.ofport) flow_template['actions'] = "output:{:d}".format(port.ofport)
elif direction == firewall.EGRESS_DIRECTION: elif direction == firewall.EGRESS_DIRECTION:
flow_template['table'] = ovs_consts.RULES_EGRESS_TABLE flow_template['table'] = ovs_consts.RULES_EGRESS_TABLE
flow_template['dl_src'] = port.mac flow_template['dl_src'] = port.mac

View File

@ -472,7 +472,7 @@ class TestOVSFirewallDriver(base.BaseTestCase):
table=ovs_consts.TRANSIENT_TABLE) table=ovs_consts.TRANSIENT_TABLE)
exp_ingress_classifier = mock.call( exp_ingress_classifier = mock.call(
actions='set_field:{:d}->reg5,set_field:{:d}->reg6,' actions='set_field:{:d}->reg5,set_field:{:d}->reg6,'
'resubmit(,{:d})'.format( 'strip_vlan,resubmit(,{:d})'.format(
self.port_ofport, TESTING_VLAN_TAG, self.port_ofport, TESTING_VLAN_TAG,
ovs_consts.BASE_INGRESS_TABLE), ovs_consts.BASE_INGRESS_TABLE),
dl_dst=self.port_mac, dl_dst=self.port_mac,
@ -480,7 +480,7 @@ class TestOVSFirewallDriver(base.BaseTestCase):
table=ovs_consts.TRANSIENT_TABLE) table=ovs_consts.TRANSIENT_TABLE)
filter_rule = mock.call( filter_rule = mock.call(
actions='ct(commit,zone=NXM_NX_REG6[0..15]),' actions='ct(commit,zone=NXM_NX_REG6[0..15]),'
'strip_vlan,output:{:d}'.format(self.port_ofport), 'output:{:d}'.format(self.port_ofport),
dl_dst=self.port_mac, dl_dst=self.port_mac,
dl_type="0x{:04x}".format(n_const.ETHERTYPE_IP), dl_type="0x{:04x}".format(n_const.ETHERTYPE_IP),
nw_proto=constants.PROTO_NUM_TCP, nw_proto=constants.PROTO_NUM_TCP,

View File

@ -187,7 +187,7 @@ class TestCreateProtocolFlows(base.BaseTestCase):
expected_flows = [{ expected_flows = [{
'table': ovs_consts.RULES_INGRESS_TABLE, 'table': ovs_consts.RULES_INGRESS_TABLE,
'dl_dst': self.port.mac, 'dl_dst': self.port.mac,
'actions': 'strip_vlan,output:1', 'actions': 'output:1',
'nw_proto': constants.PROTO_NUM_TCP, 'nw_proto': constants.PROTO_NUM_TCP,
}] }]
self._test_create_protocol_flows_helper( self._test_create_protocol_flows_helper(
@ -368,7 +368,7 @@ class TestCreateConjFlows(base.BaseTestCase):
flows[0]['ct_state']) flows[0]['ct_state'])
self.assertEqual(ovsfw_consts.OF_STATE_NEW_NOT_ESTABLISHED, self.assertEqual(ovsfw_consts.OF_STATE_NEW_NOT_ESTABLISHED,
flows[1]['ct_state']) flows[1]['ct_state'])
self.assertEqual("strip_vlan,output:{:d}".format(port.ofport), self.assertEqual("output:{:d}".format(port.ofport),
flows[0]['actions']) flows[0]['actions'])
self.assertEqual("ct(commit,zone=NXM_NX_REG{:d}[0..15]),{:s}".format( self.assertEqual("ct(commit,zone=NXM_NX_REG{:d}[0..15]),{:s}".format(
ovsfw_consts.REG_NET, flows[0]['actions']), ovsfw_consts.REG_NET, flows[0]['actions']),