Skip to content

Commit 5430119

Browse files
authored
Merge pull request #150 from stackhpc/upstream/2023.1-2024-06-17
Synchronise 2023.1 with upstream
2 parents b1ba803 + 0c9735d commit 5430119

File tree

22 files changed

+652
-22
lines changed

22 files changed

+652
-22
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
@@ -644,6 +644,14 @@ def _initialize_common_flows(self):
644644
'resubmit(,%d)' % ovs_consts.BASE_EGRESS_TABLE,
645645
)
646646

647+
if cfg.CONF.AGENT.explicitly_egress_direct:
648+
self._add_flow(
649+
table=ovs_consts.TRANSIENT_TABLE,
650+
priority=2,
651+
actions='resubmit(,%d)' % (
652+
ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE)
653+
)
654+
647655
def _initialize_third_party_tables(self):
648656
self.int_br.br.add_flow(
649657
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
@@ -1253,6 +1261,7 @@ def install_accepted_egress_direct_flow(self, mac, vlan_tag, dst_port,
12531261
return
12541262

12551263
# Prevent flood for accepted egress traffic
1264+
# For packets from internal ports or VM ports.
12561265
self._add_flow(
12571266
flow_group_id=dst_port,
12581267
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
@@ -1261,6 +1270,15 @@ def install_accepted_egress_direct_flow(self, mac, vlan_tag, dst_port,
12611270
reg_net=vlan_tag,
12621271
actions='output:{:d}'.format(dst_port)
12631272
)
1273+
# For packets from patch ports.
1274+
self._add_flow(
1275+
flow_group_id=dst_port,
1276+
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
1277+
priority=12,
1278+
dl_dst=mac,
1279+
dl_vlan=vlan_tag,
1280+
actions='strip_vlan,output:{:d}'.format(dst_port)
1281+
)
12641282

12651283
# The former flow may not match, that means the destination port is
12661284
# not in this host. So, we direct the packet to mapped bridge(s).
@@ -1309,6 +1327,12 @@ def delete_accepted_egress_direct_flow(self, mac, vlan_tag):
13091327
dl_src=mac,
13101328
reg_net=vlan_tag)
13111329

1330+
self._delete_flows(
1331+
table=ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE,
1332+
dl_dst=mac,
1333+
dl_vlan=vlan_tag
1334+
)
1335+
13121336
def _initialize_tracked_egress(self, port):
13131337
# Drop invalid packets
13141338
self._add_flow(

neutron/common/ovn/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,3 +1237,7 @@ def validate_port_forwarding_configuration():
12371237
if any(net_type in provider_network_types
12381238
for net_type in cfg.CONF.ml2.tenant_network_types):
12391239
raise ovn_exc.InvalidPortForwardingConfiguration()
1240+
1241+
1242+
def is_nat_gateway_port_supported(idl):
1243+
return idl.is_col_present('NAT', 'gateway_port')

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,16 @@
228228
"outgoing IP packet carrying GRE/VXLAN tunnel.")),
229229
cfg.BoolOpt('baremetal_smartnic', default=False,
230230
help=_("Enable the agent to process Smart NIC ports.")),
231+
# TODO(liuyulong): consider adding a new configuration
232+
# item to control ingress behavior.
231233
cfg.BoolOpt('explicitly_egress_direct', default=False,
232234
help=_("When set to True, the accepted egress unicast "
233235
"traffic will not use action NORMAL. The accepted "
234236
"egress packets will be taken care of in the final "
235237
"egress tables direct output flows for unicast "
236-
"traffic.")),
238+
"traffic. This will aslo change the pipleline for "
239+
"ingress traffic to ports without security, the final "
240+
"output action will be hit in table 94. ")),
237241
]
238242

