Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions neutron/agent/linux/openvswitch_firewall/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ def __init__(self, integration_bridge):
self._initialize_sg()
self._update_cookie = None
self._deferred = False
self._ports_pending_invalid_ct_cleanup = []
self.iptables_helper = iptables.Helper(self.int_br.br)
self.iptables_helper.load_driver_if_needed()
self.ipconntrack = ip_conntrack.OvsIpConntrackManager()
Expand Down Expand Up @@ -702,11 +703,22 @@ def _get_port_physical_network(self, port_name):
return get_physical_network_from_other_config(
self.int_br.br, port_name)

def _delete_invalid_conntrack_entries_for_port(self, port, of_port):
port['of_port'] = of_port
def _delete_invalid_conntrack_entries_for_port(self, ports):
for ethertype in [lib_const.IPv4, lib_const.IPv6]:
self.ipconntrack.delete_conntrack_state_by_remote_ips(
[port], ethertype, set(), mark=ovsfw_consts.CT_MARK_INVALID)
ports, ethertype, set(), mark=ovsfw_consts.CT_MARK_INVALID)

def _schedule_invalid_conntrack_entries_cleanup(self, port):
if self._deferred:
self._ports_pending_invalid_ct_cleanup.append(port)
else:
self._delete_invalid_conntrack_entries_for_port([port])

def _flush_pending_invalid_conntrack_cleanup(self):
self._delete_invalid_conntrack_entries_for_port(
self._ports_pending_invalid_ct_cleanup
)
self._ports_pending_invalid_ct_cleanup = []

def get_ofport(self, port):
port_id = port['device']
Expand Down Expand Up @@ -768,7 +780,8 @@ def prepare_port_filter(self, port):
self._update_flows_for_port(of_port, old_of_port)
else:
self._set_port_filters(of_port)
self._delete_invalid_conntrack_entries_for_port(port, of_port)
port['of_port'] = of_port
self._schedule_invalid_conntrack_entries_cleanup(port)
except exceptions.OVSFWPortNotFound as not_found_error:
LOG.info("port %(port_id)s does not exist in ovsdb: %(err)s.",
{'port_id': port['device'],
Expand Down Expand Up @@ -808,7 +821,8 @@ def update_port_filter(self, port):
else:
self._set_port_filters(of_port)

self._delete_invalid_conntrack_entries_for_port(port, of_port)
port['of_port'] = of_port
self._schedule_invalid_conntrack_entries_cleanup(port)

except exceptions.OVSFWPortNotFound as not_found_error:
LOG.info("port %(port_id)s does not exist in ovsdb: %(err)s.",
Expand Down Expand Up @@ -897,11 +911,13 @@ def remove_trusted_ports(self, port_ids):

def filter_defer_apply_on(self):
self._deferred = True
self._ports_pending_invalid_ct_cleanup = []

def filter_defer_apply_off(self):
if self._deferred:
self._cleanup_stale_sg()
self.int_br.apply_flows()
self._flush_pending_invalid_conntrack_cleanup()
self._deferred = False

@property
Expand Down
5 changes: 5 additions & 0 deletions neutron/agent/ovn/metadata/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,11 @@ def _get_port_ip4_ips_and_ip6_flag(self, port):
LOG.warning("Port %s MAC column is empty, cannot retrieve IP "
"addresses", port.uuid)
return [], False
if port.mac == [ovn_const.UNKNOWN_ADDR]:
LOG.warning("Port %s MAC column value is %s, this port will "
"not have metadata service", port.uuid, port.mac)
return [], False

mac, ips = ovn_utils.get_mac_and_ips_from_port_binding(port)
if not ips:
LOG.debug("Port %s IP addresses were not retrieved from the "
Expand Down
1 change: 1 addition & 0 deletions neutron/conf/policies/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
# related to the "network owner" and network isn't really parent of the subnet
# or port. Because of that, using parent owner in those cases may be
# missleading for users so it's better to keep also "network owner" rules.
NET_OWNER_MANAGER = 'role:manager and ' + RULE_NET_OWNER
NET_OWNER_MEMBER = 'role:member and ' + RULE_NET_OWNER
NET_OWNER_READER = 'role:reader and ' + RULE_NET_OWNER
ADMIN_OR_NET_OWNER_MEMBER = (
Expand Down
19 changes: 1 addition & 18 deletions neutron/conf/policies/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
check_str=neutron_policy.policy_or(
'not rule:network_device',
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER
),
scope_types=['project'],
Expand All @@ -119,7 +118,6 @@
name='create_port:mac_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER),
scope_types=['project'],
description='Specify ``mac_address`` attribute when creating a port',
Expand All @@ -136,7 +134,6 @@
name='create_port:fixed_ips',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER,
'rule:shared'),
scope_types=['project'],
Expand All @@ -155,7 +152,6 @@
name='create_port:fixed_ips:ip_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER),
scope_types=['project'],
description='Specify IP address in ``fixed_ips`` when creating a port',
Expand All @@ -172,7 +168,6 @@
name='create_port:fixed_ips:subnet_id',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER,
'rule:shared'),
scope_types=['project'],
Expand All @@ -191,7 +186,6 @@
name='create_port:port_security_enabled',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER),
scope_types=['project'],
description=(
Expand Down Expand Up @@ -258,7 +252,6 @@
name='create_port:allowed_address_pairs',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description=(
Expand All @@ -276,7 +269,6 @@
name='create_port:allowed_address_pairs:mac_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description=(
Expand All @@ -294,7 +286,6 @@
name='create_port:allowed_address_pairs:ip_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description=(
Expand Down Expand Up @@ -496,7 +487,6 @@
check_str=neutron_policy.policy_or(
'not rule:network_device',
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER,
),
scope_types=['project'],
Expand All @@ -515,7 +505,7 @@
name='update_port:mac_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER
base.NET_OWNER_MANAGER,
),
scope_types=['project'],
description='Update ``mac_address`` attribute of a port',
Expand All @@ -532,7 +522,6 @@
name='update_port:fixed_ips',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER
),
scope_types=['project'],
Expand All @@ -550,7 +539,6 @@
name='update_port:fixed_ips:ip_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER
),
scope_types=['project'],
Expand All @@ -571,7 +559,6 @@
name='update_port:fixed_ips:subnet_id',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER,
'rule:shared'
),
Expand All @@ -594,7 +581,6 @@
name='update_port:port_security_enabled',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_SERVICE,
base.PROJECT_MANAGER,
base.NET_OWNER_MEMBER
),
scope_types=['project'],
Expand Down Expand Up @@ -653,7 +639,6 @@
name='update_port:allowed_address_pairs',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description='Update ``allowed_address_pairs`` attribute of a port',
Expand All @@ -668,7 +653,6 @@
name='update_port:allowed_address_pairs:mac_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description=(
Expand All @@ -686,7 +670,6 @@
name='update_port:allowed_address_pairs:ip_address',
check_str=neutron_policy.policy_or(
base.ADMIN_OR_NET_OWNER_MEMBER,
base.PROJECT_MANAGER,
base.SERVICE),
scope_types=['project'],
description=(
Expand Down
4 changes: 2 additions & 2 deletions neutron/conf/policies/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,15 +315,15 @@
scope_types=['project'],
description=('Specify ``enable_default_route_bfd`` attribute when '
'updating a router'),
operations=ACTION_POST,
operations=ACTION_PUT,
),
policy.DocumentedRuleDefault(
name='update_router:enable_default_route_ecmp',
check_str=base.ADMIN,
scope_types=['project'],
description=('Specify ``enable_default_route_ecmp`` attribute when '
'updating a router'),
operations=ACTION_POST,
operations=ACTION_PUT,
),
policy.DocumentedRuleDefault(
name='update_router:tags',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,15 @@ def port_unbound(self, vif_id, net_uuid=None):
if not lvm.vif_ports:
self.reclaim_local_vlan(net_uuid, lvm.segmentation_id)

@staticmethod
def _has_valid_ofport(port):
return port.ofport and port.ofport != ovs_lib.INVALID_OFPORT

def port_alive(self, port, log_errors=True):
if not self._has_valid_ofport(port):
LOG.warning("port_alive skipped for port %s: invalid ofport %s",
port.port_name, port.ofport)
return
cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag",
log_errors=log_errors)
# Port normal vlan tag is set correctly, remove the drop flows
Expand All @@ -1505,6 +1513,10 @@ def port_dead(self, port, log_errors=True):

