From 4110307879cad1aa54943aedbf937b2f21575b4c Mon Sep 17 00:00:00 2001 From: Suraj Ranjan Date: Fri, 1 Apr 2016 17:48:39 +0530 Subject: [PATCH] SubnetRoute enhancements to VPN Service models This commit deals with changes required to construct internal data structures to provide SubnetRoute facility in VPN Service. With SubnetRoute facility all packets intended for a cloud coming from a DC gateway will be punted to one DPN that will be considered as designated DPN. Change-Id: Ie33ad0c62bf686496460b94bd4de6f9e28e1ae5b Signed-off-by: Suraj Ranjan Co-Authored-By: Vivekanandan Narasimhan Co-Authored-By: Karan Raj Singh Co-Authored-By: Achuth Maniyedath --- .../IBgpManager.java | 18 +- .../opendaylight/bgpmanager/BgpManager.java | 12 +- .../vpnservice/fibmanager/FibManager.java | 208 +++-- .../src/main/yang/neutronvpn.yang | 89 +++ .../src/main/config/default-config.xml | 10 +- .../neutronvpn/NeutronPortChangeListener.java | 72 +- .../neutronvpn/NeutronvpnManager.java | 149 +++- .../neutronvpn/NeutronvpnProvider.java | 17 +- .../impl/rev150325/NeutronvpnImplModule.java | 5 +- .../src/main/yang/neutronvpn-impl.yang | 17 + .../src/main/yang/odl-l3vpn.yang | 109 +++ vpnmanager/vpnmanager-impl/pom.xml | 10 + .../InterfaceStateChangeListener.java | 4 + .../vpnservice/SubnetOpDpnManager.java | 225 ++++++ .../SubnetRoutePacketInHandler.java | 318 ++++++++ .../opendaylight/vpnservice/VpnConstants.java | 7 + .../vpnservice/VpnInterfaceManager.java | 24 +- .../opendaylight/vpnservice/VpnManager.java | 2 + .../vpnservice/VpnSubnetRouteHandler.java | 730 ++++++++++++++++++ .../org/opendaylight/vpnservice/VpnUtil.java | 98 ++- .../vpnservice/VpnserviceProvider.java | 15 +- 21 files changed, 2035 insertions(+), 104 deletions(-) create mode 100644 vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/SubnetOpDpnManager.java create mode 100644 vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/SubnetRoutePacketInHandler.java create mode 100644 vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnSubnetRouteHandler.java diff --git a/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java b/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java index 3ffa33f2..d0fabf4a 100644 --- a/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java +++ b/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * Copyright (c) 2015 - 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, @@ -49,6 +49,22 @@ public interface IBgpManager { */ public void setQbgpLog(String fileName, String logLevel) throws Exception; + /** + * @param rd + * @param prefix + * @param nextHop + * @param vpnLabel + */ + public void advertisePrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception; + + /** + * + * @param rd + * @param prefix + */ + public void withdrawPrefix(String rd, String prefix) throws Exception; + + public String getDCGwIP(); } diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java index 909b82a8..6e9a1a5b 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * Copyright (c) 2015 - 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, @@ -139,6 +139,16 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana bcm.delPrefix(rd, prefix); } + @Override + public void advertisePrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception { + bcm.addPrefix(rd, prefix, nextHop, vpnLabel); + } + + @Override + public void withdrawPrefix(String rd, String prefix) throws Exception { + bcm.delPrefix(rd, prefix); + } + public void setQbgpLog(String fileName, String debugLevel) throws Exception { bcm.addLogging(fileName, debugLevel); } diff --git a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java index 128444c6..b9906ada 100644 --- a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java +++ b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java @@ -17,6 +17,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -43,6 +44,9 @@ import org.opendaylight.vpnservice.mdsalutil.NwConstants; import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.RdToElanOp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnToExtraroute; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIdsKey; @@ -182,6 +186,17 @@ public class FibManager extends AbstractDataChangeListener implements Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId() + "has null vpnId!"); Collection vpnToDpnList = vpnInstance.getVpnToDpnList(); + Long vpnId = vpnInstance.getVpnId(); + RdToElanOpEntry rdToElanOpEntry = getRdToElanOpEntry(broker, vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry!=null) { + if (vpnToDpnList!=null) { + for (VpnToDpnList curDpn : vpnToDpnList) { + installSubnetRouteInFib(curDpn.getDpnId(), rdToElanOpEntry, vpnId.longValue(), vrfEntry); + } + } + return; + } BigInteger localDpnId = createLocalFibEntry(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); if (vpnToDpnList != null) { @@ -194,6 +209,74 @@ public class FibManager extends AbstractDataChangeListener implements } } + private void installSubnetRouteInFib(BigInteger dpnId, RdToElanOpEntry rdToElanOpEntry, + long vpnId, VrfEntry vrfEntry){ + makeSubnetRouteFlow(dpnId); + List instructions = new ArrayList(); + List actionsInfos = new ArrayList(); + Long elanTag = rdToElanOpEntry.getElanTag(); + instructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] { (BigInteger.valueOf(elanTag)).shiftLeft(24), MetaDataUtil.METADATA_MASK_SERVICE })); + instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.L3_SUBNET_ROUTE_TABLE })); + makeConnectedRoute(dpnId,vpnId,vrfEntry,rdToElanOpEntry.getRd(), + instructions,NwConstants.ADD_FLOW); + makeLFibTableEntry(dpnId,vrfEntry.getLabel(),instructions, + vrfEntry.getNextHopAddress(),NwConstants.ADD_FLOW); + // TODO makeTunnelTableEntry(); + } + + private RdToElanOpEntry getRdToElanOpEntry(DataBroker broker, String rd, String subnetIp) { + InstanceIdentifier id = getRdToElanOpEntryDataPath(rd,subnetIp); + Optional sn = read(broker, LogicalDatastoreType.OPERATIONAL, id); + if(sn.isPresent()) { + return sn.get(); + } + return null; + } + + private InstanceIdentifier getRdToElanOpEntryDataPath(String rd, String subnetIp) { + return InstanceIdentifier.builder(RdToElanOp.class).child(RdToElanOpEntry.class, + new RdToElanOpEntryKey(rd,subnetIp)).build(); + } + private Optional read(DataBroker broker, LogicalDatastoreType datastoreType, + InstanceIdentifier path) { + + ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); + + Optional result = Optional.absent(); + try { + result = tx.read(datastoreType, path).get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return result; + } + + private void makeSubnetRouteFlow(BigInteger dpnId) { + //Ask Vivek cookie + final BigInteger COOKIE_TABLE_MISS = new BigInteger("8000004", 16); + List actionsInfos = new ArrayList(); + List instructions = new ArrayList(); + actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[]{})); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); + List matches = new ArrayList(); + String flowRef = getFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, NwConstants.TABLE_MISS_FLOW); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, flowRef, + NwConstants.TABLE_MISS_PRIORITY, "Subnet Route Table Miss", 0, 0, COOKIE_TABLE_MISS, matches, instructions); + + LOG.debug("Invoking MDSAL to install Table Miss Entries"); + mdsalManager.syncInstallFlow(flowEntity,1); + } + + private Collection getDpnsForVpn(VpnInstanceOpDataEntry vpnInstance) { + Collection dpns = new HashSet<>(); + for(VpnToDpnList dpn : vpnInstance.getVpnToDpnList()) { + dpns.add(dpn.getDpnId()); + } + + return dpns; + } + public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) { BigInteger localDpnId = BigInteger.ZERO; Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix()); @@ -209,18 +292,26 @@ public class FibManager extends AbstractDataChangeListener implements } if(localNextHopInfo != null) { - localDpnId = localNextHopInfo.getDpnId(); - long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP); - List actionInfos = new ArrayList(); + localDpnId = localNextHopInfo.getDpnId(); + long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP); - actionInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)})); + List actionsInfos = new ArrayList(); + List instructions = new ArrayList(); + + actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)})); + instructions.add(new InstructionInfo(InstructionType.write_actions,actionsInfos)); + makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW); - makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW); - makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), groupId, vrfEntry.getNextHopAddress(), NwConstants.ADD_FLOW); + actionsInfos=new ArrayList();; + instructions=new ArrayList(); + actionsInfos.add(new ActionInfo(ActionType.pop_mpls, new String[]{})); + actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId) })); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); + makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), instructions, vrfEntry.getNextHopAddress(), NwConstants.ADD_FLOW); - LOG.debug("Installing tunnel table entry on dpn {} for interface {} with label {}", - localDpnId, localNextHopInfo.getVpnInterfaceName(), vrfEntry.getLabel()); - makeTunnelTableEntry(localDpnId, vrfEntry.getLabel(), groupId); + LOG.debug("Installing tunnel table entry on dpn {} for interface {} with label {}", + localDpnId, localNextHopInfo.getVpnInterfaceName(), vrfEntry.getLabel()); + makeTunnelTableEntry(localDpnId, vrfEntry.getLabel(), groupId); } return localDpnId; @@ -293,7 +384,7 @@ public class FibManager extends AbstractDataChangeListener implements Prefixes prefix = getPrefixToInterface(vpnId, isExtraRoute ? localNextHopIP : vrfEntry.getDestPrefix()); makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */, NwConstants.DEL_FLOW); - makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), 0 /* invalid */, + makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), null /* invalid */, vrfEntry.getNextHopAddress(), NwConstants.DEL_FLOW); removeTunnelTableEntry(localDpnId, vrfEntry.getLabel()); deleteLocalAdjacency(localDpnId, vpnId, localNextHopIP); @@ -377,6 +468,8 @@ public class FibManager extends AbstractDataChangeListener implements tunnelId})); } actionInfos.addAll(nextHopManager.getEgressActionsForInterface(tunnelInterface)); + List instructions= new ArrayList(); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionInfos)); /* List actionInfos = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry); if(actionInfos == null) { @@ -404,35 +497,34 @@ public class FibManager extends AbstractDataChangeListener implements MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID })); } **/ - makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW); - LOG.debug( - "Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId); - } - - private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) { - InstanceIdentifier id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); - if (dpnInVpn.isPresent()) { - List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); - org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces - currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build(); - - if (vpnInterfaces.remove(currVpnInterface)) { - if (vpnInterfaces.isEmpty()) { + makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW); + LOG.debug("Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId); + } + + private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) { + InstanceIdentifier id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId); + Optional dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + if (dpnInVpn.isPresent()) { + List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces + currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build(); + + if (vpnInterfaces.remove(currVpnInterface)) { + if (vpnInterfaces.isEmpty()) { LOG.trace("Last vpn interface {} on dpn {} for vpn {}. Clean up fib in dpn", intfName, dpnId, rd); FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id); cleanUpDpnForVpn(dpnId, vpnId, rd); - } else { + } else { LOG.trace("Delete vpn interface {} from dpn {} to vpn {} list.", intfName, dpnId, rd); - FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data - .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName))); - } - } - } - } + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data + .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName))); + } + } + } + } private void cleanUpOpDataForFib(Long vpnId, String rd, final VrfEntry vrfEntry) { /* Get interface info from prefix to interface mapping; @@ -487,6 +579,24 @@ public class FibManager extends AbstractDataChangeListener implements VpnInstanceOpDataEntry vpnInstance = getVpnInstance(vrfTableKey.getRouteDistinguisher()); Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available!"); Collection vpnToDpnList = vpnInstance.getVpnToDpnList(); + RdToElanOpEntry rdToElanOpEntry= getRdToElanOpEntry(broker,vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry != null) { + if (vpnToDpnList!=null) { + for(VpnToDpnList curDpn : vpnToDpnList) { + makeConnectedRoute(curDpn.getDpnId(),vpnInstance.getVpnId(),vrfEntry,vrfTableKey + .getRouteDistinguisher(), null,NwConstants.DEL_FLOW); + makeLFibTableEntry(curDpn.getDpnId(),vrfEntry.getLabel(),null, + vrfEntry.getNextHopAddress(),NwConstants.DEL_FLOW); + // TODO DeleteTunnelTableEntry(); + } + } + //Delete rd-to-elan-op-entry + InstanceIdentifier id = getRdToElanOpEntryDataPath(vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,id); + return; + } BigInteger localDpnId = deleteLocalFibEntry(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); if (vpnToDpnList != null) { @@ -535,8 +645,7 @@ public class FibManager extends AbstractDataChangeListener implements } private void makeConnectedRoute(BigInteger dpId, long vpnId, VrfEntry vrfEntry, String rd, - List actionInfos, int addOrRemove) { - LOG.trace("makeConnectedRoute: vrfEntry {}",vrfEntry); + List instructions, int addOrRemove) { LOG.trace("makeConnectedRoute: vrfEntry {}",vrfEntry); String values[] = vrfEntry.getDestPrefix().split("/"); String ipAddress = values[0]; int prefixLength = (values.length == 1) ? 0 : Integer.parseInt(values[1]); @@ -558,13 +667,8 @@ public class FibManager extends AbstractDataChangeListener implements new long[] { 0x0800L })); if(prefixLength != 0) { - matches.add(new MatchInfo(MatchFieldType.ipv4_dst, new long[] { - getIpAddress(destPrefix.getAddress()), prefixLength })); - } - - List instructions = new ArrayList(); - if(addOrRemove == NwConstants.ADD_FLOW) { - instructions.add(new InstructionInfo(InstructionType.write_actions, actionInfos)); + matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] { + destPrefix.getHostAddress(), Integer.toString(prefixLength)})); } String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, rd, destPrefix); @@ -588,19 +692,13 @@ public class FibManager extends AbstractDataChangeListener implements } } - private void makeLFibTableEntry(BigInteger dpId, long label, long groupId, + private void makeLFibTableEntry(BigInteger dpId, long label, List instructions, String nextHop, int addOrRemove) { List matches = new ArrayList(); matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { 0x8847L })); matches.add(new MatchInfo(MatchFieldType.mpls_label, new String[]{Long.toString(label)})); - List instructions = new ArrayList(); - List actionsInfos = new ArrayList(); - actionsInfos.add(new ActionInfo(ActionType.pop_mpls, new String[]{})); - actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId) })); - instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); - // Install the flow entry in L3_LFIB_TABLE String flowRef = getFlowRef(dpId, NwConstants.L3_LFIB_TABLE, label, nextHop); @@ -620,7 +718,7 @@ public class FibManager extends AbstractDataChangeListener implements } else { mdsalManager.syncRemoveFlow(flowEntity, 1); } - LOG.debug("LFIB Entry for dpID {} : label : {} group {} modified successfully {}",dpId, label, groupId ); + LOG.debug("LFIB Entry for dpID {} : label : {} instructions {} modified successfully {}",dpId, label, instructions ); } private void deleteLocalAdjacency(final BigInteger dpId, final long vpnId, final String ipAddress) { @@ -640,6 +738,12 @@ public class FibManager extends AbstractDataChangeListener implements Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); if (vrfTable.isPresent()) { for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + RdToElanOpEntry rdToElanOpEntry = getRdToElanOpEntry(broker, rd, + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry!= null) { + installSubnetRouteInFib(dpnId, rdToElanOpEntry, vpnId, vrfEntry); + continue; + } // Passing null as we don't know the dpn // to which prefix is attached at this point createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); diff --git a/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang b/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang index f128c5bc..92c084a7 100644 --- a/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang +++ b/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang @@ -301,4 +301,93 @@ module neutronvpn { } } + notification subnet-added-to-vpn{ + description "new subnet added to vpn"; + leaf subnet-id { + type yang:uuid; + } + leaf subnet-ip { + type string; + } + leaf vpn-name { + type string; + } + leaf external-vpn { + type boolean; + } + leaf elan-tag { + type uint32; + } + } + + notification subnet-deleted-from-vpn{ + description "subnet deleted from vpn"; + leaf subnet-id { + type yang:uuid; + } + leaf subnet-ip { + type string; + } + leaf vpn-name { + type string; + } + leaf external-vpn { + type boolean; + } + leaf elan-tag { + type uint32; + } + } + + notification subnet-updated-in-vpn{ + description "subnet updated in vpn"; + leaf subnet-id { + type yang:uuid; + } + leaf subnet-ip { + type string; + } + leaf vpn-name { + type string; + } + leaf external-vpn { + type boolean; + } + leaf elan-tag { + type uint32; + } + } + + notification port-added-to-subnet{ + description "new port added to subnet"; + leaf subnet-id{ + type yang:uuid; + } + leaf subnet-ip{ + type string; + } + leaf port-id{ + type yang:uuid; + } + leaf elan-tag { + type uint32; + } + } + + notification port-removed-from-subnet{ + description "port removed from subnet"; + leaf subnet-id{ + type yang:uuid; + } + leaf subnet-ip{ + type string; + } + leaf port-id{ + type yang:uuid; + } + leaf elan-tag { + type uint32; + } + } + } \ No newline at end of file diff --git a/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml b/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml index 86f904e5..e8c777e8 100644 --- a/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml +++ b/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml @@ -1,6 +1,6 @@