2 * Copyright (c) 2017 Cisco Systems. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp;
11 import com.google.common.base.Preconditions;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.AbstractLispCommand;
14 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.LispCommandWrapper;
15 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.LispState;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
25 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.feature.data.grouping.GpeFeatureData;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.NativeForwardPathsTables;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518._native.forward.paths.tables._native.forward.paths.table.NativeForwardPath;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.Lisp;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.LocalMapping;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.eid.table.grouping.eid.table.VniTable;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.itr.remote.locator.sets.grouping.ItrRemoteLocatorSet;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.lisp.feature.data.grouping.LispFeatureData;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.locator.sets.grouping.locator.sets.LocatorSet;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.register.grouping.MapRegister;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.resolvers.grouping.map.resolvers.MapResolver;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.servers.grouping.map.servers.MapServer;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import javax.annotation.Nonnull;
45 import java.util.concurrent.ExecutionException;
48 * Created by Shakib Ahmed on 3/29/17.
50 public class LispStateManager {
51 private static final Logger LOG = LoggerFactory.getLogger(LispStateManager.class);
53 private HostRelatedInfoContainer hostRelatedInfoContainer;
54 private MountedDataBrokerProvider mountedDataBrokerProvider;
55 private ConfigManagerHelper lispStateHelper;
57 private NeutronTenantToVniMapper neutronTenantToVniMapper;
59 private static final short DEFAULT_PRIORITY = 1;
60 private static final short DEFAULT_WEIGHT = 1;
61 public static final String DEFAULT_XTR_KEY = "admin";
62 public static final String DEFAULT_LOCATOR_SET_NAME_PREFIX = "LS";
63 public static final String DEFAULT_MAPPINGRECORD_NAME_PREFIX = "MR_";
65 public LispStateManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
66 Preconditions.checkNotNull(mountedDataBrokerProvider,
67 "MountedDataBrokerProvider found to be null!");
68 hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance();
69 this.mountedDataBrokerProvider= mountedDataBrokerProvider;
70 this.lispStateHelper = new ConfigManagerHelper(this.mountedDataBrokerProvider);
71 neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
74 public synchronized void processCreateEndPoint(AddressEndpointWithLocation addressEp) {
76 if (lispStateHelper.isMetadataPort(addressEp)) {
79 EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp);
80 LispState lispStateOfHost = configureHostIfNeeded(endpointHost);
82 long vni = getVni(addressEp.getTenant().getValue());
85 Eid eid = lispStateHelper.getEid(addressEp, vni);
86 String eidMappingName = lispStateHelper.constructEidMappingName(addressEp);
88 addVniToVrfMappingIfNeeded(endpointHost.getHostDataBroker(), lispStateOfHost, vni, vrf);
90 if (lispStateHelper.getInterfaceIp(addressEp).getValue().equals(Constants.METADATA_IP)) {
94 addEidOnHostIfNeeded(endpointHost, lispStateOfHost, eid, eidMappingName);
95 } catch (LispConfigCommandFailedException e) {
96 LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp);
100 private void addEidOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfNode, Eid eid,
101 String eidMappingName)
102 throws LispConfigCommandFailedException {
103 if(!lispStateOfNode.eidSetContains(eid)) {
104 addEidInEidTable(endpointHost.getHostDataBroker(), lispStateOfNode, eid, eidMappingName);
108 private synchronized LispState configureHostIfNeeded(EndpointHost endpointHost)
109 throws LispConfigCommandFailedException {
110 LispState lispStateOfHost = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName());
112 if (lispStateOfHost == null) {
113 LOG.debug("Configuring host {} for LISP", endpointHost.getHostName());
114 lispStateOfHost = new LispState();
116 enableLispOnHost(endpointHost, lispStateOfHost);
117 enableGpeOnHostIfNeeded(endpointHost, lispStateOfHost);
118 addLocatorSetOnHost(endpointHost, lispStateOfHost);
119 addMapResolverOnHost(endpointHost, lispStateOfHost);
120 enableMapRegistrationOnHostIfNeeded(endpointHost, lispStateOfHost);
122 hostRelatedInfoContainer.setLispStateOfHost(endpointHost.getHostName(), lispStateOfHost);
123 } catch (LispNotFoundException e) {
124 LOG.warn("Lisp host configuration failed: ", e.getMessage());
125 throw new LispConfigCommandFailedException("Failed LISP configuration!");
128 return lispStateOfHost;
131 private void enableGpeOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost)
132 throws LispConfigCommandFailedException {
133 if (ConfigUtil.getInstance().isL3FlatEnabled()) {
134 enableGpeForHost(endpointHost, lispStateOfHost);
138 private void enableMapRegistrationOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost)
139 throws LispConfigCommandFailedException {
140 if (ConfigUtil.getInstance().isLispMapRegisterEnabled()) {
141 enableMapRegister(endpointHost);
142 addMapServer(endpointHost, lispStateOfHost);
146 private void enableLispOnHost(EndpointHost endpointHost, LispState lispState)
147 throws LispConfigCommandFailedException {
148 AbstractLispCommand<Lisp>
149 lispEnableCommand = LispCommandWrapper.enableLisp();
150 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), lispEnableCommand)) {
151 lispState.setLispEnabled(true);
153 throw new LispConfigCommandFailedException("Lisp Enable Command failed execution!");
157 private void enableGpeForHost(EndpointHost endpointHost, LispState lispState)
158 throws LispConfigCommandFailedException {
159 AbstractLispCommand<GpeFeatureData>
160 gpeEnableCommand = LispCommandWrapper.enableGpe();
161 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), gpeEnableCommand)) {
162 lispState.setGpeEnabled(true);
164 throw new LispConfigCommandFailedException("GPE Enable Command failed execution!");
168 private void addLocatorSetOnHost(EndpointHost endpointHost, LispState lispState)
169 throws LispNotFoundException, LispConfigCommandFailedException {
171 String locatorSetName = lispStateHelper.constructLocatorSetName(lispState.getLocatorCount());
172 String lispDataInterfaceName = lispStateHelper
173 .getLispDataRlocInterfaceName(endpointHost.getHostName(), endpointHost.getHostDataBroker()).get();
174 AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
175 lispDataInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
176 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), addLocatorSetCommand)) {
177 lispState.setLocIntfToLocSetNameMapping(lispDataInterfaceName, locatorSetName);
179 throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
180 + endpointHost.getHostName() + " and locator interface " + lispDataInterfaceName);
183 addExtraItrRlocLocatorSetIfNeeded(endpointHost, lispDataInterfaceName);
184 } catch (InterruptedException | ExecutionException e) {
185 throw new LispNotFoundException("No interface with Ip Address found!");
189 private void addExtraItrRlocLocatorSetIfNeeded(EndpointHost endpointHost, String lispDataInterfaceName)
190 throws LispNotFoundException, LispConfigCommandFailedException {
191 String lispCpRlocInterfaceName = lispStateHelper.getLispCpRlocInterfaceName(endpointHost.getHostDataBroker());
192 if (lispCpRlocInterfaceName == null
193 || lispCpRlocInterfaceName.isEmpty()
194 || lispCpRlocInterfaceName.equals(lispDataInterfaceName)) {
198 addItrLocatorSet(endpointHost, lispCpRlocInterfaceName);
201 private void addItrLocatorSet(EndpointHost endpointHost, String lispCpInterfaceName)
202 throws LispNotFoundException, LispConfigCommandFailedException {
203 String locatorSetName = lispStateHelper.constructLocatorSetNameForItrRloc();
204 AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
205 lispCpInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
206 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), addLocatorSetCommand)) {
207 throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
208 + endpointHost.getHostName() + " and locator interface " + lispCpInterfaceName);
211 AbstractLispCommand<ItrRemoteLocatorSet> addItrRlocCommand = LispCommandWrapper.addItrRloc(locatorSetName);
212 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), addItrRlocCommand)) {
213 throw new LispConfigCommandFailedException("Lisp add Itr Rloc command failed for host "
214 + endpointHost.getHostName() + " and locator set " + locatorSetName);
218 private void addMapResolverOnHost(EndpointHost endpointHost, LispState lispState)
219 throws LispConfigCommandFailedException {
220 IpAddress mapResolverIpAddress = ConfigUtil.getInstance().getOdlIp();
221 Preconditions.checkNotNull(mapResolverIpAddress, "Map Resolver ip not properly configured!");
223 AbstractLispCommand<MapResolver> addMapResolverCommand = LispCommandWrapper.
224 addMapResolver(mapResolverIpAddress);
225 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), addMapResolverCommand)) {
226 lispState.addInMapResolverSet(mapResolverIpAddress);
228 throw new LispConfigCommandFailedException("Lisp add map resolver for host " + endpointHost.getHostName()
229 + " failed for ODL ip " + mapResolverIpAddress);
233 private void enableMapRegister(EndpointHost endpointHost)
234 throws LispConfigCommandFailedException {
235 AbstractLispCommand<MapRegister> enableMapRegisterCommand = LispCommandWrapper.enableMapRegister();
237 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), enableMapRegisterCommand)) {
239 throw new LispConfigCommandFailedException("Lisp enable mapregistration for host "
240 + endpointHost.getHostName() + " failed!");
245 private void addMapServer(EndpointHost endpointHost, LispState lispState) throws LispConfigCommandFailedException {
246 IpAddress mapServerIpAddress = ConfigUtil.getInstance().getOdlIp();
247 Preconditions.checkNotNull(mapServerIpAddress, "Mapserver ip not properly configured!");
248 AbstractLispCommand<MapServer> addMapServerCommand = LispCommandWrapper.addMapServer(mapServerIpAddress);
250 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), addMapServerCommand)) {
251 lispState.addInMapServerSet(mapServerIpAddress);
253 throw new LispConfigCommandFailedException("Lisp add map server for host " + endpointHost.getHostName()
254 + " failed for ODL ip " + mapServerIpAddress);
258 private void addVniToVrfMappingIfNeeded(DataBroker vppDataBroker,
260 long vni, long vrf) throws LispConfigCommandFailedException {
261 if (!lispState.isVniConfigured(vni)) {
262 AbstractLispCommand<VniTable> addVniToVrfMapping = LispCommandWrapper.mapVniToVrf(vni, vrf);
263 addVniToVrfMapping.setOptions(General.Operations.PUT);
264 if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addVniToVrfMapping)) {
265 lispState.addInVniSet(vni);
267 throw new LispConfigCommandFailedException("Lisp add vrf " + vrf +" for vni " +vni
268 + " command failed!");
273 private void addNativeForwardPath(EndpointHost endpointHost, long vrf, IpAddress nativeForwardIp)
274 throws LispConfigCommandFailedException {
276 AbstractLispCommand<NativeForwardPath> lispCommand =
277 LispCommandWrapper.addNativeForwardEntry(vrf, nativeForwardIp);
278 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostDataBroker(), lispCommand)) {
279 LOG.debug("Added {} as native forwarding IP");
281 throw new LispConfigCommandFailedException("Lisp add Native forward failed for VNI " + vrf);
285 private void addEidInEidTable(DataBroker vppDataBroker,
288 String eidMappingName) throws LispConfigCommandFailedException {
289 AbstractLispCommand<LocalMapping> addLocalMappingInEidTableCommand = LispCommandWrapper
290 .addLocalMappingInEidTable(eidMappingName,
292 lispStateHelper.getFirstLocatorSetName(lispState),
293 lispStateHelper.getDefaultHmacKey());
294 if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addLocalMappingInEidTableCommand)) {
295 lispState.addEidInEidSet(eid);
297 throw new LispConfigCommandFailedException("Lisp add local mapping for eid " + eid + "failed!");
301 public synchronized void processDeleteEndpoint(AddressEndpointWithLocation addressEp) {
304 if (lispStateHelper.isMetadataPort(addressEp)) {
308 EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp);
310 LispState lispState = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName());
312 if (lispState == null) {
313 LOG.debug("Endpoint not configured for LISP. EndPoint: {}", addressEp);
315 long vni = getVni(addressEp.getTenant().getValue());
316 Eid eid = lispStateHelper.getEid(addressEp, vni);
317 String eidMappingName = lispStateHelper.constructEidMappingName(addressEp);
319 deleteEidFromLocalEidTableOfHostIfNeeded(endpointHost, lispState, eid, eidMappingName);
321 if (lispState.eidCount() == 0) {
322 deleteLispStatesFromHost(endpointHost);
323 deleteNativeForwardPathsTables(endpointHost);
326 } catch (LispConfigCommandFailedException e) {
327 LOG.warn("Lisp command execution failed: {}", e.getMessage());
331 private void deleteEidFromLocalEidTableOfHostIfNeeded(EndpointHost endpointHost, LispState lispState, Eid eid, String eidMappingName) throws LispConfigCommandFailedException {
332 if (lispState.eidSetContains(eid)) {
333 deleteEidFromLocalEidTableOfHost(endpointHost, lispState, eid, eidMappingName);
337 private void deleteEidFromLocalEidTableOfHost(EndpointHost endpointHost,
340 String eidMappingName) throws LispConfigCommandFailedException {
341 long value = eid.getVirtualNetworkId().getValue();
343 AbstractLispCommand<LocalMapping> deleteLocalMappingCommand = LispCommandWrapper
344 .deleteLocalMappingFromEidTable(eidMappingName, value);
346 if (LispStateCommandExecutor
347 .executeDeleteCommand(endpointHost.getHostDataBroker(), deleteLocalMappingCommand)) {
348 LOG.debug("Successfully deleted eid {} from host {}", eid, endpointHost.getHostName());
349 lispState.deleteEid(eid);
351 throw new LispConfigCommandFailedException("Lisp delete local mapping command failed!");
356 private void deleteLispStatesFromHost(EndpointHost endpointHost) throws LispConfigCommandFailedException {
357 AbstractLispCommand<LispFeatureData> deleteLispFeatureData = LispCommandWrapper.deleteLispFeatureData();
359 if (LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostDataBroker(), deleteLispFeatureData)) {
360 hostRelatedInfoContainer.deleteLispStateOfHost(endpointHost.getHostName());
361 LOG.debug("Deleted all lisp data for host {}", endpointHost.getHostName());
363 throw new LispConfigCommandFailedException("Lisp delete feature data command failed!");
367 private void deleteNativeForwardPathsTables(EndpointHost endpointHost)
368 throws LispConfigCommandFailedException {
369 AbstractLispCommand<NativeForwardPathsTables> deleteNativeForwardPathsTables = LispCommandWrapper
370 .deleteNativeForwardPathsTables();
372 if (!LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostDataBroker(),
373 deleteNativeForwardPathsTables)) {
374 throw new LispConfigCommandFailedException("Delete Native Forward Paths Tables command failed!");
378 private long getVni(String tenantUuid) {
379 return neutronTenantToVniMapper.getVni(tenantUuid);