Mark bridge_mappings as deprecated for ofagent.
Document that it will be removed in Kilo.
Implements: blueprint ofagent-physical-interface-mappings
Change-Id: I38e3b6aad2914dc5425435dd7775f66306375cd2
portbindings.OVS_HYBRID_PLUG: True})
def check_segment_for_agent(self, segment, agent):
- mappings = agent['configurations'].get('bridge_mappings', {})
+ bridge_mappings = agent['configurations'].get('bridge_mappings', {})
+ interface_mappings = agent['configurations'].get('interface_mappings',
+ {})
tunnel_types = agent['configurations'].get('tunnel_types', [])
- LOG.debug(_("Checking segment: %(segment)s "
- "for mappings: %(mappings)s "
- "with tunnel_types: %(tunnel_types)s"),
- {'segment': segment, 'mappings': mappings,
+ LOG.debug("Checking segment: %(segment)s "
+ "for bridge_mappings: %(bridge_mappings)s "
+ "and interface_mappings: %(interface_mappings)s "
+ "with tunnel_types: %(tunnel_types)s",
+ {'segment': segment,
+ 'bridge_mappings': bridge_mappings,
+ 'interface_mappings': interface_mappings,
'tunnel_types': tunnel_types})
network_type = segment[api.NETWORK_TYPE]
return (
network_type == p_const.TYPE_LOCAL or
network_type in tunnel_types or
(network_type in [p_const.TYPE_FLAT, p_const.TYPE_VLAN] and
- segment[api.PHYSICAL_NETWORK] in mappings)
+ (segment[api.PHYSICAL_NETWORK] in bridge_mappings
+ or segment[api.PHYSICAL_NETWORK] in interface_mappings))
)
# -- Notes for updating from Icehouce
+OVS.bridge_mappings is deprecated for ofagent. It's planned to be
+removed in Kilo. Please use AGENT.physical_interface_mappings instead.
+To mimic an existing setup with bridge_mapping, you can create
+a veth pair, link one side of it to the bridge, and then specify
+the other side in physical_interface_mappings.
+For example, if you have the following:
+
+ [OVS]
+ bridge_mappings=public:br-ex
+
+You can do:
+
+ # ip link add int-public type veth peer name phy-public
+ # ip link set int-public up
+ # ip link set phy-public up
+ # ovs-vsctl add-port br-ex phy-public
+
+and then replace the bridge_mappings with:
+
+ [AGENT]
+ physical_interface_mappings=public:int-public
+
After Icehouce, most of the functionality have been folded into
a single bridge, the integration bridge. (aka. br-int)
The integration bridge is the only bridge which would have an
RPC_API_VERSION = '1.1'
def __init__(self, ryuapp, integ_br, local_ip,
- bridge_mappings, root_helper,
+ bridge_mappings, interface_mappings, root_helper,
polling_interval, tunnel_types=None,
veth_mtu=None):
"""Constructor.
:param integ_br: name of the integration bridge.
:param local_ip: local IP address of this hypervisor.
:param bridge_mappings: mappings from physical network name to bridge.
+ (deprecated)
+ :param interface_mappings: mappings from physical network name to
+ interface.
:param root_helper: utility to use when running shell cmds.
:param polling_interval: interval (secs) to poll DB.
:param tunnel_types: A list of tunnel types to enable support for in
'binary': 'neutron-ofa-agent',
'host': cfg.CONF.host,
'topic': n_const.L2_AGENT_TOPIC,
- 'configurations': {'bridge_mappings': bridge_mappings,
- 'tunnel_types': self.tunnel_types,
- 'tunneling_ip': local_ip,
- 'l2_population': True,
- 'l2pop_network_types': l2pop_network_types},
+ 'configurations': {
+ 'bridge_mappings': bridge_mappings,
+ 'interface_mappings': interface_mappings,
+ 'tunnel_types': self.tunnel_types,
+ 'tunneling_ip': local_ip,
+ 'l2_population': True,
+ 'l2pop_network_types': l2pop_network_types},
'agent_type': n_const.AGENT_TYPE_OFA,
'start_flag': True}
self.updated_ports = set()
self.setup_rpc()
self.setup_integration_br()
+ self.int_ofports = {}
+ self.setup_physical_interfaces(interface_mappings)
+ # TODO(yamamoto): Remove physical bridge support
self.setup_physical_bridges(bridge_mappings)
self.local_vlan_map = {}
self.tun_ofports = {}
:param bridge_mappings: map physical network names to bridge names.
"""
self.phys_brs = {}
- self.int_ofports = {}
self.phys_ofports = {}
ip_wrapper = ip_lib.IPWrapper(self.root_helper)
for physical_network, bridge in bridge_mappings.iteritems():
self._phys_br_patch_physical_bridge_with_integration_bridge(
br, physical_network, bridge, ip_wrapper)
+ def setup_physical_interfaces(self, interface_mappings):
+ """Setup the physical network interfaces.
+
+ Link physical network interfaces to the integration bridge.
+
+ :param interface_mappings: map physical network names to
+ interface names.
+ """
+ for physical_network, interface_name in interface_mappings.iteritems():
+ ofport = int(self.int_br.add_port(interface_name))
+ self.int_ofports[physical_network] = ofport
+
def scan_ports(self, registered_ports, updated_ports=None):
cur_ports = self._get_ofport_names(self.int_br)
self.int_br_device_count = len(cur_ports)
bridge_mappings = n_utils.parse_mappings(config.OVS.bridge_mappings)
except ValueError as e:
raise ValueError(_("Parsing bridge_mappings failed: %s.") % e)
+ try:
+ interface_mappings = n_utils.parse_mappings(
+ config.AGENT.physical_interface_mappings)
+ except ValueError as e:
+ raise ValueError(_("Parsing physical_interface_mappings failed: %s.")
+ % e)
kwargs = dict(
integ_br=config.OVS.integration_bridge,
local_ip=config.OVS.local_ip,
+ interface_mappings=interface_mappings,
bridge_mappings=bridge_mappings,
root_helper=config.AGENT.root_helper,
polling_interval=config.AGENT.polling_interval,
cfg.IntOpt('get_datapath_retry_times', default=60,
help=_("Number of seconds to retry acquiring "
"an Open vSwitch datapath")),
+ cfg.ListOpt('physical_interface_mappings',
+ default=[],
+ help=_("List of <physical_network>:<physical_interface>")),
]
help=_("Local IP address of GRE tunnel endpoints.")),
cfg.ListOpt('bridge_mappings',
default=DEFAULT_BRIDGE_MAPPINGS,
- help=_("List of <physical_network>:<bridge>")),
+ help=_("List of <physical_network>:<bridge>. "
+ "Deprecated for ofagent.")),
cfg.StrOpt('tenant_network_type', default='local',
help=_("Network type for tenant networks "
"(local, vlan, gre, vxlan, or none).")),
CAP_PORT_FILTER = True
AGENT_TYPE = constants.AGENT_TYPE_OFA
- GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}
+ GOOD_MAPPINGS = {'fake_physical_network': 'fake_interface'}
GOOD_TUNNEL_TYPES = ['gre', 'vxlan']
- GOOD_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS,
+ GOOD_CONFIGS = {'interface_mappings': GOOD_MAPPINGS,
'tunnel_types': GOOD_TUNNEL_TYPES}
- BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'}
+ BAD_MAPPINGS = {'wrong_physical_network': 'wrong_interface'}
BAD_TUNNEL_TYPES = ['bad_tunnel_type']
- BAD_CONFIGS = {'bridge_mappings': BAD_MAPPINGS,
+ BAD_CONFIGS = {'interface_mappings': BAD_MAPPINGS,
'tunnel_types': BAD_TUNNEL_TYPES}
AGENTS = [{'alive': True,
class OfagentMechanismGreTestCase(OfagentMechanismBaseTestCase,
base.AgentMechanismGreTestCase):
pass
+
+
+# The following tests are for deprecated "bridge_mappings".
+# TODO(yamamoto): Remove them.
+
+class OfagentMechanismPhysBridgeTestCase(base.AgentMechanismBaseTestCase):
+ VIF_TYPE = portbindings.VIF_TYPE_OVS
+ CAP_PORT_FILTER = True
+ AGENT_TYPE = constants.AGENT_TYPE_OFA
+
+ GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}
+ GOOD_TUNNEL_TYPES = ['gre', 'vxlan']
+ GOOD_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS,
+ 'tunnel_types': GOOD_TUNNEL_TYPES}
+
+ BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'}
+ BAD_TUNNEL_TYPES = ['bad_tunnel_type']
+ BAD_CONFIGS = {'bridge_mappings': BAD_MAPPINGS,
+ 'tunnel_types': BAD_TUNNEL_TYPES}
+
+ AGENTS = [{'alive': True,
+ 'configurations': GOOD_CONFIGS}]
+ AGENTS_DEAD = [{'alive': False,
+ 'configurations': GOOD_CONFIGS}]
+ AGENTS_BAD = [{'alive': False,
+ 'configurations': GOOD_CONFIGS},
+ {'alive': True,
+ 'configurations': BAD_CONFIGS}]
+
+ def setUp(self):
+ super(OfagentMechanismPhysBridgeTestCase, self).setUp()
+ self.driver = mech_ofagent.OfagentMechanismDriver()
+ self.driver.initialize()
+
+
+class OfagentMechanismPhysBridgeGenericTestCase(
+ OfagentMechanismPhysBridgeTestCase,
+ base.AgentMechanismGenericTestCase):
+ pass
+
+
+class OfagentMechanismPhysBridgeLocalTestCase(
+ OfagentMechanismPhysBridgeTestCase,
+ base.AgentMechanismLocalTestCase):
+ pass
+
+
+class OfagentMechanismPhysBridgeFlatTestCase(
+ OfagentMechanismPhysBridgeTestCase,
+ base.AgentMechanismFlatTestCase):
+ pass
+
+
+class OfagentMechanismPhysBridgeVlanTestCase(
+ OfagentMechanismPhysBridgeTestCase,
+ base.AgentMechanismVlanTestCase):
+ pass
+
+
+class OfagentMechanismPhysBridgeGreTestCase(
+ OfagentMechanismPhysBridgeTestCase,
+ base.AgentMechanismGreTestCase):
+ pass
self.assertEqual(11, self.agent.int_ofports["physnet1"])
self.assertEqual(25, self.agent.phys_ofports["physnet1"])
+ def test_setup_physical_interfaces(self):
+ with mock.patch.object(self.agent.int_br, "add_port") as add_port_fn:
+ add_port_fn.return_value = "111"
+ self.agent.setup_physical_interfaces({"physnet1": "eth1"})
+ add_port_fn.assert_called_once_with("eth1")
+ self.assertEqual(111, self.agent.int_ofports["physnet1"])
+
def test_port_unbound(self):
with contextlib.nested(
mock.patch.object(self.agent, "reclaim_local_vlan"),