Add implementation for L3 overlay renderer 93/53693/18
authorShakib Ahmed <sheikahm@cisco.com>
Thu, 27 Apr 2017 11:47:08 +0000 (04:47 -0700)
committerShakib Ahmed <sheikahm@cisco.com>
Mon, 15 May 2017 02:07:03 +0000 (19:07 -0700)
Add implementation for rendering L3 LISP overlay. For provisioning
proper L3 overlay network with LISP, we need to enable LISP in VPP
and put configs for map server and map resolver along with other
related configurations.

This patch implement all these functionalities.

Change-Id: Iefecd813af9eab243259436531c126a6ded364da
Signed-off-by: Shakib Ahmed <sheikahm@cisco.com>
20 files changed:
renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/LoopbackCommand.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigUtil.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispState.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviHostSpecificInfo.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviManager.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispConfigCommandFailedException.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispHelperArgumentException.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispNotFoundException.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/mappers/NeutronTenantToVniMapper.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/LispUtil.java [new file with mode: 0644]
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/DtoFactory.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java

index 2d8086b84980d781d3088adc42db0878a4ade365..6b50c3e5a72e4d0cd3950a393bca668a2c5985e6 100644 (file)
@@ -23,6 +23,8 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.bvi.BviManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.GbpSubnetListener;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener;
@@ -119,6 +121,10 @@ public class VppRenderer implements AutoCloseable, BindingAwareProvider {
         if (interfaceManager != null) {
             interfaceManager.close();
         }
+
+        if (vppGbpSubnetListener != null) {
+            vppGbpSubnetListener.close();
+        }
         unregisterFromRendererManager();
     }
 
@@ -136,11 +142,15 @@ public class VppRenderer implements AutoCloseable, BindingAwareProvider {
         interfaceManager = new InterfaceManager(mountDataProvider, dataBroker);
         AclManager aclManager = new AclManager(mountDataProvider);
         NatManager natManager = new NatManager(dataBroker, mountDataProvider);
+        LispStateManager lispStateManager = new LispStateManager(mountDataProvider);
+        BviManager bviManager = new BviManager(mountDataProvider);
         dtoEventBus.register(interfaceManager);
+        dtoEventBus.register(bviManager);
         RoutingManager routingManager = new RoutingManager(dataBroker, mountDataProvider);
         bdManager = new BridgeDomainManagerImpl(dataBroker);
         ForwardingManager fwManager =
-                new ForwardingManager(interfaceManager, aclManager, natManager, routingManager, bdManager, dataBroker);
+                new ForwardingManager(interfaceManager, aclManager, natManager, routingManager, bdManager,
+                        lispStateManager, bviManager,dataBroker);
         VppRendererPolicyManager vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, aclManager, dataBroker);
         dtoEventBus.register(vppRendererPolicyManager);
 