239243
dhcp_opts = [

neutron/db/models/tag.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ class Tag(model_base.BASEV2):
2626
tag = sa.Column(sa.String(255), nullable=False, primary_key=True)
2727
standard_attr = orm.relationship(
2828
'StandardAttribute', load_on_pending=True,
29-
backref=orm.backref('tags', lazy='joined', viewonly=True),
29+
backref=orm.backref('tags', lazy='subquery', viewonly=True),
3030
sync_backref=False)
3131
revises_on_change = ('standard_attr', )

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
@@ -57,7 +57,7 @@ def setup_default_table(self, enable_openflow_dhcp=False,
5757
self.install_goto(dest_table_id=constants.PACKET_RATE_LIMIT)
5858
self.install_goto(dest_table_id=constants.TRANSIENT_TABLE,
5959
table_id=constants.PACKET_RATE_LIMIT)
60-
self.install_normal(table_id=constants.TRANSIENT_TABLE, priority=3)
60+
self.install_normal(table_id=constants.TRANSIENT_TABLE, priority=1)
6161
self.init_dhcp(enable_openflow_dhcp=enable_openflow_dhcp,
6262
enable_dhcpv6=enable_dhcpv6)
6363
self.install_drop(table_id=constants.ARP_SPOOF_TABLE)

neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,24 @@ def update_virtual_port_host(self, port_id, chassis_id):
10531053
'Chassis', chassis_id, 'hostname').execute(check_error=True)
10541054
else:
10551055
hostname = ''
1056-
self._plugin.update_virtual_port_host(n_context.get_admin_context(),
1057-
port_id, hostname)
1056+
1057+
# Updates neutron database with hostname for virtual port
1058+
context = n_context.get_admin_context()
1059+
self._plugin.update_virtual_port_host(context, port_id, hostname)
1060+
db_port = self._plugin.get_port(context, port_id)
1061+
check_rev_cmd = self.nb_ovn.check_revision_number(
1062+
port_id, db_port, ovn_const.TYPE_PORTS)
1063+
# Updates OVN NB database with hostname for lsp virtual port
1064+
with self.nb_ovn.transaction(check_error=True) as txn:
1065+
ext_ids = ('external_ids',
1066+
{ovn_const.OVN_HOST_ID_EXT_ID_KEY: hostname})
1067+
txn.add(
1068+
self.nb_ovn.db_set(
1069+
'Logical_Switch_Port', port_id, ext_ids))
1070+
txn.add(check_rev_cmd)
1071+
if check_rev_cmd.result == ovn_const.TXN_COMMITTED:
1072+
ovn_revision_numbers_db.bump_revision(context, db_port,
1073+
ovn_const.TYPE_PORTS)
10581074

10591075
def get_workers(self):
10601076
"""Get any worker instances that should have their own process

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ def get_all_logical_routers_with_rports(self):
361361
columns['external_mac'] = nat.external_mac[0]
362362
if nat.logical_port:
363363
columns['logical_port'] = nat.logical_port[0]
364+
columns['external_ids'] = nat.external_ids
365+
columns['uuid'] = nat.uuid
366+
if utils.is_nat_gateway_port_supported(self):
367+
columns['gateway_port'] = nat.gateway_port
364368
dnat_and_snats.append(columns)
365369
elif nat.type == 'snat':
366370
snat.append(columns)

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,52 @@ def cleanup_old_hash_ring_nodes(self):
11601160
context = n_context.get_admin_context()
11611161
hash_ring_db.cleanup_old_nodes(context, days=5)
11621162

1163+
@periodics.periodic(spacing=600, run_immediately=True)
1164+
def update_nat_floating_ip_with_gateway_port_reference(self):
1165+
"""Set NAT rule gateway_port column to any floating IP without
1166+
router gateway port uuid reference - LP#2035281.
1167+
"""
1168+
1169+
if not utils.is_nat_gateway_port_supported(self._nb_idl):
1170+
raise periodics.NeverAgain()
1171+
1172+
context = n_context.get_admin_context()
1173+
fip_update = []
1174+
lrouters = self._nb_idl.get_all_logical_routers_with_rports()
1175+
for router in lrouters:
1176+
ovn_fips = router['dnat_and_snats']
1177+
for ovn_fip in ovn_fips:
1178+
# Skip FIPs that are already configured with gateway_port
1179+
if ovn_fip['gateway_port']:
1180+
continue
1181+
fip_id = ovn_fip['external_ids'].get(
1182+
ovn_const.OVN_FIP_EXT_ID_KEY)
1183+
if fip_id:
1184+
fip_update.append({'uuid': ovn_fip['uuid'],
1185+
'router_id': router['name']})
1186+
1187+
# Simple caching mechanism to avoid unnecessary DB calls
1188+
gw_port_id_cache = {}
1189+
lrp_cache = {}
1190+
cmds = []
1191+
for fip in fip_update:
1192+
lrouter = utils.ovn_name(fip['router_id'])
1193+
if lrouter not in gw_port_id_cache.keys():
1194+
router_db = self._ovn_client._l3_plugin.get_router(
1195+
context, fip['router_id'], fields=['gw_port_id'])
1196+
gw_port_id_cache[lrouter] = router_db.get('gw_port_id')
1197+
lrp_cache[lrouter] = self._nb_idl.get_lrouter_port(
1198+
gw_port_id_cache[lrouter])
1199+
columns = {'gateway_port': lrp_cache[lrouter].uuid}
1200+
cmds.append(self._nb_idl.set_nat_rule_in_lrouter(
1201+
lrouter, fip['uuid'], **columns))
1202+
1203+
if cmds:
1204+
with self._nb_idl.transaction(check_error=True) as txn:
1205+
for cmd in cmds:
1206+
txn.add(cmd)
1207+
raise periodics.NeverAgain()
1208+
11631209

11641210
class HashRingHealthCheckPeriodics(object):
11651211

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,14 @@ def _create_or_update_floatingip(self, floatingip, txn=None):
850850
'logical_port': floatingip['port_id'],
851851
'external_ids': ext_ids}
852852

853+
# If OVN supports gateway_port column for NAT rules set gateway port
854+
# uuid to any floating IP without gw port reference - LP#2035281.
855+
if utils.is_nat_gateway_port_supported(self._nb_idl):
856+
router_db = self._l3_plugin.get_router(admin_context, router_id)
857+
gw_port_id = router_db.get('gw_port_id')
858+
lrp = self._nb_idl.get_lrouter_port(gw_port_id)
859+
columns['gateway_port'] = lrp.uuid
860+
853861
if ovn_conf.is_ovn_distributed_floating_ip():
854862
if self._nb_idl.lsp_get_up(floatingip['port_id']).execute():
855863
columns['external_mac'] = port_db['mac_address']

0 commit comments

Comments
 (0)