Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opendaylight.sfc.util.vpp.SfcVppUtils Maven / Gradle / Ivy
/*
* Copyright (c) 2016, 2017 Cisco Systems, Inc. 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.sfc.util.vpp;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.IpPortLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.LocatorType;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
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.InterfaceBuilder;
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.HexString;
import org.opendaylight.yang.gen.v1.urn.intel.params.xml.ns.yang.sfc.sf.proxy.rev160125.SfLocatorProxyAugmentation;
import org.opendaylight.yang.gen.v1.urn.intel.params.xml.ns.yang.sfc.sf.proxy.rev160125.proxy.ProxyDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.RoutingBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomainsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4Acl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classfier.acl.rev161214.acl.base.attributes.Ip4AclBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.OpaqueIndex;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.PacketHandlingAction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppClassifierBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.VppNodeName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySession;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.classify.table.base.attributes.ClassifySessionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev161214.vpp.classifier.ClassifyTableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.Ethernet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.MdType1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.None;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.NshMdType1Augment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.NshMdType1AugmentBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.Pop;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.Push;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.Swap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.VppNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.VxlanGpe;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.NshEntries;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.NshEntriesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.NshMaps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.NshMapsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.entries.NshEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.entries.NshEntryBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.entries.NshEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.maps.NshMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.maps.NshMapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nsh.rev161214.vpp.nsh.nsh.maps.NshMapKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class SfcVppUtils {
private static final Logger LOG = LoggerFactory.getLogger(SfcVppUtils.class);
private static final InstanceIdentifier NETCONF_TOPOLOGY_IID = InstanceIdentifier
.builder(NetworkTopology.class)
.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))).build();
private static final ConcurrentMap TABLE_INDICE = new ConcurrentHashMap<>();
private static final ConcurrentMap FIRST_TABLE = new ConcurrentHashMap<>();
private static final ConcurrentMap> RSP_TABLE_ID_LIST = new ConcurrentHashMap<>();
private static final ConcurrentMap> VXLAN_GPER_PORT_REF_CNT =
new ConcurrentHashMap<>();
private SfcVppUtils() {
}
public static DataBroker getSffMountpoint(MountPointService mountService, SffName sffName) {
final NodeId nodeId = new NodeId(sffName.getValue());
InstanceIdentifier netconfNodeIid = NETCONF_TOPOLOGY_IID.child(Node.class,
new NodeKey(new NodeId(nodeId)));
Optional optionalObject = mountService.getMountPoint(netconfNodeIid);
if (optionalObject.isPresent()) {
MountPoint mountPoint = optionalObject.get();
if (mountPoint != null) {
Optional optionalDataBroker = mountPoint.getService(DataBroker.class);
if (optionalDataBroker.isPresent()) {
return optionalDataBroker.get();
}
}
}
return null;
}
private static ServiceFunctionDictionary getSfDictionary(SffName sffName, SfName sfName) {
ServiceFunctionDictionary sfDictionary = null;
ServiceFunctionForwarder sff = SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName);
if (sff == null) {
return null;
}
List sfdList = sff.getServiceFunctionDictionary();
for (ServiceFunctionDictionary sfd : sfdList) {
if (sfd.getName().equals(sfName)) {
sfDictionary = sfd;
break;
}
}
return sfDictionary;
}
private static IpAddress getSffDplIp(SffName sffName, SffDataPlaneLocatorName sffDplName) {
IpAddress ip = null;
SffDataPlaneLocator sffDpl = SfcProviderServiceForwarderAPI
.readServiceFunctionForwarderDataPlaneLocator(sffName, sffDplName);
if (sffDpl == null) {
return null;
}
DataPlaneLocator dpl = sffDpl.getDataPlaneLocator();
if (dpl == null) {
return null;
}
LocatorType locatorType = dpl.getLocatorType();
if (locatorType instanceof Ip) {
IpPortLocator ipPortLocator = (IpPortLocator) locatorType;
ip = ipPortLocator.getIp();
}
return ip;
}
public static IpAddress getSffFirstDplIp(SffName sffName) {
ServiceFunctionForwarder sff = SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName);
List sffDataPlaneLocatorList = sff.getSffDataPlaneLocator();
if (sffDataPlaneLocatorList == null || sffDataPlaneLocatorList.isEmpty()) {
return null;
}
SffDataPlaneLocator sffDpl = sffDataPlaneLocatorList.get(0);
if (sffDpl == null) {
return null;
}
DataPlaneLocator dpl = sffDpl.getDataPlaneLocator();
if (dpl == null) {
return null;
}
IpAddress ip = null;
LocatorType locatorType = dpl.getLocatorType();
if (locatorType instanceof Ip) {
IpPortLocator ipPortLocator = (IpPortLocator) locatorType;
ip = ipPortLocator.getIp();
}
return ip;
}
public static IpAddress getSfProxyDplIp(SfLocatorProxyAugmentation augment) {
IpAddress ip = null;
ProxyDataPlaneLocator proxyDpl = augment.getProxyDataPlaneLocator();
if (proxyDpl == null) {
return null;
}
LocatorType locatorType = proxyDpl.getLocatorType();
if (locatorType instanceof Ip) {
IpPortLocator ipPortLocator = (IpPortLocator) locatorType;
ip = ipPortLocator.getIp();
}
return ip;
}
private static IpAddress getSfDplIp(SfName sfName, SfDataPlaneLocatorName sfDplName) {
IpAddress ip = null;
ServiceFunction serviceFunction = SfcProviderServiceFunctionAPI.readServiceFunction(sfName);
if (serviceFunction == null) {
return null;
}
List sdDplList = serviceFunction.getSfDataPlaneLocator();
SfDataPlaneLocator sfDataPlaneLocator = null;
for (SfDataPlaneLocator sfDpl : sdDplList) {
if (sfDpl.getName().equals(sfDplName)) {
sfDataPlaneLocator = sfDpl;
break;
}
}
if (sfDataPlaneLocator == null) {
return null;
}
SfLocatorProxyAugmentation sfDplProxyAug = sfDataPlaneLocator.augmentation(SfLocatorProxyAugmentation.class);
if (sfDplProxyAug != null) {
return SfcVppUtils.getSfProxyDplIp(sfDplProxyAug);
}
LocatorType locatorType = sfDataPlaneLocator.getLocatorType();
if (locatorType instanceof Ip) {
IpPortLocator ipPortLocator = (IpPortLocator) locatorType;
ip = ipPortLocator.getIp();
}
return ip;
}
public static List getSffSfIps(final SffName sffName, final SfName sfName) {
ServiceFunctionDictionary sfDictionary;
SfDataPlaneLocatorName sfDplName;
sfDictionary = getSfDictionary(sffName, sfName);
if (sfDictionary == null) {
return null;
}
sfDplName = sfDictionary.getSffSfDataPlaneLocator().getSfDplName();
SffDataPlaneLocatorName sffDplName;
sffDplName = sfDictionary.getSffSfDataPlaneLocator().getSffDplName();
IpAddress localIp;
localIp = getSffDplIp(sffName, sffDplName);
if (localIp == null) {
return null;
}
List ipList = new ArrayList<>();
ipList.add(localIp);
IpAddress remoteIp;
remoteIp = getSfDplIp(sfName, sfDplName);
if (remoteIp == null) {
return null;
}
ipList.add(remoteIp);
return ipList;
}
private static void addFuturesCallback(final WriteTransaction transaction,
InstanceIdentifier id,
@Nullable DataObject data) {
Futures.addCallback(transaction.submit(), new FutureCallback() {
@Override
public void onSuccess(@Nullable Void result) {
}
@Override
public void onFailure(@NonNull Throwable throwable) {
if (data == null) {
LOG.error("Error deleting {}", id, throwable);
} else {
LOG.error("Error writing to {} with data {}", id, data, throwable);
}
}
}, MoreExecutors.directExecutor());
}
public static void addDummyBridgeDomain(final DataBroker dataBroker, String bridgeDomainName, String vppNode) {
BridgeDomainBuilder bdBuilder = new BridgeDomainBuilder();
bdBuilder.setName(bridgeDomainName);
bdBuilder.setFlood(true);
bdBuilder.setForward(true);
bdBuilder.setLearn(true);
bdBuilder.setUnknownUnicastFlood(true);
bdBuilder.setArpTermination(false);
List bdList = new ArrayList<>();
bdList.add(bdBuilder.build());
BridgeDomainsBuilder bdsBuilder = new BridgeDomainsBuilder();
bdsBuilder.setBridgeDomain(bdList);
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
InstanceIdentifier bridgeDomainsIId = InstanceIdentifier.create(Vpp.class)
.child(BridgeDomains.class);
BridgeDomains bridgeDomains = bdsBuilder.build();
wTx.put(LogicalDatastoreType.CONFIGURATION, bridgeDomainsIId, bridgeDomains);
addFuturesCallback(wTx, bridgeDomainsIId, bridgeDomains);
}
public static void addBridgeDomain(final DataBroker dataBroker, String bridgeDomainName, String vppNode) {
BridgeDomainBuilder bdBuilder = new BridgeDomainBuilder();
bdBuilder.setName(bridgeDomainName);
bdBuilder.setFlood(true);
bdBuilder.setForward(true);
bdBuilder.setLearn(true);
bdBuilder.setUnknownUnicastFlood(true);
bdBuilder.setArpTermination(false);
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
InstanceIdentifier bridgeDomainIId = InstanceIdentifier.create(Vpp.class)
.child(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bridgeDomainName));
BridgeDomain bridgeDomain = bdBuilder.build();
wTx.put(LogicalDatastoreType.CONFIGURATION, bridgeDomainIId, bridgeDomain);
addFuturesCallback(wTx, bridgeDomainIId, bridgeDomain);
}
public static String buildVxlanGpePortKey(final IpAddress remote) {
return "vxlanGpeTun" + "_" + remote.getIpv4Address().getValue();
}
private static int incrementVxlanGpeRefCnt(final String vxlanGpePortKey, final String vppNode) {
final ConcurrentMap nodeMap = VXLAN_GPER_PORT_REF_CNT.computeIfAbsent(
vppNode, key -> new ConcurrentHashMap<>());
final AtomicInteger count = nodeMap.computeIfAbsent(vxlanGpePortKey, key -> new AtomicInteger(0));
return count.incrementAndGet();
}
private static int decrementVxlanGpeRefCnt(final String vxlanGpePortKey, final String vppNode) {
final ConcurrentMap nodeMap = VXLAN_GPER_PORT_REF_CNT.get(vppNode);
if (nodeMap == null) {
return 0;
}
final AtomicInteger count = nodeMap.get(vxlanGpePortKey);
if (count == null) {
return 0;
}
return count.decrementAndGet();
}
private static void addVxlanGpePort(final DataBroker dataBroker, final IpAddress local, final IpAddress remote,
Long vni, String vppNode, String bridgeDomainName) {
String vxlanGpePortKey = buildVxlanGpePortKey(remote);
LOG.info("addVxlanGpePort {} on vpp node {}", vxlanGpePortKey, vppNode);
/* do nothing if vxlanGpePortKey has been added on vppNode */
if (incrementVxlanGpeRefCnt(vxlanGpePortKey, vppNode) > 1) {
return;
}
final VxlanGpeBuilder vxlanGpeBuilder = new VxlanGpeBuilder();
vxlanGpeBuilder.setLocal(local);
vxlanGpeBuilder.setRemote(remote);
vxlanGpeBuilder.setVni(new VxlanGpeVni(vni));
vxlanGpeBuilder.setNextProtocol(VxlanGpeNextProtocol.Nsh);
vxlanGpeBuilder.setEncapVrfId(0L);
vxlanGpeBuilder.setDecapVrfId(0L);
final RoutingBuilder routingBuilder = new RoutingBuilder();
routingBuilder.setIpv4VrfId(0L);
final InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
interfaceBuilder.setName(vxlanGpePortKey);
interfaceBuilder.setType(VxlanGpeTunnel.class);
VppInterfaceAugmentationBuilder vppInterfaceAugmentationBuilder = new VppInterfaceAugmentationBuilder();
vppInterfaceAugmentationBuilder.setVxlanGpe(vxlanGpeBuilder.build());
vppInterfaceAugmentationBuilder.setRouting(routingBuilder.build());
// Set L2 bridgedomain, is it required?
final L2Builder l2Builder = new L2Builder();
final BridgeBasedBuilder bridgeBasedBuilder = new BridgeBasedBuilder();
bridgeBasedBuilder.setBridgedVirtualInterface(false);
bridgeBasedBuilder.setSplitHorizonGroup(Short.valueOf("1"));
bridgeBasedBuilder.setBridgeDomain(bridgeDomainName);
l2Builder.setInterconnection(bridgeBasedBuilder.build());
vppInterfaceAugmentationBuilder.setL2(l2Builder.build());
interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppInterfaceAugmentationBuilder.build());
interfaceBuilder.setEnabled(true);
interfaceBuilder.setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled);
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final KeyedInstanceIdentifier interfaceIid = InstanceIdentifier
.create(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceBuilder.getName()));
Interface anInterface = interfaceBuilder.build();
wTx.put(LogicalDatastoreType.CONFIGURATION, interfaceIid, anInterface);
addFuturesCallback(wTx, interfaceIid, anInterface);
}
public static void removeVxlanGpePort(final DataBroker dataBroker, final IpAddress local, final IpAddress remote,
Long vni, String vppNode) {
String interfaceKey = buildVxlanGpePortKey(remote);
LOG.info("removeVxlanGpePort {} on vpp node {}", interfaceKey, vppNode);
/* do nothing if interfaceKey is still used by other RSPs on vppNode */
if (decrementVxlanGpeRefCnt(interfaceKey, vppNode) > 0) {
return;
}
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final KeyedInstanceIdentifier interfaceIid = InstanceIdentifier
.create(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceKey));
LOG.info("removeVxlanGpePort {} on vpp node {}", interfaceKey, vppNode);
wTx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIid);
addFuturesCallback(wTx, interfaceIid, null);
}
private static String buildNshEntryKey(final Long nsp, final Short nsi) {
return "nsh_entry_" + nsp + "_" + nsi;
}
public static void addDummyNshEntry(final DataBroker dataBroker, final Long nsp, final Short nsi, String vppNode) {
NshEntryBuilder nshEntryBuilder = new NshEntryBuilder();
nshEntryBuilder.setVersion(Short.valueOf("0"));
nshEntryBuilder.setLength(Short.valueOf("6"));
nshEntryBuilder.setNsp(nsp);
nshEntryBuilder.setNsi(nsi);
nshEntryBuilder.setName(buildNshEntryKey(nsp, nsi));
nshEntryBuilder.withKey(new NshEntryKey(nshEntryBuilder.getName()));
nshEntryBuilder.setMdType(MdType1.class);
nshEntryBuilder.setNextProtocol(Ethernet.class);
NshMdType1AugmentBuilder nshMdType1AugmentBuilder = new NshMdType1AugmentBuilder();
Long c1 = 0L;
Long c2 = 0L;
Long c3 = 0L;
Long c4 = 0L;
nshMdType1AugmentBuilder.setC1(c1);
nshMdType1AugmentBuilder.setC2(c2);
nshMdType1AugmentBuilder.setC3(c3);
nshMdType1AugmentBuilder.setC4(c4);
nshEntryBuilder.addAugmentation(NshMdType1Augment.class, nshMdType1AugmentBuilder.build());
NshEntriesBuilder nshEntriesBuilder = new NshEntriesBuilder();
List nshEntryList = new ArrayList<>();
nshEntryList.add(nshEntryBuilder.build());
nshEntriesBuilder.setNshEntry(nshEntryList);
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier nshEntriesIid = InstanceIdentifier.create(VppNsh.class)
.child(NshEntries.class);
wTx.put(LogicalDatastoreType.CONFIGURATION, nshEntriesIid, nshEntriesBuilder.build());
addFuturesCallback(wTx, nshEntriesIid, null);
}
public static void addNshEntry(final DataBroker dataBroker, final Long nsp, final Short nsi, String vppNode) {
NshEntryBuilder nshEntryBuilder = new NshEntryBuilder();
nshEntryBuilder.setVersion(Short.valueOf("0"));
nshEntryBuilder.setLength(Short.valueOf("6"));
nshEntryBuilder.setNsp(nsp);
nshEntryBuilder.setNsi(nsi);
nshEntryBuilder.setName(buildNshEntryKey(nsp, nsi));
nshEntryBuilder.withKey(new NshEntryKey(nshEntryBuilder.getName()));
nshEntryBuilder.setMdType(MdType1.class);
nshEntryBuilder.setNextProtocol(Ethernet.class);
NshMdType1AugmentBuilder nshMdType1AugmentBuilder = new NshMdType1AugmentBuilder();
Long c1 = 0L;
Long c2 = 0L;
Long c3 = 0L;
Long c4 = 0L;
nshMdType1AugmentBuilder.setC1(c1);
nshMdType1AugmentBuilder.setC2(c2);
nshMdType1AugmentBuilder.setC3(c3);
nshMdType1AugmentBuilder.setC4(c4);
nshEntryBuilder.addAugmentation(NshMdType1Augment.class, nshMdType1AugmentBuilder.build());
NshEntry nshEntry = nshEntryBuilder.build();
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier nshEntryIid = InstanceIdentifier.create(VppNsh.class).child(NshEntries.class)
.child(NshEntry.class, nshEntry.key());
wTx.put(LogicalDatastoreType.CONFIGURATION, nshEntryIid, nshEntry);
addFuturesCallback(wTx, nshEntryIid, nshEntry);
}
public static void removeNshEntry(final DataBroker dataBroker, final Long nsp, final Short nsi, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
String nshEntryKey = buildNshEntryKey(nsp, nsi);
final InstanceIdentifier nshEntryIid = InstanceIdentifier.create(VppNsh.class).child(NshEntries.class)
.child(NshEntry.class, new NshEntryKey(nshEntryKey));
LOG.info("removeNshEntry {} on vpp node {}", nshEntryKey, vppNode);
wTx.delete(LogicalDatastoreType.CONFIGURATION, nshEntryIid);
addFuturesCallback(wTx, nshEntryIid, null);
}
private static String buildNshMapKey(final Long nsp, final Short nsi, final Long mappedNsp, final Short mappedNsi) {
return "nsh_map_" + nsp + "_" + nsi + "_to_" + mappedNsp + "_" + mappedNsi;
}
private static NshMapBuilder buildNshMapBuilder(final Long nsp, final Short nsi, final Long mappedNsp,
final Short mappedNsi, String encapIfName) {
NshMapBuilder nshMapBuilder = new NshMapBuilder();
nshMapBuilder.setNsp(nsp);
nshMapBuilder.setNsi(nsi);
nshMapBuilder.setMappedNsp(mappedNsp);
nshMapBuilder.setMappedNsi(mappedNsi);
nshMapBuilder.setName(buildNshMapKey(nsp, nsi, mappedNsp, mappedNsi));
nshMapBuilder.withKey(new NshMapKey(nshMapBuilder.getName()));
if (encapIfName != null) {
nshMapBuilder.setEncapType(VxlanGpe.class);
nshMapBuilder.setEncapIfName(encapIfName);
} else {
nshMapBuilder.setEncapType(None.class);
}
return nshMapBuilder;
}
private static void writeNshMap(final DataBroker dataBroker, NshMap nshMap, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier nshMapIid = InstanceIdentifier.create(VppNsh.class).child(NshMaps.class)
.child(NshMap.class, nshMap.key());
wTx.put(LogicalDatastoreType.CONFIGURATION, nshMapIid, nshMap);
addFuturesCallback(wTx, nshMapIid, nshMap);
}
public static void addDummyNshMap(final DataBroker dataBroker, final Long nsp, final Short nsi,
final Long mappedNsp, final Short mappedNsi, String encapIfName, String vppNode) {
NshMapBuilder nshMapBuilder = buildNshMapBuilder(nsp, nsi, mappedNsp, mappedNsi, encapIfName);
nshMapBuilder.setNshAction(Swap.class);
List nshMapList = new ArrayList<>();
nshMapList.add(nshMapBuilder.build());
NshMapsBuilder nshMapsBuilder = new NshMapsBuilder();
nshMapsBuilder.setNshMap(nshMapList);
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier nshMapsIid = InstanceIdentifier.create(VppNsh.class).child(NshMaps.class);
NshMaps nshMaps = nshMapsBuilder.build();
wTx.put(LogicalDatastoreType.CONFIGURATION, nshMapsIid, nshMaps);
addFuturesCallback(wTx, nshMapsIid, nshMaps);
}
private static void addNshMap(final DataBroker dataBroker, final Long nsp, final Short nsi, final Long mappedNsp,
final Short mappedNsi, String encapIfName, String vppNode) {
NshMapBuilder nshMapBuilder = buildNshMapBuilder(nsp, nsi, mappedNsp, mappedNsi, encapIfName);
nshMapBuilder.setNshAction(Swap.class);
writeNshMap(dataBroker, nshMapBuilder.build(), vppNode);
}
private static void addNshMapWithPush(final DataBroker dataBroker, final Long nsp, final Short nsi,
final Long mappedNsp, final Short mappedNsi, String encapIfName, String vppNode) {
NshMapBuilder nshMapBuilder = buildNshMapBuilder(nsp, nsi, mappedNsp, mappedNsi, encapIfName);
nshMapBuilder.setNshAction(Push.class);
writeNshMap(dataBroker, nshMapBuilder.build(), vppNode);
}
public static void addNshMapWithPop(final DataBroker dataBroker, final Long nsp, final Short nsi,
final Long mappedNsp, final Short mappedNsi, String encapIfName, String vppNode) {
NshMapBuilder nshMapBuilder = buildNshMapBuilder(nsp, nsi, mappedNsp, mappedNsi, encapIfName);
nshMapBuilder.setNshAction(Pop.class);
writeNshMap(dataBroker, nshMapBuilder.build(), vppNode);
}
public static void removeNshMap(final DataBroker dataBroker, final Long nsp, final Short nsi, final Long mappedNsp,
final Short mappedNsi, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
String nshMapKey = buildNshMapKey(nsp, nsi, mappedNsp, mappedNsi);
final InstanceIdentifier nshMapIid = InstanceIdentifier.create(VppNsh.class).child(NshMaps.class)
.child(NshMap.class, new NshMapKey(nshMapKey));
LOG.info("removeNshMap {} on vpp node {}", nshMapKey, vppNode);
wTx.delete(LogicalDatastoreType.CONFIGURATION, nshMapIid);
addFuturesCallback(wTx, nshMapIid, null);
}
public static boolean configureVxlanGpeNsh(final DataBroker dataBroker, final SffName sffName,
String bridgeDomainName, final IpAddress localIp, final IpAddress remoteIp, final Long nsp,
final Short nsi) {
Long vni = 0L; // SFC classifier set it to 0, so always use 0
addVxlanGpePort(dataBroker, localIp, remoteIp, vni, sffName.getValue(), bridgeDomainName); // SFF<->SF
addNshEntry(dataBroker, nsp, nsi, sffName.getValue()); // To Next Hop
addNshMap(dataBroker, nsp, nsi, nsp, nsi, buildVxlanGpePortKey(remoteIp), sffName.getValue());
return true;
}
public static boolean removeVxlanGpeNsh(final DataBroker dataBroker, final SffName sffName, final IpAddress localIp,
final IpAddress remoteIp, final Long nsp, final Short nsi) {
Long vni = 0L; // SFC classifier set it to 0, so always use 0
removeNshMap(dataBroker, nsp, nsi, nsp, nsi, sffName.getValue());
removeNshEntry(dataBroker, nsp, nsi, sffName.getValue()); // To SF
removeVxlanGpePort(dataBroker, localIp, remoteIp, vni, sffName.getValue()); // SFF<->SF
return true;
}
private static Integer getNextTableIndex(String vppNode) {
return TABLE_INDICE.computeIfAbsent(vppNode, key -> Integer.valueOf(0));
}
public static Integer increaseNextTableIndex(String vppNode) {
getNextTableIndex(vppNode);
return TABLE_INDICE.computeIfPresent(vppNode, (key, oldValue) -> Integer.valueOf(oldValue + 1));
}
public static String buildClassifyTableKey(final Integer tableIndex) {
return "table" + tableIndex;
}
private static ClassifyTableBuilder buildClassifyTable(String classifyTableKey, String nextTableKey,
final HexString mask) {
ClassifyTableBuilder classifyTableBuilder = new ClassifyTableBuilder();
classifyTableBuilder.setName(classifyTableKey);
if (nextTableKey != null) {
classifyTableBuilder.setNextTable(nextTableKey);
}
classifyTableBuilder.setClassifierNode(new VppNodeName("l2-input-classify"));
classifyTableBuilder.setNbuckets(2L);
classifyTableBuilder.setMemorySize(104857L);
classifyTableBuilder.setMissNext(new VppNode(PacketHandlingAction.Deny));
classifyTableBuilder.setMask(mask);
return classifyTableBuilder;
}
public static void addClassifyTable(final DataBroker dataBroker, ClassifyTable classifyTable, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
if (FIRST_TABLE.putIfAbsent(vppNode, classifyTable.getName()) == null) {
VppClassifierBuilder vppClassifierBuilder = new VppClassifierBuilder();
List classifyTableList = new ArrayList<>();
classifyTableList.add(classifyTable);
vppClassifierBuilder.setClassifyTable(classifyTableList);
VppClassifier vppClassifier = vppClassifierBuilder.build();
LOG.info("addClassifyTable: {}", vppClassifier);
final InstanceIdentifier vppClassifierIid = InstanceIdentifier.create(VppClassifier.class);
wTx.put(LogicalDatastoreType.CONFIGURATION, vppClassifierIid, vppClassifier);
addFuturesCallback(wTx, vppClassifierIid, vppClassifier);
} else {
final InstanceIdentifier classifyTableIid = InstanceIdentifier.create(VppClassifier.class)
.child(ClassifyTable.class, classifyTable.key());
wTx.put(LogicalDatastoreType.CONFIGURATION, classifyTableIid, classifyTable);
LOG.info("addClassifyTable: {}", classifyTable);
addFuturesCallback(wTx, classifyTableIid, classifyTable);
}
}
private static void removeClassifyTable(final DataBroker dataBroker, final String classifyTableKey,
String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier classifyTableIid = InstanceIdentifier.create(VppClassifier.class)
.child(ClassifyTable.class, new ClassifyTableKey(classifyTableKey));
LOG.info("removeClassifyTable on vpp node {}: table: {}", vppNode, classifyTableKey);
wTx.delete(LogicalDatastoreType.CONFIGURATION, classifyTableIid);
addFuturesCallback(wTx, classifyTableIid, null);
}
private static ClassifySessionBuilder buildClassifySession(final String classifyTableKey, Long nsp, Short nsi,
final HexString match) {
ClassifySessionBuilder classifySessionBuilder = new ClassifySessionBuilder();
classifySessionBuilder.setMatch(match);
classifySessionBuilder.setHitNext(new VppNode(new VppNodeName("nsh-classifier")));
Long opaqueIndexValue = Long.valueOf(nsp.longValue() << 8 | nsi.intValue());
classifySessionBuilder.setOpaqueIndex(new OpaqueIndex(opaqueIndexValue));
return classifySessionBuilder;
}
private static void removeClassifySession(final DataBroker dataBroker, final String classifyTableKey,
HexString match, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier classifySessionIid = InstanceIdentifier.create(VppClassifier.class)
.child(ClassifyTable.class, new ClassifyTableKey(classifyTableKey))
.child(ClassifySession.class, new ClassifySessionKey(match));
LOG.info("removeClassifySession on vpp node {}: table: {}, session: {}", vppNode, classifyTableKey, match);
wTx.delete(LogicalDatastoreType.CONFIGURATION, classifySessionIid);
addFuturesCallback(wTx, classifySessionIid, null);
}
public static void enableIngressAcl(final DataBroker dataBroker, final String interfaceName,
final String classifyTableKey, String vppNode) {
IngressBuilder ingressBuilder = new IngressBuilder();
Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(classifyTableKey).build();
ingressBuilder.setIp4Acl(acl);
Ingress ingress = ingressBuilder.build();
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier ingressIid = InstanceIdentifier.create(Interfaces.class)
.child(Interface.class, new InterfaceKey(interfaceName)).augmentation(VppInterfaceAugmentation.class)
.child(Acl.class).child(Ingress.class);
wTx.put(LogicalDatastoreType.CONFIGURATION, ingressIid, ingress);
addFuturesCallback(wTx, ingressIid, ingress);
}
public static void disableIngressAcl(final DataBroker dataBroker, final String interfaceName,
final String classifyTableKey, String vppNode) {
final DataBroker vppDataBroker = dataBroker;
final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction();
final InstanceIdentifier ingressIid = InstanceIdentifier.create(Interfaces.class)
.child(Interface.class, new InterfaceKey(interfaceName)).augmentation(VppInterfaceAugmentation.class)
.child(Acl.class).child(Ingress.class);
wTx.delete(LogicalDatastoreType.CONFIGURATION, ingressIid);
addFuturesCallback(wTx, ingressIid, null);
}
private static void saveClassifyTableKey(String vppNode, String rsp, String classifyTableKey) {
String rspKey = vppNode + "_" + rsp;
List tblIdList = RSP_TABLE_ID_LIST.computeIfAbsent(rspKey, key -> new ArrayList<>());
synchronized (tblIdList) {
tblIdList.add(classifyTableKey);
}
}
public static String getSavedClassifyTableKey(String vppNode, String rsp, int index) {
String rspKey = vppNode + "_" + rsp;
List tblIdList = RSP_TABLE_ID_LIST.get(rspKey);
if (tblIdList == null) {
return null;
}
synchronized (tblIdList) {
if (tblIdList.size() <= index) {
return null;
}
return tblIdList.get(index);
}
}
public static ClassifyTableBuilder buildVppClassifyTable(SffName sffName, String rsp, HexString mask,
boolean hasNext) {
Integer index = getNextTableIndex(sffName.getValue());
String classifyTableKey = buildClassifyTableKey(index);
saveClassifyTableKey(sffName.getValue(), rsp, classifyTableKey);
String nextTableKey = null;
if (hasNext) {
nextTableKey = buildClassifyTableKey(index + 1);
}
return buildClassifyTable(classifyTableKey, nextTableKey, mask);
}
public static ClassifySessionBuilder buildVppClassifySession(ClassifyTableBuilder classifyTableBuilder,
HexString match, Long nsp, Short nsi) {
return buildClassifySession(classifyTableBuilder.getName(), nsp, nsi, match);
}
public static boolean configureVppClassifier(DataBroker dataBroker, SffName sffName,
List classifyTableList, List classifySessionList) {
for (int i = classifyTableList.size() - 1; i >= 0; i--) {
ClassifyTableBuilder classifyTableBuilder = classifyTableList.get(i);
ClassifySessionBuilder classifySessionBuilder = classifySessionList.get(i);
List sessionList = new ArrayList<>();
sessionList.add(classifySessionBuilder.build());
classifyTableBuilder.setClassifySession(sessionList);
addClassifyTable(dataBroker, classifyTableBuilder.build(), sffName.getValue());
}
return true;
}
public static boolean removeVppClassifier(DataBroker dataBroker, SffName sffName, List tableKeyList,
List matchList) {
for (int i = 0; i < tableKeyList.size(); i++) {
removeClassifySession(dataBroker, tableKeyList.get(i), matchList.get(i), sffName.getValue());
removeClassifyTable(dataBroker, tableKeyList.get(i), sffName.getValue());
}
return true;
}
public static boolean configureClassifierVxlanGpeNsh(final DataBroker dataBroker, final SffName sffName,
String bridgeDomainName, final IpAddress localIp, final IpAddress remoteIp, final Long nsp,
final Short nsi) {
Long vni = 0L; // SFC classifier set it to 0, so always use 0
addVxlanGpePort(dataBroker, localIp, remoteIp, vni, sffName.getValue(), bridgeDomainName); // SFF<->SF
addNshEntry(dataBroker, nsp, nsi, sffName.getValue()); // To Next Hop
addNshMapWithPush(dataBroker, nsp, nsi, nsp, nsi, buildVxlanGpePortKey(remoteIp), sffName.getValue());
return true;
}
public static boolean removeClassifierVxlanGpeNsh(final DataBroker dataBroker, final SffName sffName,
String bridgeDomainName, final IpAddress localIp, final IpAddress remoteIp, final Long nsp,
final Short nsi) {
Long vni = 0L; // SFC classifier set it to 0, so always use 0
removeNshMap(dataBroker, nsp, nsi, nsp, nsi, sffName.getValue());
removeNshEntry(dataBroker, nsp, nsi, sffName.getValue()); // To SFF
removeVxlanGpePort(dataBroker, localIp, remoteIp, vni, sffName.getValue()); // Classifier<->SFF
return true;
}
}