File 0001-Avoid-agents-adding-ports-as-trunk-by-default.patch of Package openstack-neutron
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/agent/common/ovs_lib.py neutron-9.4.2.dev21/neutron/agent/common/ovs_lib.py
*** neutron-9.4.2.dev21-backup/neutron/agent/common/ovs_lib.py 2018-12-17 16:03:21.761022853 -0800
--- neutron-9.4.2.dev21/neutron/agent/common/ovs_lib.py 2018-12-18 14:47:48.361661601 -0800
***************
*** 260,265 ****
--- 260,278 ----
with self.ovsdb.transaction() as txn:
txn.add(self.ovsdb.add_port(self.br_name, port_name,
may_exist=False))
+ # NOTE(mangelajo): Port is added to dead vlan (4095) by default
+ # until it's handled by the neutron-openvswitch-agent. Otherwise it
+ # becomes a trunk port on br-int (receiving traffic for all vlans),
+ # and also triggers issues on ovs-vswitchd related to the
+ # datapath flow revalidator thread, see lp#1767422
+ txn.add(self.ovsdb.db_set(
+ 'Port', port_name, ('tag', constants.DEAD_VLAN_TAG)))
+
+ # TODO(mangelajo): We could accept attr tuples for the Port too
+ # but, that could potentially break usage of this function in
+ # stable branches (where we need to backport).
+ # https://review.openstack.org/#/c/564825/4/neutron/agent/common/
+ # ovs_lib.py@289
if interface_attr_tuples:
txn.add(self.ovsdb.db_set('Interface', port_name,
*interface_attr_tuples))
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/agent/l3/router_info.py neutron-9.4.2.dev21/neutron/agent/l3/router_info.py
*** neutron-9.4.2.dev21-backup/neutron/agent/l3/router_info.py 2017-09-23 11:10:44.000000000 -0700
--- neutron-9.4.2.dev21/neutron/agent/l3/router_info.py 2018-12-18 14:56:02.934852397 -0800
***************
*** 614,619 ****
--- 614,629 ----
prefix=EXTERNAL_DEV_PREFIX,
mtu=ex_gw_port.get('mtu'))
+ if self.agent_conf.external_network_bridge:
+ # NOTE(slaweq): for OVS implementations remove the DEAD VLAN tag
+ # on ports. DEAD VLAN tag is added to each newly created port
+ # and should be removed by L2 agent but if
+ # external_network_bridge is set than external gateway port is
+ # created in this bridge and will not be touched by L2 agent.
+ # This is related to lp#1767422
+ self.driver.remove_vlan_tag(
+ self.agent_conf.external_network_bridge, interface_name)
+
def _get_external_gw_ips(self, ex_gw_port):
gateway_ips = []
if 'subnets' in ex_gw_port:
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/agent/linux/interface.py neutron-9.4.2.dev21/neutron/agent/linux/interface.py
*** neutron-9.4.2.dev21-backup/neutron/agent/linux/interface.py 2017-09-23 11:10:44.000000000 -0700
--- neutron-9.4.2.dev21/neutron/agent/linux/interface.py 2018-12-18 14:58:23.282430711 -0800
***************
*** 238,243 ****
--- 238,254 ----
def get_device_name(self, port):
return (self.DEV_NAME_PREFIX + port.id)[:self.DEV_NAME_LEN]
+ def remove_vlan_tag(self, bridge, interface_name):
+ """Remove vlan tag from given interface.
+
+ This method is necessary only for the case when deprecated
+ option 'external_network_bridge' is used in L3 agent as
+ external gateway port is then created in this external bridge
+ directly and it will have DEAD_VLAN_TAG added by default.
+ """
+ # TODO(slaweq): remove it when external_network_bridge option will be
+ # removed
+
@staticmethod
def configure_ipv6_ra(namespace, dev_name, value):
"""Configure handling of IPv6 Router Advertisements on an
***************
*** 347,352 ****
--- 358,367 ----
ovs = ovs_lib.OVSBridge(bridge)
ovs.replace_port(device_name, *attrs)
+ def remove_vlan_tag(self, bridge, interface):
+ ovs = ovs_lib.OVSBridge(bridge)
+ ovs.clear_db_attribute("Port", interface, "tag")
+
def plug_new(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None, prefix=None, mtu=None):
"""Plug in the interface."""
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/tests/common/net_helpers.py neutron-9.4.2.dev21/neutron/tests/common/net_helpers.py
*** neutron-9.4.2.dev21-backup/neutron/tests/common/net_helpers.py 2017-09-23 11:10:44.000000000 -0700
--- neutron-9.4.2.dev21/neutron/tests/common/net_helpers.py 2018-12-18 15:01:42.826132346 -0800
***************
*** 741,746 ****
--- 741,750 ----
self.mac,
bridge=self.bridge.br_name,
namespace=self.namespace)
+ # NOTE(mangelajo): for OVS implementations remove the DEAD VLAN tag
+ # on ports that we intend to use as fake vm interfaces, they
+ # need to be flat. This is related to lp#1767422
+ self.bridge.clear_db_attribute("Port", port_name, "tag")
self.addCleanup(self.bridge.delete_port, port_name)
self.port = ip_lib.IPDevice(port_name, self.namespace)
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/l2/base.py neutron-9.4.2.dev21/neutron/tests/functional/agent/l2/base.py
*** neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/l2/base.py 2017-09-23 11:10:44.000000000 -0700
--- neutron-9.4.2.dev21/neutron/tests/functional/agent/l2/base.py 2018-12-18 15:03:34.937795498 -0800
***************
*** 394,401 ****
self._plug_ports(network, ports, self.agent, bridge=phys_br,
namespace=namespace)
!
! if phys_segmentation_id and network_type == 'vlan':
for port in ports:
phys_br.set_db_attribute(
"Port", port['vif_name'], "tag", phys_segmentation_id)
--- 394,406 ----
self._plug_ports(network, ports, self.agent, bridge=phys_br,
namespace=namespace)
! if network_type == 'flat':
! # NOTE(slaweq): for OVS implementations remove the DEAD VLAN tag
! # on ports that belongs to flat network. DEAD VLAN tag is added
! # to each newly created port. This is related to lp#1767422
! for port in ports:
! phys_br.clear_db_attribute("Port", port['vif_name'], "tag")
! elif phys_segmentation_id and network_type == 'vlan':
for port in ports:
phys_br.set_db_attribute(
"Port", port['vif_name'], "tag", phys_segmentation_id)
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/l3/framework.py neutron-9.4.2.dev21/neutron/tests/functional/agent/l3/framework.py
*** neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/l3/framework.py 2017-09-23 11:10:44.000000000 -0700
--- neutron-9.4.2.dev21/neutron/tests/functional/agent/l3/framework.py 2018-12-18 15:07:31.894883761 -0800
***************
*** 32,37 ****
--- 32,38 ----
from neutron.agent.l3 import router_info as l3_router_info
from neutron.agent import l3_agent as l3_agent_main
from neutron.agent.linux import external_process
+ from neutron.agent.linux import interface
from neutron.agent.linux import ip_lib
from neutron.agent.linux import keepalived
from neutron.common import constants as n_const
***************
*** 44,56 ****
_uuid = uuidutils.generate_uuid
def get_ovs_bridge(br_name):
return ovs_lib.OVSBridge(br_name)
class L3AgentTestFramework(base.BaseSudoTestCase):
! INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
NESTED_NAMESPACE_SEPARATOR = '@'
def setUp(self):
--- 45,59 ----
_uuid = uuidutils.generate_uuid
+ OVS_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
+
def get_ovs_bridge(br_name):
return ovs_lib.OVSBridge(br_name)
class L3AgentTestFramework(base.BaseSudoTestCase):
! INTERFACE_DRIVER = OVS_INTERFACE_DRIVER
NESTED_NAMESPACE_SEPARATOR = '@'
def setUp(self):
***************
*** 318,324 ****
def manage_router(self, agent, router):
self.addCleanup(agent._safe_router_removed, router['id'])
! agent._process_added_router(router)
return agent.router_info[router['id']]
def _delete_router(self, agent, router_id):
--- 321,347 ----
def manage_router(self, agent, router):
self.addCleanup(agent._safe_router_removed, router['id'])
!
! # NOTE(mangelajo): Neutron functional for l3 don't rely on openvswitch
! # agent tagging ports, and all ports remain untagged
! # during test execution.
! # Workaround related to lp#1767422 plugs new ports as
! # dead vlan (4095) to avoid issues, we need to remove
! # such tag during functional l3 testing.
! original_plug_new = interface.OVSInterfaceDriver.plug_new
!
! def new_ovs_plug(self, *args, **kwargs):
! original_plug_new(self, *args, **kwargs)
! bridge = (kwargs.get('bridge') or args[4] or
! self.conf.ovs_integration_bridge)
! device_name = kwargs.get('device_name') or args[2]
! ovsbr = ovs_lib.OVSBridge(bridge)
! ovsbr.clear_db_attribute('Port', device_name, 'tag')
!
! with mock.patch(OVS_INTERFACE_DRIVER + '.plug_new', autospec=True) as (
! ovs_plug):
! ovs_plug.side_effect = new_ovs_plug
! agent._process_added_router(router)
return agent.router_info[router['id']]
def _delete_router(self, agent, router_id):
diff -crB --new-file neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/test_ovs_lib.py neutron-9.4.2.dev21/neutron/tests/functional/agent/test_ovs_lib.py
*** neutron-9.4.2.dev21-backup/neutron/tests/functional/agent/test_ovs_lib.py 2018-12-17 16:03:21.765022894 -0800
--- neutron-9.4.2.dev21/neutron/tests/functional/agent/test_ovs_lib.py 2018-12-18 15:13:06.210277942 -0800
***************
*** 25,30 ****
--- 25,32 ----
from neutron.agent.linux import ip_lib
from neutron.agent.ovsdb.native import idlutils
from neutron.common import utils
+ from neutron.plugins.ml2.drivers.openvswitch.agent.common import (
+ constants as agent_const)
from neutron.tests.common.exclusive_resources import port
from neutron.tests.common import net_helpers
from neutron.tests.functional.agent.linux import base
***************
*** 90,95 ****
--- 92,99 ----
self.assertTrue(self.br.port_exists(port_name))
self.assertEqual('test', self.br.db_get_val('Interface', port_name,
'external_ids')['test'])
+ self.assertEqual(agent_const.DEAD_VLAN_TAG,
+ self.br.db_get_val('Port', port_name, 'tag'))
def test_attribute_lifecycle(self):
(port_name, ofport) = self.create_ovs_port()