diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py index edf8bdada44..5e367352843 100644 --- a/neutron/agent/common/ovs_lib.py +++ b/neutron/agent/common/ovs_lib.py @@ -282,7 +282,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, @@ -291,6 +291,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 3dad1a829a0..6d3a03f2b41 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -1187,6 +1187,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) @@ -1340,6 +1343,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 a58fac174f6..55a10fa51d5 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 @@ -1374,7 +1374,8 @@ class TestOvsNeutronAgent(object): self.assertNotIn('activated_port_id', port_info['added']) 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"),\ @@ -1432,6 +1433,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: @@ -1501,6 +1504,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"),\ @@ -1556,6 +1563,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', @@ -1596,6 +1605,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() @@ -1620,6 +1631,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 a3b0d6dbb0a..addbdbac499 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 @@ -231,6 +231,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 += [ @@ -260,6 +262,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, @@ -714,7 +717,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 += [ @@ -737,7 +742,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,