diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py index 6ca5a85d5c0..029f3fffda7 100644 --- a/neutron/agent/common/ovs_lib.py +++ b/neutron/agent/common/ovs_lib.py @@ -281,7 +281,7 @@ class OVSBridge(BaseOVS): def set_igmp_snooping_state(self, state): state = bool(state) other_config = { - 'mcast-snooping-disable-flood-unregistered': str(state)} + 'mcast-snooping-disable-flood-unregistered': 'false'} with self.ovsdb.transaction() as txn: txn.add( self.ovsdb.db_set('Bridge', self.br_name, @@ -290,6 +290,16 @@ class OVSBridge(BaseOVS): self.ovsdb.db_set('Bridge', self.br_name, ('other_config', other_config))) + def set_igmp_snooping_flood(self, port_name, state): + state = str(state) + other_config = { + 'mcast-snooping-flood-reports': state, + 'mcast-snooping-flood': state} + self.ovsdb.db_set( + 'Port', port_name, + ('other_config', other_config)).execute( + check_error=True, log_errors=True) + def create(self, secure_mode=False): other_config = { 'mac-table-size': str(cfg.CONF.OVS.bridge_mac_table_size)} diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py index eb3724a089a..f9d2e964fc5 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -1141,6 +1141,9 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin, "version of OVS does not support tunnels or patch " "ports. Agent terminated!") sys.exit(1) + self.int_br.set_igmp_snooping_flood( + self.conf.OVS.int_peer_patch_port, + self.conf.OVS.igmp_snooping_enable) if self.conf.AGENT.drop_flows_on_start: self.tun_br.uninstall_flows(cookie=ovs_lib.COOKIE_ANY) @@ -1294,6 +1297,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin, phys_ofport = br.add_patch_port( phys_if_name, constants.NONEXISTENT_PEER) + self.int_br.set_igmp_snooping_flood( + int_if_name, self.conf.OVS.igmp_snooping_enable) self.int_ofports[physical_network] = int_ofport self.phys_ofports[physical_network] = phys_ofport diff --git a/neutron/tests/functional/agent/test_ovs_lib.py b/neutron/tests/functional/agent/test_ovs_lib.py index 3fc39389782..131046ae8d2 100644 --- a/neutron/tests/functional/agent/test_ovs_lib.py +++ b/neutron/tests/functional/agent/test_ovs_lib.py @@ -196,8 +196,9 @@ class OVSBridgeTestCase(OVSBridgeTestBase): 'Bridge', ('name', '=', self.br.br_name), columns=['other_config'] ).execute()[0]['other_config'] self.assertEqual( - str(state), - br_other_config['mcast-snooping-disable-flood-unregistered']) + 'false', + br_other_config.get( + 'mcast-snooping-disable-flood-unregistered', '').lower()) def test_set_igmp_snooping_enabled(self): self._test_set_igmp_snooping_state(True) diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py index 7870b2d382c..d7abefcd5cf 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py @@ -1288,7 +1288,8 @@ class TestOvsNeutronAgent(object): self.assertFalse(int_br.drop_port.called) def _test_setup_physical_bridges(self, port_exists=False, - dvr_enabled=False): + dvr_enabled=False, + igmp_snooping_enabled=False): self.agent.enable_distributed_routing = dvr_enabled with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\ mock.patch.object(sys, "exit"),\ @@ -1346,6 +1347,8 @@ class TestOvsNeutronAgent(object): 'phy-br-eth', constants.NONEXISTENT_PEER), ] expected_calls += [ + mock.call.int_br.set_igmp_snooping_flood( + 'int-br-eth', igmp_snooping_enabled), mock.call.int_br.drop_port(in_port='int_ofport') ] if not dvr_enabled: @@ -1415,6 +1418,10 @@ class TestOvsNeutronAgent(object): int_br.add_port.assert_called_with("int-br-eth") phys_br.add_port.assert_called_with("phy-br-eth") + def test_setup_physical_bridges_igmp_snooping_enabled(self): + cfg.CONF.set_override('igmp_snooping_enable', True, 'OVS') + self._test_setup_physical_bridges(igmp_snooping_enabled=True) + def _test_setup_physical_bridges_change_from_veth_to_patch_conf( self, port_exists=False): with mock.patch.object(sys, "exit"),\ @@ -1470,6 +1477,8 @@ class TestOvsNeutronAgent(object): 'phy-br-eth', constants.NONEXISTENT_PEER), ] expected_calls += [ + mock.call.int_br.set_igmp_snooping_flood( + 'int-br-eth', False), mock.call.int_br.drop_port(in_port='int_ofport'), mock.call.phys_br.drop_port(in_port='phy_ofport'), mock.call.int_br.set_db_attribute('Interface', 'int-br-eth', @@ -1510,6 +1519,8 @@ class TestOvsNeutronAgent(object): return_value=False),\ mock.patch.object(self.agent.int_br, 'port_exists', return_value=False),\ + mock.patch.object(self.agent.int_br, + 'set_igmp_snooping_flood'),\ mock.patch.object(sys, "exit"): self.agent.setup_tunnel_br(None) self.agent.setup_tunnel_br() @@ -1534,6 +1545,8 @@ class TestOvsNeutronAgent(object): "add_patch_port") as int_patch_port,\ mock.patch.object(self.agent.tun_br, "add_patch_port") as tun_patch_port,\ + mock.patch.object(self.agent.int_br, + 'set_igmp_snooping_flood'),\ mock.patch.object(sys, "exit"): self.agent.setup_tunnel_br(None) self.agent.setup_tunnel_br() diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_tunnel.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_tunnel.py index e25a7c37abc..6e72714f367 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_tunnel.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_tunnel.py @@ -230,6 +230,8 @@ class TunnelTest(object): mock.call.port_exists('int-%s' % self.MAP_TUN_BRIDGE), mock.call.add_patch_port('int-%s' % self.MAP_TUN_BRIDGE, constants.NONEXISTENT_PEER), + mock.call.set_igmp_snooping_flood('int-%s' % self.MAP_TUN_BRIDGE, + igmp_snooping), ] self.mock_int_bridge_expected += [ @@ -259,6 +261,7 @@ class TunnelTest(object): self.mock_int_bridge_expected += [ mock.call.port_exists('patch-tun'), mock.call.add_patch_port('patch-tun', 'patch-int'), + mock.call.set_igmp_snooping_flood('patch-tun', igmp_snooping), ] self.mock_int_bridge_expected += [ mock.call.get_vif_ports((ovs_lib.INVALID_OFPORT, @@ -713,7 +716,9 @@ class TunnelTestUseVethInterco(TunnelTest): self.mock_int_bridge_expected += [ mock.call.db_get_val('Interface', 'int-%s' % self.MAP_TUN_BRIDGE, 'type', log_errors=False), - mock.call.add_port('int-%s' % self.MAP_TUN_BRIDGE) + mock.call.add_port('int-%s' % self.MAP_TUN_BRIDGE), + mock.call.set_igmp_snooping_flood('int-%s' % self.MAP_TUN_BRIDGE, + igmp_snooping), ] self.mock_int_bridge_expected += [ @@ -736,7 +741,8 @@ class TunnelTestUseVethInterco(TunnelTest): ] self.mock_int_bridge_expected += [ mock.call.port_exists('patch-tun'), - mock.call.add_patch_port('patch-tun', 'patch-int') + mock.call.add_patch_port('patch-tun', 'patch-int'), + mock.call.set_igmp_snooping_flood('patch-tun', igmp_snooping), ] self.mock_int_bridge_expected += [ mock.call.get_vif_ports((ovs_lib.INVALID_OFPORT,