Skip to content

Commit f94f8b6

Browse files
gotostackrubasov
authored andcommitted
Add a default goto table=94 for openvswitch fw
If enable explicitly_egress_direct=True and set port as no security group and port_security=False, the ingress flood will reappear. The pipleline is: Ingress table_0 -> table_60 -> NORMAL -> VM Egress table_0 -> ... -> table_94 -> output Because ingress final action is normal, the br-int will learn the source MAC, but egress final action is output. So VM's mac will never be learnt by the br-int. Then ingress flood comes again. This patch adds a default direct flow to table 94 during the openflow security group init and explicitly_egress_direct=True, then the pipleline will be: Ingress table_0 -> table_60 -> table_94 -> output VM Egress table_0 -> ... -> table_94 -> output And this patch adds the flows coming from patch port which will match local vlan then go to table 94 do the same direct actions. Above flood issue will be addressed by these flows. Closes-Bug: #2051351 Change-Id: Ia61784174ee610b338f26660b2954330abc131a1 (cherry picked from commit d6f56c5)
1 parent f0901c7 commit f94f8b6

File tree

6 files changed

+50
-4
lines changed

6 files changed

+50
-4
lines changed

doc/source/contributor/internals/openvswitch_firewall.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,19 @@ will be:
525525
table=94, priority=10,reg6=0x284,dl_src=fa:16:3e:24:57:c7,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=push_vlan:0x8100,set_field:0x1->vlan_vid,output:3
526526
table=94, priority=1 actions=NORMAL
527527

528+
The OVS firewall will initialize a default goto table 94 flow
529+
on TRANSIENT_TABLE |table_60|, if ``explicitly_egress_direct``
530+
is set to True, which is mainly for ports without security groups
531+
and disabled port_security. For instance:
532+
533+
::
534+
table=60, priority=2 actions=resubmit(,94)
535+
536+
Then for packets from the outside to VM without security functionalities
537+
(--disable-port-security --no-security-group)
538+
will go to table 94 and do the same direct actions.
539+
540+
528541
OVS firewall integration points
529542
-------------------------------
530543

neutron/agent/linux/openvswitch_firewall/firewall.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,14 @@ def _initialize_common_flows(self):
646646
'resubmit(,%d)' % ovs_consts.BASE_EGRESS_TABLE,
647647
)
648648

649+
if cfg.CONF.AGENT.explicitly_egress_direct:
650+
self._add_flow(
651+
table=ovs_consts.TRANSIENT_TABLE,
652+
priority=2,
653+
actions='resubmit(,%d)' % (
654+
ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE)
655+
)
656+
649657
def _initialize_third_party_tables(self):
650658
self.int_br.br.add_flow(
651659
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
@@ -1255,6 +1263,7 @@ def install_accepted_egress_direct_flow(self, mac, vlan_tag, dst_port,
12551263
return
12561264

12571265
# Prevent flood for accepted egress traffic
1266+
# For packets from internal ports or VM ports.
12581267
self._add_flow(
12591268
flow_group_id=dst_port,
12601269
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
@@ -1263,6 +1272,15 @@ def install_accepted_egress_direct_flow(self, mac, vlan_tag, dst_port,
12631272
reg_net=vlan_tag,
12641273
actions='output:{:d}'.format(dst_port)
12651274
)
1275+
# For packets from patch ports.
1276+
self._add_flow(
1277+
flow_group_id=dst_port,
1278+
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
1279+
priority=12,
1280+
dl_dst=mac,
1281+
dl_vlan=vlan_tag,
1282+
actions='strip_vlan,output:{:d}'.format(dst_port)
1283+
)
12661284

12671285
# The former flow may not match, that means the destination port is
12681286
# not in this host. So, we direct the packet to mapped bridge(s).
@@ -1311,6 +1329,12 @@ def delete_accepted_egress_direct_flow(self, mac, vlan_tag):
13111329
dl_src=mac,
13121330
reg_net=vlan_tag)
13131331

1332+
self._delete_flows(
1333+
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
1334+
dl_dst=mac,
1335+
dl_vlan=vlan_tag
1336+
)
1337+
13141338
def _initialize_tracked_egress(self, port):
13151339
# Drop invalid packets
13161340
self._add_flow(

neutron/conf/plugins/ml2/drivers/ovs_conf.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,16 @@
222222
"outgoing IP packet carrying GRE/VXLAN tunnel.")),
223223
cfg.BoolOpt('baremetal_smartnic', default=False,
224224
help=_("Enable the agent to process Smart NIC ports.")),
225+
# TODO(liuyulong): consider adding a new configuration
226+
# item to control ingress behavior.
225227
cfg.BoolOpt('explicitly_egress_direct', default=False,
226228
help=_("When set to True, the accepted egress unicast "
227229
"traffic will not use action NORMAL. The accepted "
228230
"egress packets will be taken care of in the final "
229231
"egress tables direct output flows for unicast "
230-
"traffic.")),
232+
"traffic. This will aslo change the pipleline for "
233+
"ingress traffic to ports without security, the final "
234+
"output action will be hit in table 94. ")),
231235
]
232236

233237
dhcp_opts = [

neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/br_int.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def setup_default_table(self, enable_openflow_dhcp=False,
6464
self.install_goto(dest_table_id=PACKET_RATE_LIMIT)
6565
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
6666
table_id=PACKET_RATE_LIMIT)
67-
self.install_normal(table_id=constants.TRANSIENT_TABLE, priority=3)
67+
self.install_normal(table_id=constants.TRANSIENT_TABLE, priority=1)
6868
self.init_dhcp(enable_openflow_dhcp=enable_openflow_dhcp,
6969
enable_dhcpv6=enable_dhcpv6)
7070
self.install_drop(table_id=constants.ARP_SPOOF_TABLE)

neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,13 @@ def test_delete_all_port_flows(self):
919919
"reg6": port.vlan_tag}
920920
flow7 = mock.call(**call_args7)
921921

922+
call_args8 = {"table": ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
923+
"dl_dst": port.mac,
924+
"dl_vlan": port.vlan_tag}
925+
flow8 = mock.call(**call_args8)
926+
922927
self.mock_bridge.br.delete_flows.assert_has_calls(
923-
[flow1, flow2, flow3, flow6, flow7, flow4, flow5])
928+
[flow1, flow2, flow3, flow6, flow7, flow8, flow4, flow5])
924929

925930
def test_prepare_port_filter_initialized_port(self):
926931
port_dict = {'device': 'port-id',

neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/native/test_br_int.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def test_setup_default_table(self):
7575
]),
7676
],
7777
match=ofpp.OFPMatch(),
78-
priority=3,
78+
priority=1,
7979
table_id=ovs_constants.TRANSIENT_TABLE),
8080
active_bundle=None),
8181
call._send_msg(ofpp.OFPFlowMod(dp,

0 commit comments

Comments
 (0)