Subnet getNeutronSubnet(Uuid subnetId);
- String uuidToTapPortName(Uuid id);
-
Port getNeutronPort(Uuid portId);
IpAddress getNeutronSubnetGateway(Uuid subnetId);
+ String getVifPortName(Port port);
+
}
}
}
+ /* container to maintain mapping between neutron router and DPN(s) on which vpn-interfaces for router are present
+ container neutron-router-dpns {
+ list router-dpn-list {
+ key router-id;
+ leaf router-id { type yang:uuid;}
+ list dpn-vpninterfaces-list {
+ key dpn-id;
+ leaf dpn-id { type uint64;}
+ leaf-list vpninterfaces-list { type yang:uuid;}
+ }
+ }
+ }
/* container for DHCP Configuration */
container dhcp-config {
}
notification router-associated-to-vpn {
- description "router association to vpn";
- leaf router-id{
- type yang:uuid;
- }
- leaf vpn-id{
- type yang:uuid;
- }
- }
+ description "router association to vpn";
+ leaf router-id{
+ type yang:uuid;
+ }
+ leaf vpn-id{
+ type yang:uuid;
+ }
+ }
- notification router-disassociated-from-vpn {
- description "router disassociation from vpn";
- leaf router-id{
- type yang:uuid;
- }
- leaf vpn-id{
- type yang:uuid;
- }
- }
+ notification router-disassociated-from-vpn {
+ description "router disassociation from vpn";
+ leaf router-id{
+ type yang:uuid;
+ }
+ leaf vpn-id{
+ type yang:uuid;
+ }
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.neutronvpn;
+
+public class NeutronConstants {
+
+ public static final String DEVICE_OWNER_GATEWAY_INF = "network:router_gateway";
+ public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
+ public static final String VNIC_TYPE_NORMAL = "normal";
+ public static final String VIF_TYPE_VHOSTUSER = "vhostuser";
+ public static final String VIF_TYPE_UNBOUND = "unbound";
+ public static final String VIF_TYPE_BINDING_FAILED = "binding_failed";
+ public static final String VIF_TYPE_DISTRIBUTED = "distributed";
+ public static final String VIF_TYPE_OVS = "ovs";
+ public static final String VIF_TYPE_BRIDGE = "bridge";
+ public static final String VIF_TYPE_OTHER = "other";
+ public static final String VIF_TYPE_MACVTAP = "macvtap";
+ public static final String PREFIX_TAP = "tap";
+ public static final String PREFIX_VHOSTUSER = "vhu";
+
+}
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
- .PortsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
- .PortsKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
- .ports.IpMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
- .ports.IpMappingBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
- .ports.IpMappingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
if (LOG.isTraceEnabled()) {
LOG.trace("Neutron Floating IP deleted : key: " + identifier + ", value=" + input);
}
+ IpAddress fixedIp = input.getFixedIpAddress();
+ if (fixedIp != null) {
+ clearFromFloatingIpInfo(input.getRouterId().getValue(), input.getPortId().getValue(), fixedIp
+ .getIpv4Address().getValue());
+ }
}
// populate the floating to fixed ip map upon association/dissociation from fixed ip
LOG.error("Failed to delete ipMapping from FloatingIpInfo DS for fixed Ip {}", fixedIpAddress);
}
}
+
+ protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
+ boolean isLockAcquired = false;
+ InstanceIdentifier.InstanceIdentifierBuilder<FloatingIpInfo> floatingIpInfoIdentifierBuilder =
+ InstanceIdentifier.builder(FloatingIpInfo.class);
+ try {
+ Optional<FloatingIpInfo> optionalFloatingIPInfo = NeutronvpnUtils.read(broker, LogicalDatastoreType
+ .CONFIGURATION, floatingIpInfoIdentifierBuilder.build());
+ if (optionalFloatingIPInfo.isPresent() && optionalFloatingIPInfo.get() != null) {
+ List<RouterPorts> routerPortsList = optionalFloatingIPInfo.get().getRouterPorts();
+ if (routerPortsList != null && !routerPortsList.isEmpty()) {
+ for (RouterPorts routerPorts : routerPortsList) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating
+ .ip.info.router.ports.Ports> portsList = routerPorts.getPorts();
+ if (portsList != null && !portsList.isEmpty()) {
+ String routerName = routerPorts.getRouterId();
+ InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder =
+ floatingIpInfoIdentifierBuilder.child(RouterPorts.class, new RouterPortsKey
+ (routerName));
+ if (portsList.size() == 1) {
+ try {
+ // remove entire routerPorts node
+ isLockAcquired = NeutronvpnUtils.lock(lockManager, routerName);
+ //Fixme :planning to use synchronized blocks for entire NeutronVPN module instead
+ // of using this lockmanager timed API.
+ LOG.debug("removing routerPorts node: {} ", routerName);
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerPortsIdentifierBuilder.build());
+
+ } catch (Exception e) {
+ LOG.error("Failure in deletion of routerPorts node {}", routerName);
+ } finally {
+ if (isLockAcquired) {
+ NeutronvpnUtils.unlock(lockManager, routerName);
+ }
+ }
+ } else {
+ InstanceIdentifier.InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn
+ .opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports
+ .Ports> portsIdentifierBuilder = routerPortsIdentifierBuilder.child(org
+ .opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+ .floating.ip.info.router.ports.Ports.class, new PortsKey(fixedNeutronPortName));
+ try {
+ // remove entire ports node under this routerPorts node
+ isLockAcquired = NeutronvpnUtils.lock(lockManager, fixedNeutronPortName);
+ LOG.debug("removing ports node {} under routerPorts node {}",
+ fixedNeutronPortName, routerName);
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
+ portsIdentifierBuilder.build());
+ } catch (Exception e) {
+ LOG.error("Failure in deletion of routerPorts node {}", routerName);
+ } finally {
+ if (isLockAcquired) {
+ NeutronvpnUtils.unlock(lockManager, routerName);
+ }
+ }
+ }
+ LOG.debug("Deletion from FloatingIpInfo DS successful for fixedIP neutron port {} ",
+ fixedNeutronPortName);
+ } else {
+ LOG.debug("Neutron port {} not associated to any floating IP", fixedNeutronPortName);
+ }
+ }
+ } else {
+ LOG.debug("No router present containing fixed to floating IP association(s)");
+ }
+ } else {
+ LOG.debug("FloatingIPInfo DS empty. Hence, no router present containing fixed to floating IP " +
+ "association(s)");
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to dissociate fixedIP from FloatingIpInfo DS for neutron port {}", fixedNeutronPortName);
+ }
+ }
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
private LockManagerService lockManager;
private NotificationPublishService notificationPublishService;
private NotificationService notificationService;
+ private NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
public NeutronPortChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr,NeutronvpnNatManager nVpnNatMgr,
- NotificationPublishService notiPublishService, NotificationService notiService) {
+ NotificationPublishService notiPublishService, NotificationService notiService,
+ NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener) {
super(Port.class);
broker = db;
nvpnManager = nVpnMgr;
nvpnNatManager = nVpnNatMgr;
notificationPublishService = notiPublishService;
notificationService = notiService;
+ floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
registerListener(db);
}
}
/* check if router interface has been created */
if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
- if (input.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+ if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
handleRouterInterfaceAdded(input);
/* nothing else to do here */
return;
return;
}
if ((input.getDeviceOwner() != null) && (input.getDeviceId() != null)) {
- if (input.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+ if (input.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
handleRouterInterfaceRemoved(input);
/* nothing else to do here */
return;
List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<FixedIps>();
List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<FixedIps>();
+ /* check if VIF type updated as part of port binding */
+ if (NeutronvpnUtils.isPortVifTypeUpdated(original, update)) {
+ updateOfPortInterface(original, update);
+ }
+
/* check if router interface has been updated */
if ((update.getDeviceOwner() != null) && (update.getDeviceId() != null)) {
- if (update.getDeviceOwner().equals(NeutronvpnUtils.DEVICE_OWNER_ROUTER_INF)) {
+ if (update.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF)) {
handleRouterInterfaceAdded(update);
/* nothing else to do here */
return;
}
}
} else {
- LOG.error("Neutron network {} corresponding to router interface port {} for neutron router {} already" +
- " associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
+ LOG.warn("Neutron network {} corresponding to router interface port {} for neutron router {} already " +
+ "associated to VPN {}", infNetworkId.getValue(), routerPort.getUuid().getValue(), routerId
.getValue(), existingVpnId.getValue());
}
}
}
private void handleNeutronPortDeleted(Port port) {
- LOG.debug("Of-port-interface removal");
+ //dissociate fixedIP from floatingIP if associated
+ floatingIpMapListener.dissociatefixedIPFromFloatingIP(port.getUuid().getValue());
LOG.debug("Remove port from subnet");
// remove port from local Subnets DS
Uuid vpnId = removePortFromSubnets(port);
}
// Remove of-port interface for this neutron port
// ELAN interface is also implicitly deleted as part of this operation
+ LOG.debug("Of-port-interface removal", port);
deleteOfPortInterface(port);
Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
}
private Interface createInterface(Port port) {
- String parentRefName = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+
+ String parentRefName = NeutronvpnUtils.getVifPortName(port);
String interfaceName = port.getUuid().getValue();
IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
- ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
- interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class).addAugmentation(IfL2vlan
- .class, ifL2vlanBuilder.build()).addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+ if (parentRefName != null) {
+ ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
+ interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+ }
if (NeutronvpnUtils.isPortSecurityEnabled(port)) {
InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
}
+ interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
+ .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
return interfaceBuilder.build();
}
}
}
+ private Interface updateInterface(Port original, Port update) {
+ String parentRefName = NeutronvpnUtils.getVifPortName(update);
+ String interfaceName = original.getUuid().getValue();
+ InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
+
+ if (parentRefName != null) {
+ ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentRefName);
+ interfaceBuilder.addAugmentation(ParentRefs.class, parentRefsBuilder.build());
+ }
+
+ interfaceBuilder.setName(interfaceName);
+ return interfaceBuilder.build();
+ }
+
+ private String updateOfPortInterface(Port original, Port updated) {
+ Interface inf = updateInterface(original, updated);
+ String infName = inf.getName();
+
+ LOG.debug("Updating OFPort Interface {}", infName);
+ InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(infName);
+ try {
+ Optional<Interface> optionalInf = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+ interfaceIdentifier);
+ if (optionalInf.isPresent()) {
+ MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
+ } else {
+ LOG.error("Interface {} doesn't exist", infName);
+ }
+ } catch (Exception e) {
+ LOG.error("failed to update interface {} due to the exception {} ", infName, e);
+ }
+
+ return infName;
+ }
+
private void createElanInterface(Port port, String name) {
String elanInstanceName = port.getNetworkId().getValue();
List<PhysAddress> physAddresses = new ArrayList<>();
boolean isLockAcquired = false;
String lockName = vpnId.getValue() + subnet.getValue();
String elanInstanceName = sn.getNetworkId().getValue();
- InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
- Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+ InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+ (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+ Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+ elanIdentifierId);
+ //TODO: Cache it in add so can reuse it in update and delete. Best would be to cache in some ElanUtils
long elanTag = elanInstance.get().getElanTag();
Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
if (vpnId.equals(routerId)) {
boolean isLockAcquired = false;
String lockName = vpnId.getValue() + subnet.getValue();
String elanInstanceName = sn.getNetworkId().getValue();
- InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
- Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+ InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+ (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+ Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+ elanIdentifierId);
long elanTag = elanInstance.get().getElanTag();
try {
isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
- checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated, elanTag);
+ checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
+ elanTag);
logger.debug("Subnet updated in Vpn notification sent");
- }catch (Exception e){
- logger.error("Subnet updated in Vpn notification failed",e);
+ } catch (Exception e) {
+ logger.error("Subnet updated in Vpn notification failed", e);
}finally {
if (isLockAcquired) {
NeutronvpnUtils.unlock(lockManager, lockName);
boolean isLockAcquired = false;
String lockName = vpnId.getValue() + subnet.getValue();
String elanInstanceName = sn.getNetworkId().getValue();
- InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
- Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+ InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+ (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+ Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+ elanIdentifierId);
long elanTag = elanInstance.get().getElanTag();
Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
if (vpnId.equals(routerId)) {
}
protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
- List<String> failed = new ArrayList<>();
+
+ List<String> failedNwList = new ArrayList<String>();
+ List<Uuid> passedNwList = new ArrayList<>();
if (!networks.isEmpty()) {
- // store in Data Base
- updateVpnMaps(vpn, null, null, null, networks);
// process corresponding subnets for VPN
for (Uuid nw : networks) {
- Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
- if (net == null) {
- failed.add(nw.getValue());
+ Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+ Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
+ if (network == null) {
+ failedNwList.add(String.format("network %s not found", nw.getValue()));
+ } else if (vpnId != null) {
+ failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
+ vpnId.getValue()));
} else {
List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
- logger.debug("Adding network subnets...");
+ logger.debug("Adding network subnets...{}", networkSubnets);
if (networkSubnets != null) {
for (Uuid subnet : networkSubnets) {
- addSubnetToVpn(vpn, subnet);
+ // check if subnet added as router interface to some router
+ Uuid routerVpnId = NeutronvpnUtils.getVpnForSubnet(broker, subnet);
+ if (routerVpnId == null) {
+ addSubnetToVpn(vpn, subnet);
+ passedNwList.add(nw);
+ } else {
+ failedNwList.add(String.format("subnet %s already added as router interface bound to " +
+ "internal/external VPN %s", subnet.getValue (), routerVpnId.getValue()));
+ }
}
}
- if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
- nvpnNatManager.addExternalNetworkToVpn(net, vpn);
+ if (network.getAugmentation(NetworkL3Extension.class) != null && network.getAugmentation
+ (NetworkL3Extension.class).isExternal()) {
+ nvpnNatManager.addExternalNetworkToVpn(network, vpn);
}
}
}
+ updateVpnMaps(vpn, null, null, null, passedNwList);
}
- return failed;
+ return failedNwList;
}
protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
- List<String> failed = new ArrayList<>();
+
+ List<String> failedNwList = new ArrayList<String>();
+ List<Uuid> passedNwList = new ArrayList<>();
if (networks != null && !networks.isEmpty()) {
- // store in Data Base
- clearFromVpnMaps(vpn, null, networks);
// process corresponding subnets for VPN
for (Uuid nw : networks) {
- Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
- if (net == null) {
- failed.add(nw.getValue());
+ Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+ if (network == null) {
+ failedNwList.add(String.format("network %s not found", nw.getValue()));
} else {
List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
logger.debug("Removing network subnets...");
if (networkSubnets != null) {
for (Uuid subnet : networkSubnets) {
- removeSubnetFromVpn(vpn, subnet);
+ // check if subnet added as router interface to some router
+ Uuid routerVpnId = NeutronvpnUtils.getVpnForSubnet(broker, subnet);
+ if (routerVpnId == null) {
+ removeSubnetFromVpn(vpn, subnet);
+ passedNwList.add(nw);
+ } else {
+ failedNwList.add(String.format("subnet %s added as router interface bound to " +
+ "internal/external VPN %s", subnet.getValue (), routerVpnId.getValue()));
+ }
}
}
- if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
- nvpnNatManager.removeExternalNetworkFromVpn(net);
+ if (network.getAugmentation(NetworkL3Extension.class).isExternal()) {
+ nvpnNatManager.removeExternalNetworkFromVpn(network);
}
}
}
+ clearFromVpnMaps(vpn, null, passedNwList);
}
- return failed;
+ return failedNwList;
}
@Override
if (netIds != null && !netIds.isEmpty()) {
List<String> failed = associateNetworksToVpn(vpnId, netIds);
if (!failed.isEmpty()) {
- returnMsg.append("network(s) not found : ").append(failed);
+ returnMsg.append(failed);
}
}
} else {
Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, vpnId);
if (rtr != null && vpnMap != null) {
+ Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
if (vpnMap.getRouterId() != null) {
returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
.append(vpnMap.getRouterId().getValue());
+ } else if (extVpnId != null) {
+ returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
+ "another VPN ").append(extVpnId.getValue());
} else {
associateRouterToVpn(vpnId, routerId);
}
if (netIds != null && !netIds.isEmpty()) {
List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
if (!failed.isEmpty()) {
- returnMsg.append("netowrk(s) not found : ").append(failed);
+ returnMsg.append(failed);
}
}
} else {
if (routerId != null) {
Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
if (rtr != null) {
- dissociateRouterFromVpn(vpnId, routerId);
+ Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+ if (!routerVpnId.equals(vpnId)) {
+ returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
+ "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as input");
+ } else {
+ dissociateRouterFromVpn(vpnId, routerId);
+ }
} else {
returnMsg.append("router not found : ").append(routerId.getValue());
}
try {
Optional<Ports> ports = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, portidentifier);
if (ports.isPresent() && ports.get().getPort() != null) {
- List<Port> portList = ports.get().getPort();
- for (Port port : portList) {
- result.add(String.format(" %-34s %-22s %-22s %-6s ", port.getUuid().getValue(), port
- .getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
- NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+ for (Port port : ports.get().getPort()) {
+ if (port.getFixedIps() != null && !port.getFixedIps().isEmpty()) {
+ result.add(String.format(" %-34s %-22s %-22s %-6s ", port.getUuid().getValue(), port.
+ getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
+ NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+ }
}
}
} catch (Exception e) {
return help.toString();
}
- private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+ private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
+ Boolean isExternalvpn, Long elanTag)throws InterruptedException {
SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
logger.info("publish notification called");
notificationPublishService.putNotification(builder.build());
}
- private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+ private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
+ Boolean isExternalvpn, Long elanTag) throws InterruptedException {
SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
logger.info("publish notification called");
notificationPublishService.putNotification(builder.build());
}
- private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+ private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
+ Boolean isExternalvpn, Long elanTag) throws InterruptedException {
SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
logger.info("publish notification called");
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
logger.trace("External Network removal detected " +
"for router " + routerId.getValue());
removeExternalNetworkFromRouter(origExtNetId, update);
+ //gateway mac unset handled as part of gateway clear deleting top-level routers node
return;
}
origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
private void addExternalRouter(Router update, DataBroker broker) {
Uuid routerId = update.getUuid();
Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
+ Uuid gatewayPortId = update.getGatewayPortId();
// Create and add Routers object for this Router to the ExtRouters list
// Create a Routers object
- InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
- child(Routers.class, new RoutersKey(routerId.getValue())).build();
+ InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
try {
Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
}
builder.setExternalIps(ext_fixed_ips);
}
+ if (gatewayPortId != null) {
+ logger.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
+ Port port = NeutronvpnUtils.getNeutronPort(broker, gatewayPortId);
+ if (port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
+ builder.setExtGwMacAddress(port.getMacAddress().getValue());
+ }
+ }
List<Uuid> subList = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
builder.setSubnetIds(subList);
Routers routerss = builder.build();
private void removeExternalRouter(Uuid extNetId, Router update, DataBroker broker) {
Uuid routerId = update.getUuid();
- InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
- child(Routers.class, new RoutersKey(routerId.getValue())).build();
+ InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
try {
Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
private void handleExternalFixedIpsForRouter(Router update, DataBroker broker) {
Uuid routerId = update.getUuid();
- InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
- child(Routers.class, new RoutersKey(routerId.getValue())).build();
+ InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
try {
Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
public void handleSubnetsForExternalRouter(Uuid routerId, DataBroker broker) {
- InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
- child(Routers.class, new RoutersKey(routerId.getValue())).build();
+ InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
try {
Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
private void handleSnatSettingChangeForRouter(Router update, DataBroker broker) {
Uuid routerId = update.getUuid();
- InstanceIdentifier<Routers> routersIdentifier = InstanceIdentifier.builder(ExtRouters.class).
- child(Routers.class, new RoutersKey(routerId.getValue())).build();
+ InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
try {
Optional<Routers> optionalRouters = NeutronvpnUtils.read(broker,
private NotificationPublishService notificationPublishService;
private NotificationService notificationService;
private EntityOwnershipService entityOwnershipService;
- private DataBroker broker;
public NeutronvpnProvider(RpcProviderRegistry rpcRegistry,NotificationPublishService notificationPublishService,
NotificationService notificationService) {
subnetListener = new NeutronSubnetChangeListener(dbx, nvManager);
routerListener = new NeutronRouterChangeListener(dbx, nvManager, nvNatManager);
portListener = new NeutronPortChangeListener(dbx, nvManager, nvNatManager,
- notificationPublishService,notificationService);
+ notificationPublishService,notificationService, floatingIpMapListener);
portListener.setLockManager(lockManager);
portListener.setLockManager(lockManager);
floatingIpMapListener = new NeutronFloatingToFixedIpMappingChangeListener(dbx);
@Override
public Subnet getNeutronSubnet(Uuid subnetId) {
- return NeutronvpnUtils.getNeutronSubnet(broker, subnetId);
+ return nvManager.getNeutronSubnet(subnetId);
}
@Override
- public String uuidToTapPortName(Uuid id) {
- return NeutronvpnUtils.uuidToTapPortName(id);
+ public String getVifPortName(Port port) {
+ return NeutronvpnUtils.getVifPortName(port);
}
@Override
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
public class NeutronvpnUtils {
private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
- public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
- public static final String VNIC_TYPE_NORMAL = "normal";
public static ConcurrentHashMap<Uuid, Network> networkMap = new ConcurrentHashMap<Uuid, Network>();
public static ConcurrentHashMap<Uuid, Router> routerMap = new ConcurrentHashMap<Uuid, Router>();
public static ConcurrentHashMap<Uuid, Port> portMap = new ConcurrentHashMap<Uuid, Port>();
return null;
}
- // true for external vpn, false for internal vpn
+ protected static Uuid getVpnForSubnet(DataBroker broker, Uuid subnetId) {
+ InstanceIdentifier<Subnetmap> subnetmapIdentifier = buildSubnetMapIdentifier(subnetId);
+ Optional<Subnetmap> optionalSubnetMap = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapIdentifier);
+ if (optionalSubnetMap.isPresent()) {
+ return optionalSubnetMap.get().getVpnId();
+ }
+ return null;
+ }
+
+ // @param external vpn - true if external vpn being fetched, false for internal vpn
protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
if (ports != null && ports.getPort() != null) {
for (Port port: ports.getPort()) {
if ((port.getDeviceOwner() != null) && (port.getDeviceId() != null)) {
- if (port.getDeviceOwner().equals(DEVICE_OWNER_ROUTER_INF) &&
+ if (port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF) &&
port.getDeviceId().equals(routerId.getValue())) {
for (FixedIps portIp: port.getFixedIps()) {
subnetIdList.add(portIp.getSubnetId());
return subnet;
}
- protected static String uuidToTapPortName(Uuid id) {
- String tapId = id.getValue().substring(0, 11);
- return new StringBuilder().append("tap").append(tapId).toString();
+ protected static String getVifPortName(Port port) {
+ if (port == null || port.getUuid() == null) {
+ logger.warn("Invalid Neutron port {}", port);
+ return null;
+ }
+ String tapId = port.getUuid().getValue().substring(0, 11);
+ String portNamePrefix = getPortNamePrefix(port);
+ if (portNamePrefix != null) {
+ return new StringBuilder().append(portNamePrefix).append(tapId).toString();
+ }
+ logger.debug("Failed to get prefix for port {}", port.getUuid());
+ return null;
+ }
+
+ protected static String getPortNamePrefix(Port port) {
+ PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
+ if (portBinding == null || portBinding.getVifType() == null) {
+ return null;
+ }
+ switch(portBinding.getVifType()) {
+ case NeutronConstants.VIF_TYPE_VHOSTUSER:
+ return NeutronConstants.PREFIX_VHOSTUSER;
+ case NeutronConstants.VIF_TYPE_OVS:
+ case NeutronConstants.VIF_TYPE_DISTRIBUTED:
+ case NeutronConstants.VIF_TYPE_BRIDGE:
+ case NeutronConstants.VIF_TYPE_OTHER:
+ case NeutronConstants.VIF_TYPE_MACVTAP:
+ return NeutronConstants.PREFIX_TAP;
+ case NeutronConstants.VIF_TYPE_UNBOUND:
+ case NeutronConstants.VIF_TYPE_BINDING_FAILED:
+ default:
+ return null;
+ }
+ }
+
+ protected static boolean isPortVifTypeUpdated(Port original, Port updated) {
+ return ((getPortNamePrefix(original) == null) && (getPortNamePrefix(updated) != null));
}
protected static boolean lock(LockManagerService lockManager, String lockName) {
return id;
}
+ static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext
+ .routers.Routers> buildExtRoutersIdentifier(Uuid routerId) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers
+ .Routers> id = InstanceIdentifier.builder(ExtRouters.class).child(org.opendaylight.yang.gen.v1.urn
+ .opendaylight.netvirt.natservice.rev160111.ext.routers.Routers.class,
+ new RoutersKey(routerId.getValue())).build();
+ return id;
+ }
+
static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path) {
static boolean isNetworkTypeVlanOrGre(Network network) {
NetworkProviderExtension npe = network.getAugmentation(NetworkProviderExtension.class);
- if (npe != null) {
- Class<? extends NetworkTypeBase> networkTypeBase = npe.getNetworkType();
- if (networkTypeBase.isAssignableFrom(NetworkTypeVlan.class) || networkTypeBase.isAssignableFrom(NetworkTypeGre.class)) {
- logger.trace("Network is of type {}", networkTypeBase);
+ if (npe != null && npe.getNetworkType() != null) {
+ if (npe.getNetworkType().isAssignableFrom(NetworkTypeVlan.class) ||
+ npe.getNetworkType().isAssignableFrom(NetworkTypeGre.class)) {
+ logger.trace("Network is of type {}", npe.getNetworkType());
return true;
}
}
@Mock
NotificationService notiService;
@Mock
+ NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
+ @Mock
ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
@Mock
WriteTransaction mockWriteTx;
when(mockReadTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).
thenReturn(Futures.immediateCheckedFuture(Optional.of(mockNetwork)));
- neutronPortChangeListener = new NeutronPortChangeListener(dataBroker, nVpnMgr, nVpnNatMgr, notiPublishService, notiService);
+ neutronPortChangeListener = new NeutronPortChangeListener(dataBroker, nVpnMgr, nVpnNatMgr,
+ notiPublishService, notiService, floatingIpMapListener);
}
@Test