:param port: an ovs_lib.VifPort object.
'''
if not self._has_valid_ofport(port):
LOG.warning("port_dead skipped for port %s: invalid ofport %s",
port.port_name, port.ofport)
return
# Don't kill a port if it's already dead
cur_tag = self.int_br.db_get_val("Port", port.port_name, "tag",
log_errors=log_errors)
Expand Down Expand Up @@ -1856,9 +1868,11 @@ def _process_port(port, ports, ancillary_ports):
iface_id = self.int_br.portid_from_external_ids(
port['external_ids'])
if iface_id:
if port['ofport'] == ovs_lib.UNASSIGNED_OFPORT:
LOG.debug("Port %s not ready yet on the bridge",
iface_id)
if port['ofport'] in (ovs_lib.UNASSIGNED_OFPORT,
ovs_lib.INVALID_OFPORT):
LOG.debug("Port %s not ready yet on the bridge "
"(ofport=%s)",
iface_id, port['ofport'])
ports_not_ready_yet.add(port['name'])
return
# check if port belongs to ancillary bridge
Expand Down Expand Up @@ -1964,19 +1978,12 @@ def treat_vif_port(self, vif_port, port_id, network_id, network_type,
physical_network, segmentation_id, admin_state_up,
fixed_ips, device_owner, provisioning_needed):
port_needs_binding = True
if not vif_port.ofport:
# Log an error if the VIF port has no ofport, which indicates
# that the port might not be able to transmit traffic.
LOG.error("VIF port: %s has no ofport and might not "
"be able to transmit.", vif_port.vif_id)
elif vif_port.ofport == ovs_lib.INVALID_OFPORT:
# When the ofport is set to INVALID_OFPORT, it indicates that
# the port is in a transitional state and has not yet been fully
# configured.
LOG.info("VIF port: %s is in a transitional state and has not "
"yet been assigned a valid ofport. This is expected "
"during port initialization. (ofport=%s)",
vif_port.vif_id, vif_port.ofport)
if not self._has_valid_ofport(vif_port):
LOG.warning("VIF port: %s has no valid ofport (ofport=%s), "
"skipping OF operations; the port will be "
"retried on the next iteration.",
vif_port.vif_id, vif_port.ofport)
return False
if admin_state_up:
port_needs_binding = self.port_bound(
vif_port, network_id, network_type,
Expand Down
Loading