from quantum.api.v2 import attributes
+NETWORK_TYPE = 'provider:network_type'
+PHYSICAL_NETWORK = 'provider:physical_network'
+SEGMENTATION_ID = 'provider:segmentation_id'
+
EXTENDED_ATTRIBUTES_2_0 = {
'networks': {
- 'provider:network_type': {'allow_post': True, 'allow_put': True,
- 'validate': {'type:values': ['flat',
- 'vlan']},
- 'default': attributes.ATTR_NOT_SPECIFIED,
- 'is_visible': True},
- 'provider:physical_network': {'allow_post': True, 'allow_put': True,
- 'default': attributes.ATTR_NOT_SPECIFIED,
- 'is_visible': True},
- 'provider:vlan_id': {'allow_post': True, 'allow_put': True,
- 'convert_to': int,
- 'validate': {'type:range': (1, 4095)},
- 'default': attributes.ATTR_NOT_SPECIFIED,
- 'is_visible': True},
+ NETWORK_TYPE: {'allow_post': True, 'allow_put': True,
+ 'validate': {'type:values': ['flat',
+ 'vlan']},
+ 'default': attributes.ATTR_NOT_SPECIFIED,
+ 'is_visible': True},
+ PHYSICAL_NETWORK: {'allow_post': True, 'allow_put': True,
+ 'default': attributes.ATTR_NOT_SPECIFIED,
+ 'is_visible': True},
+ SEGMENTATION_ID: {'allow_post': True, 'allow_put': True,
+ 'convert_to': int,
+ 'default': attributes.ATTR_NOT_SPECIFIED,
+ 'is_visible': True},
}
}
To create a provider VLAN network using the CLI with admin rights:
(shell) net-create --tenant_id <tenant-id> <net-name> \
- --provider:vlan_id <vlan-id>
+ --provider:segmentation_id <vlan-id>
With admin rights, network dictionaries returned from CLI commands
will also include provider attributes.
from quantum.db import dhcp_rpc_base
from quantum.db import l3_db
from quantum.db import models_v2
+from quantum.extensions import providernet as provider
from quantum.openstack.common import context
from quantum.openstack.common import cfg
from quantum.openstack.common import rpc
def _extend_network_dict(self, context, network):
if self._check_provider_view_auth(context, network):
binding = db.get_network_binding(context.session, network['id'])
- network['provider:physical_network'] = binding.physical_network
+ network[provider.PHYSICAL_NETWORK] = binding.physical_network
if binding.vlan_id == lconst.FLAT_VLAN_ID:
- network['provider:network_type'] = 'flat'
- network['provider:vlan_id'] = None
+ network[provider.NETWORK_TYPE] = 'flat'
+ network[provider.SEGMENTATION_ID] = None
else:
- network['provider:network_type'] = 'vlan'
- network['provider:vlan_id'] = binding.vlan_id
+ network[provider.NETWORK_TYPE] = 'vlan'
+ network[provider.SEGMENTATION_ID] = binding.vlan_id
def _process_provider_create(self, context, attrs):
- network_type = attrs.get('provider:network_type')
- physical_network = attrs.get('provider:physical_network')
- vlan_id = attrs.get('provider:vlan_id')
+ network_type = attrs.get(provider.NETWORK_TYPE)
+ physical_network = attrs.get(provider.PHYSICAL_NETWORK)
+ segmentation_id = attrs.get(provider.SEGMENTATION_ID)
network_type_set = attributes.is_attr_set(network_type)
physical_network_set = attributes.is_attr_set(physical_network)
- vlan_id_set = attributes.is_attr_set(vlan_id)
+ segmentation_id_set = attributes.is_attr_set(segmentation_id)
- if not (network_type_set or physical_network_set or vlan_id_set):
+ if not (network_type_set or physical_network_set or
+ segmentation_id_set):
return (None, None, None)
# Authorize before exposing plugin details to client
msg = _("provider:network_type required")
raise q_exc.InvalidInput(error_message=msg)
elif network_type == 'flat':
- if vlan_id_set:
- msg = _("provider:vlan_id specified for flat network")
+ if segmentation_id_set:
+ msg = _("provider:segmentation_id specified for flat network")
raise q_exc.InvalidInput(error_message=msg)
else:
- vlan_id = lconst.FLAT_VLAN_ID
+ segmentation_id = lconst.FLAT_VLAN_ID
elif network_type == 'vlan':
- if not vlan_id_set:
- msg = _("provider:vlan_id required")
+ if not segmentation_id_set:
+ msg = _("provider:segmentation_id required")
+ raise q_exc.InvalidInput(error_message=msg)
+ if segmentation_id < 1 or segmentation_id > 4094:
+ msg = _("provider:segmentation_id out of range "
+ "(1 through 4094)")
raise q_exc.InvalidInput(error_message=msg)
else:
msg = _("invalid provider:network_type %s" % network_type)
msg = _("provider:physical_network required")
raise q_exc.InvalidInput(error_message=msg)
- return (network_type, physical_network, vlan_id)
+ return (network_type, physical_network, segmentation_id)
def _check_provider_update(self, context, attrs):
- network_type = attrs.get('provider:network_type')
- physical_network = attrs.get('provider:physical_network')
- vlan_id = attrs.get('provider:vlan_id')
+ network_type = attrs.get(provider.NETWORK_TYPE)
+ physical_network = attrs.get(provider.PHYSICAL_NETWORK)
+ segmentation_id = attrs.get(provider.SEGMENTATION_ID)
network_type_set = attributes.is_attr_set(network_type)
physical_network_set = attributes.is_attr_set(physical_network)
- vlan_id_set = attributes.is_attr_set(vlan_id)
+ segmentation_id_set = attributes.is_attr_set(segmentation_id)
- if not (network_type_set or physical_network_set or vlan_id_set):
+ if not (network_type_set or physical_network_set or
+ segmentation_id_set):
return
# Authorize before exposing plugin details to client
# A class to represent a VIF (i.e., a port that has 'iface-id' and 'vif-mac'
# attributes set).
class LocalVLANMapping:
- def __init__(self, vlan, network_type, physical_network, physical_id,
+ def __init__(self, vlan, network_type, physical_network, segmentation_id,
vif_ids=None):
if vif_ids is None:
vif_ids = []
self.vlan = vlan
self.network_type = network_type
self.physical_network = physical_network
- self.physical_id = physical_id
+ self.segmentation_id = segmentation_id
self.vif_ids = vif_ids
def __str__(self):
return ("lv-id = %s type = %s phys-net = %s phys-id = %s" %
(self.vlan, self.network_type, self.physical_network,
- self.physical_id))
+ self.segmentation_id))
class Port(object):
vif_port = self.int_br.get_vif_port_by_id(port['id'])
if vif_port:
if port['admin_state_up']:
+ # REVISIT(rkukura) This does not seem right. This
+ # needs to be the local_vlan.
vlan_id = kwargs.get('vlan_id')
# create the networking for the port
self.int_br.set_db_attribute("Port", vif_port.port_name,
consumers)
def provision_local_vlan(self, net_uuid, network_type, physical_network,
- physical_id):
+ segmentation_id):
'''Provisions a local VLAN.
:param net_uuid: the uuid of the network associated with this vlan.
:param network_type: the type of the network ('gre', 'vlan', 'flat')
:param physical_network: the physical network for 'vlan' or 'flat'
- :param physical_id: the VLAN ID for 'vlan' or tunnel ID for 'tunnel'
+ :param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
'''
if not self.available_local_vlans:
LOG.info("Assigning %s as local vlan for net-id=%s" % (lvid, net_uuid))
self.local_vlan_map[net_uuid] = LocalVLANMapping(lvid, network_type,
physical_network,
- physical_id)
+ segmentation_id)
if network_type == constants.TYPE_GRE:
# outbound
self.tun_br.add_flow(priority=4, in_port=self.patch_int_ofport,
dl_vlan=lvid,
- actions="set_tunnel:%s,normal" % physical_id)
+ actions="set_tunnel:%s,normal" %
+ segmentation_id)
# inbound bcast/mcast
- self.tun_br.add_flow(priority=3, tun_id=physical_id,
+ self.tun_br.add_flow(priority=3, tun_id=segmentation_id,
dl_dst="01:00:00:00:00:00/01:00:00:00:00:00",
actions="mod_vlan_vid:%s,output:%s" %
(lvid, self.patch_int_ofport))
br.add_flow(priority=4,
in_port=self.phys_ofports[physical_network],
dl_vlan=lvid,
- actions="mod_vlan_vid:%s,normal" % physical_id)
+ actions="mod_vlan_vid:%s,normal" % segmentation_id)
# inbound
self.int_br.add_flow(priority=3,
in_port=self.int_ofports[physical_network],
- dl_vlan=physical_id,
+ dl_vlan=segmentation_id,
actions="mod_vlan_vid:%s,normal" % lvid)
else:
LOG.error("provisioning unknown network type %s for net-id=%s" %
LOG.info("reclaming vlan = %s from net-id = %s" % (lvm.vlan, net_uuid))
if lvm.network_type == constants.TYPE_GRE:
- self.tun_br.delete_flows(tun_id=lvm.physical_id)
+ self.tun_br.delete_flows(tun_id=lvm.segmentation_id)
self.tun_br.delete_flows(dl_vlan=lvm.vlan)
elif network_type == constants.TYPE_FLAT:
# outbound
# inbound
br = self.int_br
br.delete_flows(in_port=self.int_ofports[lvm.physical_network],
- dl_vlan=lvm.physical_id)
+ dl_vlan=lvm.segmentation_id)
else:
LOG.error("reclaiming unknown network type %s for net-id=%s" %
(lvm.network_type, net_uuid))
self.available_local_vlans.add(lvm.vlan)
def port_bound(self, port, net_uuid,
- network_type, physical_network, physical_id):
+ network_type, physical_network, segmentation_id):
'''Bind port to net_uuid/lsw_id and install flow for inbound traffic
to vm.
:param net_uuid: the net_uuid this port is to be associated with.
:param network_type: the type of the network ('gre', 'vlan', 'flat')
:param physical_network: the physical network for 'vlan' or 'flat'
- :param physical_id: the VLAN ID for 'vlan' or tunnel ID for 'tunnel'
+ :param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
'''
if net_uuid not in self.local_vlan_map:
self.provision_local_vlan(net_uuid, network_type,
- physical_network, physical_id)
+ physical_network, segmentation_id)
lvm = self.local_vlan_map[net_uuid]
lvm.vif_ids.append(port.vif_id)
if network_type == constants.TYPE_GRE:
# inbound unicast
- self.tun_br.add_flow(priority=3, tun_id=physical_id,
+ self.tun_br.add_flow(priority=3, tun_id=segmentation_id,
dl_dst=port.vif_mac,
actions="mod_vlan_vid:%s,normal" % lvm.vlan)
self.port_bound(p, new_net_uuid,
bind.network_type,
bind.physical_network,
- bind.physical_id)
+ bind.segmentation_id)
all_bindings[p.vif_id].status = (
q_const.PORT_STATUS_ACTIVE)
LOG.info("Port %s on net-id = %s bound to %s " % (
self.port_bound(port, details['network_id'],
details['network_type'],
details['physical_network'],
- details['physical_id'])
+ details['segmentation_id'])
else:
self.port_unbound(port, details['network_id'])
else:
def add_network_binding(session, network_id, network_type,
- physical_network, physical_id):
+ physical_network, segmentation_id):
with session.begin(subtransactions=True):
binding = ovs_models_v2.NetworkBinding(network_id, network_type,
physical_network,
- physical_id)
+ segmentation_id)
session.add(binding)
primary_key=True)
network_type = Column(String(32), nullable=False) # 'gre', 'vlan', 'flat'
physical_network = Column(String(64))
- physical_id = Column(Integer) # tunnel_id or vlan_id
+ segmentation_id = Column(Integer) # tunnel_id or vlan_id
def __init__(self, network_id, network_type, physical_network,
- physical_id):
+ segmentation_id):
self.network_id = network_id
self.network_type = network_type
self.physical_network = physical_network
- self.physical_id = physical_id
+ self.segmentation_id = segmentation_id
def __repr__(self):
return "<NetworkBinding(%s,%s,%s,%d)>" % (self.network_id,
self.network_type,
self.physical_network,
- self.physical_id)
+ self.segmentation_id)
class TunnelIP(model_base.BASEV2):
from quantum.db import db_base_plugin_v2
from quantum.db import dhcp_rpc_base
from quantum.db import l3_db
+from quantum.extensions import providernet as provider
from quantum.openstack.common import context
from quantum.openstack.common import cfg
from quantum.openstack.common import rpc
'port_id': port['id'],
'admin_state_up': port['admin_state_up'],
'network_type': binding.network_type,
- 'physical_id': binding.physical_id,
+ 'segmentation_id': binding.segmentation_id,
'physical_network': binding.physical_network}
# Set the port status to UP
ovs_db_v2.set_port_status(port['id'], q_const.PORT_STATUS_ACTIVE)
if self._check_provider_view_auth(context, network):
binding = ovs_db_v2.get_network_binding(context.session,
network['id'])
- network['provider:network_type'] = binding.network_type
+ network[provider.NETWORK_TYPE] = binding.network_type
if binding.network_type == constants.TYPE_GRE:
- network['provider:physical_network'] = None
- network['provider:vlan_id'] = None
+ network[provider.PHYSICAL_NETWORK] = None
+ network[provider.SEGMENTATION_ID] = binding.segmentation_id
elif binding.network_type == constants.TYPE_FLAT:
- network['provider:physical_network'] = binding.physical_network
- network['provider:vlan_id'] = None
+ network[provider.PHYSICAL_NETWORK] = binding.physical_network
+ network[provider.SEGMENTATION_ID] = None
elif binding.network_type == constants.TYPE_VLAN:
- network['provider:physical_network'] = binding.physical_network
- network['provider:vlan_id'] = binding.physical_id
+ network[provider.PHYSICAL_NETWORK] = binding.physical_network
+ network[provider.SEGMENTATION_ID] = binding.segmentation_id
def _process_provider_create(self, context, attrs):
- network_type = attrs.get('provider:network_type')
- physical_network = attrs.get('provider:physical_network')
- vlan_id = attrs.get('provider:vlan_id')
+ network_type = attrs.get(provider.NETWORK_TYPE)
+ physical_network = attrs.get(provider.PHYSICAL_NETWORK)
+ segmentation_id = attrs.get(provider.SEGMENTATION_ID)
network_type_set = attributes.is_attr_set(network_type)
physical_network_set = attributes.is_attr_set(physical_network)
- vlan_id_set = attributes.is_attr_set(vlan_id)
+ segmentation_id_set = attributes.is_attr_set(segmentation_id)
- if not (network_type_set or physical_network_set or vlan_id_set):
+ if not (network_type_set or physical_network_set or
+ segmentation_id_set):
return (None, None, None)
# Authorize before exposing plugin details to client
msg = _("provider:network_type required")
raise q_exc.InvalidInput(error_message=msg)
elif network_type == constants.TYPE_FLAT:
- if vlan_id_set:
- msg = _("provider:vlan_id specified for flat network")
+ if segmentation_id_set:
+ msg = _("provider:segmentation_id specified for flat network")
raise q_exc.InvalidInput(error_message=msg)
else:
- vlan_id = constants.FLAT_VLAN_ID
+ segmentation_id = constants.FLAT_VLAN_ID
elif network_type == constants.TYPE_VLAN:
- if not vlan_id_set:
- msg = _("provider:vlan_id required")
+ if not segmentation_id_set:
+ msg = _("provider:segmentation_id required")
+ raise q_exc.InvalidInput(error_message=msg)
+ if segmentation_id < 1 or segmentation_id > 4094:
+ msg = _("provider:segmentation_id out of range "
+ "(1 through 4094)")
raise q_exc.InvalidInput(error_message=msg)
else:
msg = _("invalid provider:network_type %s" % network_type)
msg = _("provider:physical_network required")
raise q_exc.InvalidInput(error_message=msg)
- return (network_type, physical_network, vlan_id)
+ return (network_type, physical_network, segmentation_id)
def _check_provider_update(self, context, attrs):
- network_type = attrs.get('provider:network_type')
- physical_network = attrs.get('provider:physical_network')
- vlan_id = attrs.get('provider:vlan_id')
+ network_type = attrs.get(provider.NETWORK_TYPE)
+ physical_network = attrs.get(provider.PHYSICAL_NETWORK)
+ segmentation_id = attrs.get(provider.SEGMENTATION_ID)
network_type_set = attributes.is_attr_set(network_type)
physical_network_set = attributes.is_attr_set(physical_network)
- vlan_id_set = attributes.is_attr_set(vlan_id)
+ segmentation_id_set = attributes.is_attr_set(segmentation_id)
- if not (network_type_set or physical_network_set or vlan_id_set):
+ if not (network_type_set or physical_network_set or
+ segmentation_id_set):
return
# Authorize before exposing plugin details to client
def create_network(self, context, network):
(network_type, physical_network,
- physical_id) = self._process_provider_create(context,
- network['network'])
+ segmentation_id) = self._process_provider_create(context,
+ network['network'])
session = context.session
with session.begin(subtransactions=True):
if not network_type:
try:
(physical_network,
- physical_id) = ovs_db_v2.reserve_vlan(session)
+ segmentation_id) = ovs_db_v2.reserve_vlan(session)
network_type = constants.TYPE_VLAN
except q_exc.NoNetworkAvailable:
- physical_id = ovs_db_v2.reserve_tunnel(session)
+ segmentation_id = ovs_db_v2.reserve_tunnel(session)
network_type = constants.TYPE_GRE
else:
ovs_db_v2.reserve_specific_vlan(session, physical_network,
- physical_id)
+ segmentation_id)
net = super(OVSQuantumPluginV2, self).create_network(context,
network)
ovs_db_v2.add_network_binding(session, net['id'], network_type,
- physical_network, physical_id)
+ physical_network, segmentation_id)
self._extend_network_dict(context, net)
# note - exception will rollback entire transaction
LOG.debug("Created network: %s" % net['id'])
result = super(OVSQuantumPluginV2, self).delete_network(context,
id)
if binding.network_type == constants.TYPE_GRE:
- ovs_db_v2.release_tunnel(session, binding.physical_id,
+ ovs_db_v2.release_tunnel(session, binding.segmentation_id,
self.tunnel_id_ranges)
else:
ovs_db_v2.release_vlan(session, binding.physical_network,
- binding.physical_id,
+ binding.segmentation_id,
self.network_vlan_ranges)
# the network_binding record is deleted via cascade from
# the network record, so explicit removal is not necessary
if original_port['admin_state_up'] != port['admin_state_up']:
binding = ovs_db_v2.get_network_binding(None,
port['network_id'])
- # REVISIT(rkukura): needs other binding data as well
+ # REVISIT(rkukura): Either all binding data or no
+ # binding data needed.
self.notifier.port_update(self.rpc_context, port,
- binding.physical_id)
+ binding.segmentation_id)
return port
def delete_port(self, context, id, l3_port_check=True):
self.assertEqual(binding.network_id, TEST_NETWORK_ID)
self.assertEqual(binding.network_type, 'vlan')
self.assertEqual(binding.physical_network, PHYS_NET)
- self.assertEqual(binding.physical_id, 1234)
+ self.assertEqual(binding.segmentation_id, 1234)
self.mox.VerifyAll()
def testReclaimLocalVlan(self):
- self.mock_tun_bridge.delete_flows(tun_id=LVM.physical_id)
+ self.mock_tun_bridge.delete_flows(tun_id=LVM.segmentation_id)
self.mock_tun_bridge.delete_flows(dl_vlan=LVM.vlan)