index 69172a5e64ead6d5da36015147c3e6c02d5c57b4..b9f5a679bb5360880676972ae11e80f294b60c78 100644 (file)
@@ -147,7 +147,7 @@ public class LoopbackCommand extends AbstractInterfaceCommand {
         private IpPrefix ipPrefix;
         private Long vrfId;
 
-        String getInterfaceName() {
+        public String getInterfaceName() {
             return interfaceName;
         }
 
@@ -174,11 +174,11 @@ public class LoopbackCommand extends AbstractInterfaceCommand {
             return this;
         }
 
-        String getBridgeDomain() {
+        public String getBridgeDomain() {
             return bridgeDomain;
         }
 
-        LoopbackCommandBuilder setBridgeDomain(String bridgeDomain) {
+        public LoopbackCommandBuilder setBridgeDomain(String bridgeDomain) {
             this.bridgeDomain = bridgeDomain;
             return this;
         }
@@ -196,7 +196,7 @@ public class LoopbackCommand extends AbstractInterfaceCommand {
             return enabled;
         }
 
-        LoopbackCommandBuilder setEnabled(boolean enabled) {
+        public LoopbackCommandBuilder setEnabled(boolean enabled) {
             this.enabled = enabled;
             return this;
         }
index 1c3f6fabe457dba45a05030bce0bcbae7b4ed059..221b3508b10a2334b6e742692df332581431c2df 100644 (file)
@@ -29,7 +29,7 @@ public class ConfigUtil {
 
     private IpAddress odlTenantIp;
     private boolean lispOverlayEnabled = DEFAULT_LISP_OVERLAY_ENABLED;
-    private boolean lispMapRegisterEnbled = DEFAULT_LISP_MAPREGISTER_ENABLED;
+    private boolean lispMapRegisterEnabled = DEFAULT_LISP_MAPREGISTER_ENABLED;
     private boolean l3FlatEnabled = DEFAULT_L3_FLAT_ENABLED;
 
     static final String ODL_TENANT_IP = "odl.ip.tenant";
@@ -75,11 +75,11 @@ public class ConfigUtil {
 
     void configureMapRegister(String configStr) {
         if (configStr == null) {
-            lispMapRegisterEnbled = DEFAULT_LISP_MAPREGISTER_ENABLED;
+            lispMapRegisterEnabled = DEFAULT_LISP_MAPREGISTER_ENABLED;
             LOG.debug(CONFIGURATION_VARIABLE_MESSAGE, LISP_MAPREGISTER_ENABLED, DEFAULT_LISP_MAPREGISTER_ENABLED);
             return;
         }
-        lispMapRegisterEnbled = configStr.trim().equalsIgnoreCase(DEFAULT_TRUE_STRING_VALUE);
+        lispMapRegisterEnabled = configStr.trim().equalsIgnoreCase(DEFAULT_TRUE_STRING_VALUE);
     }
 
     void configL3FlatEnabled(String configStr) {
@@ -103,8 +103,8 @@ public class ConfigUtil {
         return lispOverlayEnabled;
     }
 
-    public boolean isLispMapRegisterEnbled() {
-        return lispMapRegisterEnbled;
+    public boolean isLispMapRegisterEnabled() {
+        return lispMapRegisterEnabled;
     }
 
     public boolean isL3FlatEnabled() {
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispState.java
new file mode 100644 (file)
index 0000000..9b46a75
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by Shakib Ahmed on 3/29/17.
+ */
+public class LispState {
+    private String hostName;
+    private boolean lispEnabled;
+    private HashMap<String, String> locIntfToLocSetNameMapping;
+    private Set<IpAddress> mapServerIpAddressSet;
+    private Set<IpAddress> mapResolverIpAddressSet;
+    private Set<Long> vniSet;
+    private boolean mapRegisteredEnabled;
+    private HashMap<Eid, String> eidToMappingIdMapper;
+
+    public LispState(String hostName) {
+        this.hostName = hostName;
+        lispEnabled = false;
+        locIntfToLocSetNameMapping = new HashMap<>();
+        mapServerIpAddressSet = new HashSet<>();
+        mapResolverIpAddressSet = new HashSet<>();
+        mapRegisteredEnabled = false;
+        vniSet = new HashSet<>();
+        eidToMappingIdMapper = new HashMap<>();
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public boolean isLispEnabled() {
+        return lispEnabled;
+    }
+
+    public void setLispEnabled(boolean lispEnabled) {
+        this.lispEnabled = lispEnabled;
+    }
+
+    public String getLocIntfToLocSetNameMapping(String locatorIntf) {
+        return locIntfToLocSetNameMapping.get(locatorIntf);
+    }
+
+    public void setLocIntfToLocSetNameMapping(String locIntfName, String locSetName) {
+        locIntfToLocSetNameMapping.put(locIntfName, locSetName);
+    }
+
+    public Set<Map.Entry<String, String>> getLocatorSetEntry() {
+        return locIntfToLocSetNameMapping.entrySet();
+    }
+
+    public int getLocatorCount() {
+        return locIntfToLocSetNameMapping.size();
+    }
+
+    public boolean mapServerSetContains(IpAddress ip) {
+        return mapServerIpAddressSet.contains(ip);
+    }
+
+    public void addInMapServerSet(IpAddress ip) {
+        mapServerIpAddressSet.add(ip);
+    }
+
+    public boolean mapResolverSetContains(IpAddress ip) {
+        return mapResolverIpAddressSet.contains(ip);
+    }
+
+    public void addInMapResolverSet(IpAddress ip) {
+        mapResolverIpAddressSet.add(ip);
+    }
+
+    public boolean vniSetContains(long vni) {
+        return vniSet.contains(vni);
+    }
+
+    public void addInVniSet(long vni) {
+        vniSet.add(vni);
+    }
+
+    public boolean isMapRegisteredEnabled() {
+        return mapRegisteredEnabled;
+    }
+
+    public void setMapRegisteredEnabled(boolean mapRegisteredEnabled) {
+        this.mapRegisteredEnabled = mapRegisteredEnabled;
+    }
+
+    public boolean eidSetContains(Eid eid) {
+        return eidToMappingIdMapper.containsKey(eid);
+    }
+
+    public void addInEidSet(Eid eid, String mappingId) {
+        eidToMappingIdMapper.put(eid, mappingId);
+    }
+
+    public int eidCount() {
+        return eidToMappingIdMapper.size();
+    }
+
+    public void deleteEid(Eid eid) {
+        eidToMappingIdMapper.remove(eid);
+    }
+
+    public String getEidMapping(Eid eid) {
+        return eidToMappingIdMapper.get(eid);
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java
new file mode 100644 (file)
index 0000000..d227695
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.AbstractLispCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by Shakib Ahmed on 4/18/17.
+ */
+public class LispStateCommandExecutor {
+    private static final Logger LOG = LoggerFactory.getLogger(LispStateCommandExecutor.class);
+
+    public static <T extends DataObject> boolean executePutCommand(DataBroker vppDataBroker,
+                                                                   AbstractLispCommand<T> lispStateCommand) {
+        lispStateCommand.setOptions(General.Operations.PUT);
+        return executeCommand(vppDataBroker, lispStateCommand);
+    }
+
+    public static <T extends DataObject> boolean executeDeleteCommand(DataBroker vppDataBroker,
+                                                                      AbstractLispCommand<T> lispStateCommand) {
+        lispStateCommand.setOptions(General.Operations.DELETE);
+        return executeCommand(vppDataBroker, lispStateCommand);
+    }
+
+    public static <T extends DataObject> boolean executeCommand(DataBroker vppDataBroker,
+                                                                AbstractLispCommand<T> lispStateCommand) {
+        final boolean transactionState = GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker, lispStateCommand,
+                GbpNetconfTransaction.RETRY_COUNT);
+
+        if (transactionState) {
+            LOG.trace("Successfully executed command: ", lispStateCommand);
+        } else {
+            LOG.debug("Failed to execute command: ", lispStateCommand);
+        }
+
+        return transactionState;
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java
new file mode 100644 (file)
index 0000000..95e11c3
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.AbstractLispCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.LispCommandWrapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.Lisp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.LocalMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.eid.table.grouping.eid.table.VniTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.lisp.feature.data.grouping.LispFeatureData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.locator.sets.grouping.locator.sets.LocatorSet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.register.grouping.MapRegister;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.resolvers.grouping.map.resolvers.MapResolver;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.servers.grouping.map.servers.MapServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.util.HashMap;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by Shakib Ahmed on 3/29/17.
+ */
+public class LispStateManager {
+    private static final Logger LOG = LoggerFactory.getLogger(LispStateManager.class);
+
+    private HashMap<String, LispState> lispStateMapper;
+    private MountedDataBrokerProvider mountedDataBrokerProvider;
+    private ConfigManagerHelper lispStateHelper;
+
+    private NeutronTenantToVniMapper neutronTenantToVniMapper;
+
+    private static final short DEFAULT_PRIORITY = 1;
+    private static final short DEFAULT_WEIGHT = 1;
+    public static final String DEFAULT_XTR_KEY = "admin";
+    public static final String DEFAULT_LOCATOR_SET_NAME_PREFIX = "LS";
+    public static final String DEFAULT_MAPPINGRECORD_NAME_PREFIX = "MR";
+
+    public LispStateManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
+        Preconditions.checkNotNull(mountedDataBrokerProvider,
+                "MountedDataBrokerProvider found to be null!");
+        lispStateMapper = new HashMap<>();
+        this.mountedDataBrokerProvider= mountedDataBrokerProvider;
+        this.lispStateHelper = new ConfigManagerHelper(this.mountedDataBrokerProvider);
+        neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
+    }
+
+    public synchronized void configureEndPoint(AddressEndpointWithLocation addressEp) {
+        try {
+            DataBroker dataBroker = lispStateHelper.getPotentialExternalDataBroker(addressEp).get();
+            String hostName = lispStateHelper.getHostName(addressEp).get();
+            LispState lispStateOfNode = configureHostIfNeeded(hostName, dataBroker);
+
+            long vni = getVni(addressEp.getTenant().getValue());
+            long vrf = vni;
+            addVniToVrfMappingIfNeeded(dataBroker, lispStateOfNode, vni, vrf);
+
+            Eid eid = lispStateHelper.getEid(addressEp, vni);
+
+            if(!lispStateOfNode.eidSetContains(eid)) {
+                addEidInEidTable(dataBroker, lispStateOfNode, eid);
+            }
+
+        } catch (LispConfigCommandFailedException e) {
+            LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp);
+        }
+    }
+
+    public synchronized LispState configureHostIfNeeded(String hostName, DataBroker vppDataBroker) throws LispConfigCommandFailedException {
+        LispState lispStateOfNode = lispStateMapper.get(hostName);
+
+        if (lispStateOfNode == null) {
+            lispStateOfNode = new LispState(hostName);
+            try {
+                enableLispForNode(vppDataBroker, lispStateOfNode);
+                addLocatorSet(vppDataBroker, lispStateOfNode);
+                addMapResolver(vppDataBroker, lispStateOfNode);
+                if (ConfigUtil.getInstance().isLispMapRegisterEnabled()) {
+                    enableMapRegister(vppDataBroker, lispStateOfNode);
+                    addMapServer(vppDataBroker, lispStateOfNode);
+                }
+                lispStateMapper.put(hostName, lispStateOfNode);
+            } catch (LispNotFoundException e) {
+                LOG.warn("Lisp host configuration failed: ", e.getMessage());
+                throw new LispConfigCommandFailedException("Failed LISP configuration!");
+            }
+        }
+        return lispStateOfNode;
+    }
+
+    public synchronized void deleteLispConfigurationForEndpoint(AddressEndpointWithLocation addressEp) {
+        try {
+            DataBroker vppDataBroker = lispStateHelper.getPotentialExternalDataBroker(addressEp).get();
+            String hostName = lispStateHelper.getHostName(addressEp).get();
+
+            LispState lispState = lispStateMapper.get(hostName);
+
+            if (lispState == null) {
+                LOG.debug("Endpoint not configured for LISP. EndPoint: {}", addressEp);
+            } else {
+                long vni = getVni(addressEp.getTenant().getValue());
+                Eid eid = lispStateHelper.getEid(addressEp, vni);
+
+                if (lispState.eidSetContains(eid)) {
+                    deleteEidFromEidTable(vppDataBroker, lispState, eid);
+                }
+
+                if (lispState.eidCount() == 0) {
+                    deleteLispStatesInEndPoints(vppDataBroker, lispState);
+                }
+            }
+        } catch (LispConfigCommandFailedException e) {
+            LOG.warn("Lisp command execution failed: {}", e.getMessage());
+        }
+    }
+
+    private void enableLispForNode(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
+        AbstractLispCommand<Lisp>
+                lispEnableCommand = LispCommandWrapper.enableLisp();
+        if (LispStateCommandExecutor.executePutCommand(vppDataBroker, lispEnableCommand)) {
+            lispState.setLispEnabled(true);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp Enable Command failed execution!");
+        }
+    }
+
+    private void addLocatorSet(DataBroker vppDataBroker, LispState lispState) throws LispNotFoundException, LispConfigCommandFailedException {
+        try {
+            String locatorSetName = lispStateHelper.constructLocatorSetName(lispState.getLocatorCount());
+            String interfaceName = lispStateHelper.readRlocInterface(lispState.getHostName(), vppDataBroker).get();
+            AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
+                    interfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
+            if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addLocatorSetCommand)) {
+                lispState.setLocIntfToLocSetNameMapping(interfaceName, locatorSetName);
+            } else {
+                throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
+                        + lispState.getHostName() + " and locator interface " + interfaceName);
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            throw new LispNotFoundException("No interface with Ip Address found!");
+        }
+
+    }
+
+    private void addMapResolver(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
+        IpAddress mapResolverIpAddress = ConfigUtil.getInstance().getOdlTenantIp();
+        Preconditions.checkNotNull(mapResolverIpAddress, "Map Resolver ip not properly configured!");
+
+        AbstractLispCommand<MapResolver> addMapResolverCommand = LispCommandWrapper.
+                addMapResolver(mapResolverIpAddress);
+        if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addMapResolverCommand)) {
+            lispState.addInMapResolverSet(mapResolverIpAddress);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp add map resolver for host " + lispState.getHostName()
+                    + " failed for ODL ip " + mapResolverIpAddress);
+        }
+    }
+
+    private void addMapServer(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
+        IpAddress mapServerIpAddress = ConfigUtil.getInstance().getOdlTenantIp();
+        Preconditions.checkNotNull(mapServerIpAddress, "Mapserver ip not properly configured!");
+        AbstractLispCommand<MapServer> addMapServerCommand = LispCommandWrapper.addMapServer(mapServerIpAddress);
+
+        if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addMapServerCommand)) {
+            lispState.addInMapServerSet(mapServerIpAddress);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp add map server for host " + lispState.getHostName()
+                    + " failed for ODL ip " + mapServerIpAddress);
+        }
+    }
+
+    private void enableMapRegister(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
+        AbstractLispCommand<MapRegister> enableMapRegisterCommand = LispCommandWrapper.enableMapRegister();
+
+        if (LispStateCommandExecutor.executePutCommand(vppDataBroker, enableMapRegisterCommand)) {
+            lispState.setMapRegisteredEnabled(true);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp enable mapregistration for host "
+                    + lispState.getHostName() + " failed!");
+        }
+
+    }
+
+    private void addVniToVrfMappingIfNeeded(DataBroker vppDataBroker,
+                                            LispState lispState,
+                                            long vni, long vrf) throws LispConfigCommandFailedException {
+        if (!lispState.vniSetContains(vni)) {
+            AbstractLispCommand<VniTable> addVniToVrfMapping = LispCommandWrapper.mapVniToVrf(vni, vrf);
+            addVniToVrfMapping.setOptions(General.Operations.PUT);
+            if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addVniToVrfMapping)) {
+                lispState.addInVniSet(vni);
+            } else {
+                throw new LispConfigCommandFailedException("Lisp add vrf " + vrf +" for vni " +vni
+                        + " command failed!");
+            }
+        }
+    }
+
+    private void addEidInEidTable(DataBroker vppDataBroker,
+                                  LispState lispState,
+                                  Eid eid) throws LispConfigCommandFailedException {
+        String mappingId = lispStateHelper.constructMappingName(lispState.eidCount());
+        AbstractLispCommand<LocalMapping> addLocalMappingInEidTableCommand = LispCommandWrapper
+                .addLocalMappingInEidTable(mappingId,
+                        eid,
+                        lispStateHelper.getFirstLocatorSetName(lispState),
+                        lispStateHelper.getDefaultHmacKey());
+        if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addLocalMappingInEidTableCommand)) {
+            lispState.addInEidSet(eid, mappingId);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp add local mapping for eid " + eid + "failed!");
+        }
+    }
+
+    private void deleteLispStatesInEndPoints(DataBroker vppDataBroker,
+                                             LispState lispState) throws LispConfigCommandFailedException {
+        AbstractLispCommand<LispFeatureData> deleteLispFeatureData = LispCommandWrapper.deleteLispFeatureData();
+
+        if (LispStateCommandExecutor.executeDeleteCommand(vppDataBroker, deleteLispFeatureData)) {
+            String computeNode = lispState.getHostName();
+            lispStateMapper.remove(computeNode);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp delete feature data command failed!");
+        }
+    }
+
+    private void deleteEidFromEidTable(DataBroker vppDataBroker,
+                                       LispState lispState,
+                                       Eid eid) throws LispConfigCommandFailedException {
+        String mappingId = lispState.getEidMapping(eid);
+        long value = eid.getVirtualNetworkId().getValue();
+
+        AbstractLispCommand<LocalMapping> deleteLocalMappingCommand = LispCommandWrapper
+                .deleteLocalMappingFromEidTable(mappingId, value);
+
+        if (LispStateCommandExecutor.executeDeleteCommand(vppDataBroker, deleteLocalMappingCommand)) {
+            lispState.deleteEid(eid);
+        } else {
+            throw new LispConfigCommandFailedException("Lisp delete local mapping command failed!");
+        }
+    }
+
+    private long getVni(String tenantUuid) {
+        return neutronTenantToVniMapper.getVni(tenantUuid);
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviHostSpecificInfo.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviHostSpecificInfo.java
new file mode 100644 (file)
index 0000000..b8315a2
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.bvi;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by Shakib Ahmed on 4/26/17.
+ */
+public class BviHostSpecificInfo {
+    private HashMap<String, HashMap<String, String>> hostIdToSubnetMapper;
+    private Multimap<String, String> subnetUuidToHostIdList;
+
+    public BviHostSpecificInfo() {
+        hostIdToSubnetMapper = new HashMap<>();
+        subnetUuidToHostIdList = ArrayListMultimap.create();
+    }
+
+    private HashMap<String, String> getSubnetsOfHost(String hostName) {
+        return hostIdToSubnetMapper.get(hostName);
+    }
+
+    private void putSubnetInfoOfAHost(String hostId, String subnetUuid, String interfaceName) {
+        HashMap<String, String> subnetsOfAHost = getSubnetsOfHost(hostId);
+
+        if (subnetsOfAHost == null) {
+            subnetsOfAHost = new HashMap<>();
+            hostIdToSubnetMapper.put(hostId, subnetsOfAHost);
+        }
+        subnetsOfAHost.put(subnetUuid, interfaceName);
+    }
+
+    public boolean bviAlreadyExists(String hostName, String subnetUuid) {
+        return hostIdToSubnetMapper.containsKey(hostName) &&
+                hostIdToSubnetMapper.get(hostName).containsKey(subnetUuid);
+    }
+
+    public void addBviForHost(String hostName, String subnetUuid, String interfaceName) {
+        putSubnetInfoOfAHost(hostName, subnetUuid, interfaceName);
+        subnetUuidToHostIdList.put(subnetUuid, hostName);
+    }
+
+    public int getBviCount(String hostName) {
+        if (hostIdToSubnetMapper.get(hostName) == null) {
+            return 0;
+        }
+        return hostIdToSubnetMapper.get(hostName).size();
+    }
+
+    public void clearSubnet(String subnetUuid) {
+        subnetUuidToHostIdList.get(subnetUuid).forEach(hostId -> {
+            deleteParticularSubnetFromHost(hostId, subnetUuid);
+        });
+        subnetUuidToHostIdList.get(subnetUuid).clear();
+    }
+
+    private void deleteParticularSubnetFromHost(String hostId, String subnetUuid) {
+        hostIdToSubnetMapper.get(hostId).remove(subnetUuid);
+    }
+
+    public List<String> getHostsWithSubnet(String subnetUuid) {
+        return subnetUuidToHostIdList.get(subnetUuid).stream().collect(Collectors.toList());
+    }
+
+    public String getInterfaceNameForBviInHost(String hostId, String subnetUuid) {
+        if (hostIdToSubnetMapper.get(hostId) != null) {
+            return hostIdToSubnetMapper.get(hostId).get(subnetUuid);
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/bvi/BviManager.java
new file mode 100644 (file)
index 0000000..078a3fd
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.bvi;
+
+import com.google.common.base.Preconditions;
+import com.google.common.eventbus.Subscribe;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.event.GbpSubnetEvent;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpSubnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by Shakib Ahmed on 4/26/17.
+ */
+public class BviManager {
+    private static final Logger LOG = LoggerFactory.getLogger(BviManager.class);
+
+    private ConfigManagerHelper managerHelper;
+
+    private HashMap<String, GbpSubnet> subnetInformation;
+
+    private BviHostSpecificInfo bviHostSpecificInfo;
+    private NeutronTenantToVniMapper neutronTenantToVniMapper;
+
+    public BviManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
+        managerHelper = new ConfigManagerHelper(mountedDataBrokerProvider);
+        subnetInformation = new HashMap<>();
+        bviHostSpecificInfo = new BviHostSpecificInfo();
+        neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
+    }
+
+    @Subscribe
+    public synchronized void gbpSubnetChanged(GbpSubnetEvent event) {
+        final GbpSubnet oldGbpSubnet = event.getBefore().orNull();
+        final GbpSubnet newGbpSubnet = event.getAfter().orNull();
+        switch (event.getDtoModificationType()) {
+            case CREATED:
+                Preconditions.checkNotNull(newGbpSubnet);
+                processSubnetCreated(newGbpSubnet.getId(), newGbpSubnet);
+                break;
+            case UPDATED:
+                Preconditions.checkNotNull(oldGbpSubnet);
+                Preconditions.checkNotNull(newGbpSubnet);
+                processSubnetDeleted(oldGbpSubnet.getId());
+                processSubnetCreated(newGbpSubnet.getId(), newGbpSubnet);
+                break;
+            case DELETED:
+                Preconditions.checkNotNull(oldGbpSubnet);
+                processSubnetDeleted(oldGbpSubnet.getId());
+                break;
+        }
+    }
+
+    private void processSubnetCreated(String subnetUuid, GbpSubnet subnetInfo) {
+        subnetInformation.put(subnetUuid, subnetInfo);
+    }
+
+    private void processSubnetDeleted(String subnetUuid) {
+        subnetInformation.remove(subnetUuid);
+
+        deleteBviIfExists(subnetUuid);
+    }
+
+    public GbpSubnet getSubnetInfo(String subnetUuid) {
+        return subnetInformation.get(subnetUuid);
+    }
+
+    public void createBviIfNecessary(AddressEndpointWithLocation addressEp,
+                                     String bridgeDomainName) {
+        try {
+            DataBroker vppDataBroker = managerHelper.getPotentialExternalDataBroker(addressEp).get();
+            String hostName = managerHelper.getHostName(addressEp).get();
+            String subnetUuid = managerHelper.getSubnet(addressEp);
+
+            if (bviHostSpecificInfo.bviAlreadyExists(hostName, subnetUuid)) {
+                return;
+            }
+
+            GbpSubnet gbpSubnetInfo = Preconditions.checkNotNull(getSubnetInfo(subnetUuid),
+                    "Subnet UUID {} hasn't been created yet!", subnetUuid);
+
+            LoopbackCommand.LoopbackCommandBuilder loopbackCommandBuilder =
+                    new LoopbackCommand.LoopbackCommandBuilder();
+            loopbackCommandBuilder.setInterfaceName("loop"
+                    + bviHostSpecificInfo.getBviCount(hostName));
+            loopbackCommandBuilder.setBridgeDomain(bridgeDomainName);
+            loopbackCommandBuilder.setBvi(true);
+            loopbackCommandBuilder.setEnabled(true);
+            loopbackCommandBuilder.setVrfId(getVni(addressEp.getTenant().getValue()));
+            loopbackCommandBuilder.setIpAddress(gbpSubnetInfo.getGatewayIp());
+            loopbackCommandBuilder.setIpPrefix(gbpSubnetInfo.getCidr());
+            loopbackCommandBuilder.setOperation(General.Operations.PUT);
+            createBviInterface(hostName, vppDataBroker, loopbackCommandBuilder);
+        } catch (LispConfigCommandFailedException e) {
+            LOG.debug("LISP loopback command failed for {}", e.getMessage());
+        }
+    }
+
+    public void createBviInterface(String hostName, DataBroker vppDataBroker,
+                                   LoopbackCommand.LoopbackCommandBuilder commandBuilder) throws LispConfigCommandFailedException {
+
+        if (GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker,
+                                                     commandBuilder.build(),
+                                                     GbpNetconfTransaction.RETRY_COUNT)) {
+            bviHostSpecificInfo.addBviForHost(hostName,
+                                              commandBuilder.getBridgeDomain(),
+                                              commandBuilder.getInterfaceName());
+        } else {
+            throw new LispConfigCommandFailedException("BVI could not be created for "
+                    + hostName + " and bridge domain " + commandBuilder.getBridgeDomain());
+        }
+    }
+
+    public void deleteBviIfExists(String subnetUuid) {
+
+        List<String> hostsWithSubnet = bviHostSpecificInfo.getHostsWithSubnet(subnetUuid);
+
+        hostsWithSubnet.forEach(host -> {
+            DataBroker vppDataBroker = managerHelper.getPotentialExternalDataBroker(host).get();
+            String bviInterfaceName = bviHostSpecificInfo.getInterfaceNameForBviInHost(host, subnetUuid);
+            GbpNetconfTransaction.netconfSyncedDelete(vppDataBroker,
+                    VppIidFactory.getInterfaceIID(new InterfaceKey(bviInterfaceName)), GbpNetconfTransaction.RETRY_COUNT);
+        });
+    }
+
+    private long getVni(String tenantUuid) {
+        return neutronTenantToVniMapper.getVni(tenantUuid);
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispConfigCommandFailedException.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispConfigCommandFailedException.java
new file mode 100644 (file)
index 0000000..afe1d02
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.exception;
+
+/**
+ * Created by Shakib Ahmed on 4/3/17.
+ */
+public class LispConfigCommandFailedException extends Exception {
+    public LispConfigCommandFailedException(final String message) {
+        super(message);
+    }
+
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispHelperArgumentException.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispHelperArgumentException.java
new file mode 100644 (file)
index 0000000..8a76674
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.exception;
+
+/**
+ * Created by Shakib Ahmed on 3/31/17.
+ */
+public class LispHelperArgumentException extends Exception {
+    public LispHelperArgumentException(final String message) {
+        super(message);
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispNotFoundException.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/exception/LispNotFoundException.java
new file mode 100644 (file)
index 0000000..e4e2448
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.exception;
+
+/**
+ * Created by Shakib Ahmed on 4/2/17.
+ */
+public class LispNotFoundException extends Exception{
+    public LispNotFoundException(final String message) {
+        super(message);
+    }
+
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/mappers/NeutronTenantToVniMapper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/mappers/NeutronTenantToVniMapper.java
new file mode 100644 (file)
index 0000000..d464ef7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc.  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.groupbasedpolicy.renderer.vpp.lisp.mappers;
+
+import java.util.HashMap;
+
+/**
+ * Created by Shakib Ahmed on 2/17/17.
+ */
+public class NeutronTenantToVniMapper {
+    private HashMap<String, Long> neutronTenantToVniMapper;
+    private long id = 1;
+
+    private static final NeutronTenantToVniMapper INSTANCE = new NeutronTenantToVniMapper();
+
+    public static NeutronTenantToVniMapper getInstance() {
+        return INSTANCE;
+    }
+
+    private NeutronTenantToVniMapper() {
+        neutronTenantToVniMapper = new HashMap<>();
+    }
+
+    public synchronized long getVni(String tenantUuid) {
+        if (neutronTenantToVniMapper.containsKey(tenantUuid)) {
+            return neutronTenantToVniMapper.get(tenantUuid);
+        }
+        neutronTenantToVniMapper.put(tenantUuid, id);
+        return id++;
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java
new file mode 100644 (file)
index 0000000..91185b7
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.util;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispState;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.LispUtil;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+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.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.Containment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.HmacKeyType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.hmac.key.grouping.HmacKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.Routing;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.RoutingBuilder;
+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.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.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Created by Shakib Ahmed on 3/31/17.
+ */
+public class ConfigManagerHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigManagerHelper.class);
+
+    private static final String TENANT_INTERFACE = "tenant-interface";
+    private MountedDataBrokerProvider mountedDataBrokerProvider;
+
+    public ConfigManagerHelper(MountedDataBrokerProvider mountedDataBrokerProvider) {
+        this.mountedDataBrokerProvider = mountedDataBrokerProvider;
+    }
+
+    public Optional<DataBroker> getPotentialExternalDataBroker(AddressEndpointWithLocation addressEpWithLoc) {
+        ExternalLocationCase externalLocationCase = resolveAndValidateLocation(addressEpWithLoc);
+        InstanceIdentifier<?> vppNodeIid = externalLocationCase.getExternalNodeMountPoint();
+        String interfacePath = externalLocationCase.getExternalNodeConnector();
+
+        Optional<DataBroker> potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
+
+        Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
+                "Cannot resolve data broker for interface path: {}", interfacePath);
+
+        return potentialVppDataProvider;
+    }
+
+    public Optional<DataBroker> getPotentialExternalDataBroker(VppEndpoint vppEp) {
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEp.getVppNodeId());
+        Optional<DataBroker> potentialVppDataProvider =
+                mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
+
+        Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
+                "Cannot resolve data broker for Vpp Endpoint: {}", vppEp);
+        return potentialVppDataProvider;
+    }
+
+    public Optional<DataBroker> getPotentialExternalDataBroker(String hostId) {
+        InstanceIdentifier<Node> nodeIid = VppIidFactory.getNetconfNodeIid(new NodeId(hostId));
+        Optional<DataBroker> potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(nodeIid);
+        Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
+                "Data Broker not found for {}", hostId);
+        return potentialVppDataProvider;
+    }
+
+    public Optional<String> getHostName(AddressEndpointWithLocation addrEp) {
+        ExternalLocationCase locationCase = resolveAndValidateLocation(addrEp);
+        NodeKey nodeKey = locationCase.getExternalNodeMountPoint().firstKeyOf(Node.class);
+        String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(),
+                "Host Id extraction failed from address endpoint: {}", addrEp);
+        return Optional.fromNullable(hostId);
+    }
+
+    public ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
+        LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
+        if (!(locationType instanceof ExternalLocationCase)) {
+            throw new IllegalArgumentException("Endpoint does not have external location " + addrEpWithLoc);
+        }
+        ExternalLocationCase result = (ExternalLocationCase) locationType;
+        if (result.getExternalNodeMountPoint() == null || result.getExternalNodeConnector() == null) {
+            throw new IllegalArgumentException(
+                    "Endpoint does not have external-node-mount-point or external-node-connector " + addrEpWithLoc);
+        }
+        return result;
+    }
+
+    //This is almost identical to VBD's equivalent method
+    public ListenableFuture<String> readRlocInterface(@Nonnull String hostName, @Nonnull DataBroker vppDataBroker) {
+        Preconditions.checkNotNull(hostName, "Hostname is null!");
+        Preconditions.checkNotNull(vppDataBroker, "Vpp DataBroker is null!");
+        final Optional<InterfacesState> opInterfaceState = GbpNetconfTransaction.read(vppDataBroker,
+                LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class),
+                GbpNetconfTransaction.RETRY_COUNT);
+
+        if (!opInterfaceState.isPresent()) {
+            LOG.debug("There appear to be no interfaces on node {}.", hostName);
+            return Futures.immediateFailedFuture(new LispNotFoundException("No interfaces found"));
+        }
+
+        String interfaceName = null;
+        for(Interface intf: opInterfaceState.get().getInterface()) {
+            if(!ipAddressPresent(intf)) {
+                continue;
+            }
+            interfaceName = intf.getName();
+        }
+
+        final Optional<Interfaces> opInterfaces =
+                GbpNetconfTransaction.read(vppDataBroker, LogicalDatastoreType.CONFIGURATION,
+                        InstanceIdentifier.create(Interfaces.class), GbpNetconfTransaction.RETRY_COUNT);
+
+
+        if (opInterfaces.isPresent()) {
+            for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.
+                    interfaces.Interface intf : opInterfaces.get().getInterface()) {
+                if (TENANT_INTERFACE.equals(intf.getDescription())
+                        && ipAddressPresent(intf)
+                        && intf.getType().equals(EthernetCsmacd.class)) {
+                    return Futures.immediateFuture(intf.getName());
+                }
+            }
+        }
+
+        if (interfaceName == null) {
+            LOG.warn("No interface with IP found for host {}", hostName);
+            return Futures.immediateFailedFuture(new LispNotFoundException("No interface with Ip address found!"));
+        }
+        return Futures.immediateFuture(interfaceName);
+    }
+
+    private boolean ipAddressPresent(Interface intf) {
+        Interface2 augIntf = intf.getAugmentation(Interface2.class);
+
+        if (augIntf == null) {
+            return false;
+        }
+
+        Ipv4 ipv4 = augIntf.getIpv4();
+
+        if (ipv4 == null) {
+            return false;
+        }
+
+        final List<Address> addresses = ipv4.getAddress();
+
+        if (addresses == null || addresses.isEmpty()) {
+            return false;
+        }
+
+        final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
+
+        if (ip == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean ipAddressPresent(final org.opendaylight.yang.gen.v1.urn.ietf.
+            params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf) {
+        final Interface1 augIntf = intf.getAugmentation(Interface1.class);
+
+        if (augIntf == null) {
+            LOG.debug("Cannot get Interface1 augmentation for intf {}", intf);
+            return false;
+        }
+
+        final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4 ipv4 =
+                augIntf.getIpv4();
+        if (ipv4 == null) {
+            return false;
+        }
+
+        final List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address> addresses =
+                ipv4.getAddress();
+        if (addresses == null || addresses.isEmpty()) {
+            return false;
+        }
+
+        final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
+        if (ip == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public String constructLocatorSetName(int locatorSetCount) {
+        return LispStateManager.DEFAULT_LOCATOR_SET_NAME_PREFIX + (locatorSetCount + 1);
+    }
+
+    public String constructMappingName(int presentMappingCount) {
+        return LispStateManager.DEFAULT_MAPPINGRECORD_NAME_PREFIX + (presentMappingCount + 1);
+    }
+
+    public String getSubnet(AddressEndpointWithLocation addressEp) {
+        String subnetUuid = null;
+        Containment containment = addressEp.getNetworkContainment().getContainment();
+        if (containment instanceof NetworkDomainContainment) {
+            NetworkDomainContainment networkDomainContainment = (NetworkDomainContainment) containment;
+            subnetUuid = networkDomainContainment.getNetworkDomainId().getValue();
+        }
+        return subnetUuid;
+    }
+
+    public Eid getEid(AddressEndpointWithLocation addressEp, long vni) {
+        String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
+        return LispUtil.toEid(LispUtil.toIpv4(ipPrefix), vni, Ipv4Afi.class);
+    }
+
+    public String getIpWithPrefixOfEndpoint(AddressEndpointWithLocation addressEp) {
+        String ipPrefix = null;
+        if (addressEp.getAddressType().equals(IpPrefixType.class)) {
+            ipPrefix = addressEp.getAddress();
+        }
+        return Preconditions.checkNotNull(ipPrefix,
+                "No IP address found for Address Endpoint: {}", addressEp);
+    }
+
+    public Ipv4Address getInterfaceIp(AddressEndpointWithLocation addressEp) {
+        String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
+        return LispUtil.toIpv4(ipPrefix).getIpv4();
+    }
+
+    public Ipv4Prefix getInterfaceIpAsPrefix(AddressEndpointWithLocation addressEp) {
+        return new Ipv4Prefix(getInterfaceIp(addressEp).getValue() + "/32");
+    }
+
+    public String getFirstLocatorSetName(LispState lispState) {
+        Set<Map.Entry<String, String >> locatorSet = lispState.getLocatorSetEntry();
+        Preconditions.checkNotNull(locatorSet, "No locator set found!");
+        if (!locatorSet.iterator().hasNext()) {
+            return null;
+        }
+
+        return locatorSet.iterator().next().getValue();
+    }
+
+    public HmacKey getDefaultHmacKey() {
+        return LispUtil.toHmacKey(HmacKeyType.Sha196Key, LispStateManager.DEFAULT_XTR_KEY);
+    }
+
+    public Routing getRouting(long vrf) {
+        return new RoutingBuilder().setIpv4VrfId(vrf).build();
+    }
+}
index 759e849604bcefd1162663b142730b50f3d00b0a..f3d9331a32912b9d904d5fe1a2986d829b79d35f 100644 (file)
@@ -27,6 +27,8 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.RoutingCommand;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.bvi.BviManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatUtil;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
@@ -99,15 +101,20 @@ public final class ForwardingManager {
     private final BridgeDomainManager bdManager;
     private final NatManager natManager;
     private final RoutingManager routingManager;
+    private final LispStateManager lispStateManager;
+    private final BviManager bviManager;
     private final DataBroker dataBroker;
 
     public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull AclManager aclManager,
         @Nonnull NatManager natManager, @Nonnull RoutingManager routingManager, @Nonnull BridgeDomainManager bdManager,
+        @Nonnull LispStateManager lispStateManager, @Nonnull BviManager bviManager,
         @Nonnull DataBroker dataBroker) {
         this.ifaceManager = Preconditions.checkNotNull(ifaceManager);
         this.bdManager = Preconditions.checkNotNull(bdManager);
         this.natManager = Preconditions.checkNotNull(natManager);
         this.routingManager = Preconditions.checkNotNull(routingManager);
+        this.lispStateManager = Preconditions.checkNotNull(lispStateManager);
+        this.bviManager = Preconditions.checkNotNull(bviManager);
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.aclManager = Preconditions.checkNotNull(aclManager);
     }
@@ -195,6 +202,11 @@ public final class ForwardingManager {
 
     public void createForwardingForEndpoint(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
         AddressEndpointWithLocation rEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
+
+        if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+            lispStateManager.configureEndPoint(rEp);
+        }
+
         ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
         if (Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
             // TODO add it to the status for renderer manager
@@ -213,9 +225,13 @@ public final class ForwardingManager {
                 String l2FloodDomain = optL2FloodDomain.get();
                 try {
                     ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, aclManager.resolveAclsOnInterface(
-                        rEpKey, policyCtx), isBviForEndpoint(rEp)).get();
+                            rEpKey, policyCtx), isBviForEndpoint(rEp)).get();
                     LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
 
+                    if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+                        bviManager.createBviIfNecessary(rEp, l2FloodDomain);
+                    }
+
                 } catch (InterruptedException | ExecutionException e) {
                     // TODO add it to the status for renderer manager
                     LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e);
@@ -257,6 +273,9 @@ public final class ForwardingManager {
         }
         if (!Strings.isNullOrEmpty(rEpLoc.getExternalNode())) {
             try {
+                if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+                    lispStateManager.deleteLispConfigurationForEndpoint(rEp);
+                }
                 ifaceManager.deleteBridgeDomainFromInterface(rEp).get();
                 LOG.debug("bridge-domain was deleted from interface for endpoint {}", rEp);
             } catch (InterruptedException | ExecutionException e) {
index 956028b1b75c8ef8672989617896a18821a137ac..b054a000dd29dce5d5e0782379083fa73d477725 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.AbstractConfigCommand;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.AbstractInterfaceCommand;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.interfaces.ConfigCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.AbstractLispCommand;
 import org.opendaylight.vbd.impl.transaction.VbdNetconfTransaction;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -67,6 +68,22 @@ public class GbpNetconfTransaction {
         return result;
     }
 
+    /***
+     * Netconf wrapper method for synced requests for write operation on a Netconf Device
+     * @param mountpoint    netconf device
+     * @param command       abstract lisp command that needs to be executed
+     * @param retryCounter  retry counter, will repeat the operation for specified amount of times if transaction fails
+     * @return true if transaction is successful, false otherwise
+     */
+    public static <T extends DataObject> boolean netconfSyncedWrite(@Nonnull final DataBroker mountpoint,
+                                                                    @Nonnull final AbstractLispCommand<T> command,
+                                                                    byte retryCounter) {
+        VbdNetconfTransaction.REENTRANT_LOCK.lock();
+        boolean result = write(mountpoint, command, retryCounter);
+        VbdNetconfTransaction.REENTRANT_LOCK.unlock();
+        return result;
+    }
+
     /***
      * Netconf wrapper method for synced requests for delete operation on a Netconf Device
      * @param mountpoint    netconf device
@@ -176,6 +193,39 @@ public class GbpNetconfTransaction {
         }
     }
 
+    /**
+     * Use {@link AbstractLispCommand} to put data into netconf transaction and submit. Transaction is restarted if failed
+     *
+     * @param mountpoint   to access remote device
+     * @param command      abstract lisp command with data, datastore type and iid
+     * @param retryCounter number of attempts
+     * @return true if transaction is successful, false otherwise
+     */
+    private static <T extends DataObject> boolean write(final DataBroker mountpoint,
+                                                        final AbstractLispCommand<T> command,
+                                                        byte retryCounter) {
+        LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
+        Preconditions.checkNotNull(mountpoint);
+        final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
+        try {
+            command.execute(rwTx);
+            final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
+            futureTask.get();
+            LOG.trace("Netconf WRITE transaction done for command {}", command);
+            return true;
+        } catch (Exception e) {
+            // Retry
+            if (retryCounter > 0) {
+                LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage());
+                rwTx.cancel();
+                return write(mountpoint, command, --retryCounter);
+            } else {
+                LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
+                return false;
+            }
+        }
+    }
+
     /**
      * Read data from remote device. Transaction is restarted if failed.
      *
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/LispUtil.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/LispUtil.java
new file mode 100644 (file)
index 0000000..59be81f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.util;
+
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.dom.EidDom;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.dom.HmacKeyDom;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.HmacKeyType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.hmac.key.grouping.HmacKey;
+
+import java.security.InvalidParameterException;
+
+/**
+ * Created by Shakib Ahmed on 3/21/17.
+ */
+public class LispUtil {
+    private LispUtil() {
+
+    }
+
+    public static Eid toEid(Address address, long vni, Class<? extends LispAddressFamily> addressType) {
+        EidDom eidDom = new EidDom();
+        eidDom.setAddress(address);
+        eidDom.setVni(vni);
+        eidDom.setAddressFamily(addressType);
+        return eidDom.getSALObject();
+    }
+
+    public static HmacKey toHmacKey(HmacKeyType keyType, String key) {
+        HmacKeyDom hmacKeyDom = new HmacKeyDom();
+        hmacKeyDom.setKey(key);
+        hmacKeyDom.setKeyType(keyType);
+        return hmacKeyDom.getSALObject();
+    }
+
+    public static Ipv4 toIpv4(String ipStr) throws InvalidParameterException {
+        String[] strArray = ipStr.split("/");
+        if (strArray.length == 0 || strArray.length > 2) {
+            throw new InvalidParameterException("Parameter " + ipStr + " is invalid for IPv4");
+        }
+
+        if(strArray.length == 2) {
+            int mask = Integer.valueOf(strArray[1]);
+            if(mask != 32) {
+                throw new InvalidParameterException("Parameter " + ipStr + " is invalid for IPv4");
+            }
+        }
+
+        return new Ipv4Builder().setIpv4(new Ipv4Address(strArray[0])).build();
+    }
+}
index 17d947f9fc87ee192fa35896508ee66502c56460..52dcdf5d239e336e525f5d2cafacbae27b5fc939 100644 (file)
@@ -240,6 +240,7 @@ public class DtoFactory {
         return new AddressEndpointWithLocationBuilder().setKey(key)
             .setNetworkContainment(networkContainment)
             .setAbsoluteLocation(absoluteLocation)
+            .setTenant(new TenantId(TENANT_ID))
             .build();
     }
 
index 66fc78951bd0248115610aba27be4aef9ed1da8e..541f2acddde214e1f9ab253729a58bfeaa7f0451 100644 (file)
@@ -23,6 +23,8 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.bvi.BviManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
@@ -106,9 +108,11 @@ public class BridgeDomainManagerImplTest extends CustomDataBrokerTest {
         final AclManager aclManager = Mockito.mock(AclManager.class);
         final NatManager natManager = Mockito.mock(NatManager.class);
         final RoutingManager routingManager = Mockito.mock(RoutingManager.class);
+        final LispStateManager lispStateManager = Mockito.mock(LispStateManager.class);
+        final BviManager bviManager = Mockito.mock(BviManager.class);
         final ForwardingManager fwManager =
             new ForwardingManager(interfaceManager, aclManager, natManager, routingManager, bridgeDomainManager,
-                dataBroker);
+                lispStateManager, bviManager, dataBroker);
         fwManager.setTimer((byte) 1);
     }
 
index 40caf4490db1d21dfde97df06583f7c6056bd4f3..1ae6f5f09bd7519a26c3ab5c924ea5e2bcfef26d 100644 (file)
@@ -23,6 +23,8 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.bvi.BviManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListWrapper;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
@@ -67,13 +69,18 @@ public class ForwardingManagerTest extends CustomDataBrokerTest {
     private NatManager natManager;
     @Mock
     private RoutingManager routingManager;
+    @Mock
+    private LispStateManager lispStateManager;
+    @Mock
+    private BviManager bviManager;
 
     private ForwardingManager fwdManager;
 
     @Before
     public void init() {
         fwdManager =
-            new ForwardingManager(ifaceManager, aclManager, natManager, routingManager, bdManager, getDataBroker());
+            new ForwardingManager(ifaceManager, aclManager, natManager, routingManager, bdManager, lispStateManager,
+                    bviManager, getDataBroker());
     }
 
     @Override
index 112c8aadbea1263a60da294f084463e977bcc426..5b328c81daf6651dc05ca76c1bf9ec139dbfd8e3 100644 (file)
@@ -28,6 +28,8 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEv
 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.bvi.BviManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
@@ -86,6 +88,8 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
     private ForwardingManager fwManager;
     private NatManager natManager;
     private RoutingManager routingManager;
+    private LispStateManager lispStateManager;
+    private BviManager bviManager;
     private VppRendererPolicyManager vppRendererPolicyManager;
 
     @Override
@@ -108,7 +112,10 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
         natManager = new NatManager(dataBroker, mountedDataProviderMock);
         routingManager = new RoutingManager(dataBroker, mountedDataProviderMock);
         bdManager = new BridgeDomainManagerImpl(mountPointDataBroker);
-        fwManager = new ForwardingManager(ifaceManager, aclManager, natManager, routingManager, bdManager, dataBroker);
+        lispStateManager = new LispStateManager(mountedDataProviderMock);
+        bviManager = new BviManager(mountedDataProviderMock);
+        fwManager = new ForwardingManager(ifaceManager, aclManager, natManager, routingManager, bdManager,
+                lispStateManager, bviManager, dataBroker);
         vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, aclManager, dataBroker);
         fwManager.setTimer((byte) 1);
     }