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;
13 import java.util.concurrent.ExecutionException;
15 import javax.annotation.Nonnull;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.AbstractLispCommand;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.LispCommandWrapper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.LispState;
25 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PhysicalInterfaces;
26 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
27 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
28 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants;
29 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.NativeForwardPathsTables;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801._native.forward.paths.tables._native.forward.paths.table.NativeForwardPath;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.gpe.feature.data.grouping.GpeFeatureData;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.Lisp;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.dp.subtable.grouping.local.mappings.LocalMapping;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.dp.subtable.grouping.local.mappings.local.mapping.Eid;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.eid.table.grouping.eid.table.VniTable;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.itr.remote.locator.sets.grouping.ItrRemoteLocatorSet;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.lisp.feature.data.grouping.LispFeatureData;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.locator.sets.grouping.locator.sets.LocatorSet;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.register.grouping.MapRegister;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.resolvers.grouping.map.resolvers.MapResolver;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.servers.grouping.map.servers.MapServer;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 public class LispStateManager {
49 private static final Logger LOG = LoggerFactory.getLogger(LispStateManager.class);
51 private HostRelatedInfoContainer hostRelatedInfoContainer;
52 private MountedDataBrokerProvider mountedDataBrokerProvider;
53 private ConfigManagerHelper lispStateHelper;
55 private NeutronTenantToVniMapper neutronTenantToVniMapper;
57 private static final short DEFAULT_PRIORITY = 1;
58 private static final short DEFAULT_WEIGHT = 1;
59 public static final String DEFAULT_XTR_KEY = "admin";
60 public static final String DEFAULT_LOCATOR_SET_NAME_PREFIX = "LS";
61 public static final String DEFAULT_MAPPING_RECORD_NAME_PREFIX = "MR_";
63 public LispStateManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
64 Preconditions.checkNotNull(mountedDataBrokerProvider,
65 "MountedDataBrokerProvider found to be null!");
66 hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance();
67 this.mountedDataBrokerProvider= mountedDataBrokerProvider;
68 this.lispStateHelper = new ConfigManagerHelper(this.mountedDataBrokerProvider);
69 neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
72 public synchronized void processCreateEndPoint(AddressEndpointWithLocation addressEp) {
74 if (lispStateHelper.isMetadataPort(addressEp)) {
77 EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp);
78 LispState lispStateOfHost = configureHostIfNeeded(endpointHost);
80 long vni = getVni(addressEp.getTenant().getValue());
83 Eid eid = lispStateHelper.getEid(addressEp, vni);
84 String eidMappingName = lispStateHelper.constructEidMappingName(addressEp);
86 addVniSpecificConfigurationsIfNeeded(endpointHost, lispStateOfHost, vni, vrf);
88 if (lispStateHelper.getInterfaceIp(addressEp).getValue().equals(Constants.METADATA_IP)) {
92 addEidOnHostIfNeeded(endpointHost, lispStateOfHost, eid, eidMappingName);
93 } catch (LispConfigCommandFailedException e) {
94 LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp);
98 private void addEidOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfNode, Eid eid,
99 String eidMappingName)
100 throws LispConfigCommandFailedException {
101 if(!lispStateOfNode.eidSetContains(eid)) {
102 addEidInEidTable(endpointHost, lispStateOfNode, eid, eidMappingName);
106 private synchronized LispState configureHostIfNeeded(EndpointHost endpointHost)
107 throws LispConfigCommandFailedException {
108 LispState lispStateOfHost = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName());
110 if (lispStateOfHost == null) {
111 LOG.debug("Configuring host {} for LISP", endpointHost.getHostName());
112 lispStateOfHost = new LispState();
114 enableLispOnHost(endpointHost, lispStateOfHost);
115 enableGpeOnHostIfNeeded(endpointHost, lispStateOfHost);
116 addLocatorSetOnHost(endpointHost, lispStateOfHost);
117 addMapResolverOnHost(endpointHost, lispStateOfHost);
118 enableMapRegistrationOnHostIfNeeded(endpointHost, lispStateOfHost);
120 hostRelatedInfoContainer.setLispStateOfHost(endpointHost.getHostName(), lispStateOfHost);
121 } catch (LispNotFoundException e) {
122 LOG.warn("Lisp host configuration failed: ", e.getMessage());
123 throw new LispConfigCommandFailedException("Failed LISP configuration!");
126 return lispStateOfHost;
129 private void enableGpeOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost)
130 throws LispConfigCommandFailedException {
131 if (ConfigUtil.getInstance().isL3FlatEnabled()) {
132 enableGpeForHost(endpointHost, lispStateOfHost);
136 private void enableMapRegistrationOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost)
137 throws LispConfigCommandFailedException {
138 if (ConfigUtil.getInstance().isLispMapRegisterEnabled()) {
139 enableMapRegister(endpointHost);
140 addMapServer(endpointHost, lispStateOfHost);
144 private void enableLispOnHost(EndpointHost endpointHost, LispState lispState)
145 throws LispConfigCommandFailedException {
146 LOG.debug("Enabling LISP on host {}", endpointHost.getHostName());
147 AbstractLispCommand<Lisp> lispEnableCommand = LispCommandWrapper.enableLisp();
148 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), lispEnableCommand)) {
149 lispState.setLispEnabled(true);
151 throw new LispConfigCommandFailedException("Lisp Enable Command failed execution!");
155 private void enableGpeForHost(EndpointHost endpointHost, LispState lispState)
156 throws LispConfigCommandFailedException {
157 AbstractLispCommand<GpeFeatureData> gpeEnableCommand = LispCommandWrapper.enableGpe();
158 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), gpeEnableCommand)) {
159 lispState.setGpeEnabled(true);
161 throw new LispConfigCommandFailedException("GPE Enable Command failed execution!");
165 private void addLocatorSetOnHost(EndpointHost endpointHost, LispState lispState)
166 throws LispNotFoundException, LispConfigCommandFailedException {
168 String locatorSetName = lispStateHelper.constructLocatorSetName(lispState.getLocatorCount());
169 String lispDataInterfaceName = lispStateHelper
170 .getLispDataRlocInterfaceName(endpointHost.getHostName()).get();
171 AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
172 lispDataInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
173 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocatorSetCommand)) {
174 lispState.setLocIntfToLocSetNameMapping(lispDataInterfaceName, locatorSetName);
176 throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
177 + endpointHost.getHostName() + " and locator interface " + lispDataInterfaceName);
180 addExtraItrRlocLocatorSetIfNeeded(endpointHost, lispDataInterfaceName);
181 } catch (InterruptedException | ExecutionException e) {
182 throw new LispNotFoundException("No interface with Ip Address found!");
186 private void addExtraItrRlocLocatorSetIfNeeded(EndpointHost endpointHost, String lispDataInterfaceName)
187 throws LispNotFoundException, LispConfigCommandFailedException {
188 String lispCpRlocInterfaceName = lispStateHelper.getLispCpRlocInterfaceName(endpointHost);
189 if (lispCpRlocInterfaceName == null
190 || lispCpRlocInterfaceName.isEmpty()
191 || lispCpRlocInterfaceName.equals(lispDataInterfaceName)) {
195 addItrLocatorSet(endpointHost, lispCpRlocInterfaceName);
198 private void addItrLocatorSet(EndpointHost endpointHost, String lispCpInterfaceName)
199 throws LispNotFoundException, LispConfigCommandFailedException {
200 String locatorSetName = lispStateHelper.constructLocatorSetNameForItrRloc();
201 AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
202 lispCpInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
203 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocatorSetCommand)) {
204 throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
205 + endpointHost.getHostName() + " and locator interface " + lispCpInterfaceName);
208 AbstractLispCommand<ItrRemoteLocatorSet> addItrRlocCommand = LispCommandWrapper.addItrRloc(locatorSetName);
209 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addItrRlocCommand)) {
210 throw new LispConfigCommandFailedException("Lisp add Itr Rloc command failed for host "
211 + endpointHost.getHostName() + " and locator set " + locatorSetName);
215 private void addMapResolverOnHost(EndpointHost endpointHost, LispState lispState)
216 throws LispConfigCommandFailedException {
217 IpAddress mapResolverIpAddress = ConfigUtil.getInstance().getOdlIp();
218 Preconditions.checkNotNull(mapResolverIpAddress, "Map Resolver ip not properly configured!");
220 AbstractLispCommand<MapResolver> addMapResolverCommand = LispCommandWrapper.
221 addMapResolver(mapResolverIpAddress);
222 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addMapResolverCommand)) {
223 lispState.addInMapResolverSet(mapResolverIpAddress);
225 throw new LispConfigCommandFailedException("Lisp add map resolver for host " + endpointHost.getHostName()
226 + " failed for ODL ip " + mapResolverIpAddress);
230 private void enableMapRegister(EndpointHost endpointHost)
231 throws LispConfigCommandFailedException {
232 AbstractLispCommand<MapRegister> enableMapRegisterCommand = LispCommandWrapper.enableMapRegister();
234 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), enableMapRegisterCommand)) {
235 throw new LispConfigCommandFailedException("Lisp enable mapregistration for host "
236 + endpointHost.getHostName() + " failed!");
241 private void addMapServer(EndpointHost endpointHost, LispState lispState) throws LispConfigCommandFailedException {
242 IpAddress mapServerIpAddress = ConfigUtil.getInstance().getOdlIp();
243 Preconditions.checkNotNull(mapServerIpAddress, "Mapserver ip not properly configured!");
244 AbstractLispCommand<MapServer> addMapServerCommand = LispCommandWrapper.addMapServer(mapServerIpAddress);
246 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addMapServerCommand)) {
247 lispState.addInMapServerSet(mapServerIpAddress);
249 throw new LispConfigCommandFailedException("Lisp add map server for host " + endpointHost.getHostName()
250 + " failed for ODL ip " + mapServerIpAddress);
254 private void addVniSpecificConfigurationsIfNeeded(EndpointHost endpointHost,
256 long vni, long vrf) throws LispConfigCommandFailedException {
257 if (!lispState.isVniConfigured(vni)) {
258 addVniToVrfMapping(endpointHost, lispState, vni, vrf);
259 addGpeNativeForwardPath(endpointHost, vrf,
260 hostRelatedInfoContainer.getPhysicalInterfaceState(endpointHost.getHostName())
261 .getIp(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC));
265 private void addVniToVrfMapping(EndpointHost endpointHost,
267 long vni, long vrf) throws LispConfigCommandFailedException {
268 AbstractLispCommand<VniTable> addVniToVrfMapping = LispCommandWrapper.mapVniToVrf(vni, vrf);
269 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addVniToVrfMapping)) {
270 lispState.addInVniSet(vni);
272 throw new LispConfigCommandFailedException("Lisp add vrf " + vrf +" for vni " +vni
273 + " command failed!");
277 private void addGpeNativeForwardPath(EndpointHost endpointHost,
278 long vrf, IpAddress nativeForwardIp) throws LispConfigCommandFailedException {
279 AbstractLispCommand<NativeForwardPath> addNativeForwardingIp =
280 LispCommandWrapper.addNativeForwardEntry(vrf, nativeForwardIp);
281 if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addNativeForwardingIp)) {
282 throw new LispConfigCommandFailedException("Lisp add native forwarding to ip " + addNativeForwardingIp
283 + " for vrf " + vrf + " command failed!");
287 private void addEidInEidTable(EndpointHost endpointHost,
290 String eidMappingName) throws LispConfigCommandFailedException {
291 AbstractLispCommand<LocalMapping> addLocalMappingInEidTableCommand = LispCommandWrapper
292 .addLocalMappingInEidTable(eidMappingName,
294 lispStateHelper.getFirstLocatorSetName(lispState),
295 lispStateHelper.getDefaultHmacKey());
296 if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocalMappingInEidTableCommand)) {
297 lispState.addEidInEidSet(eid);
299 throw new LispConfigCommandFailedException("Lisp add local mapping for eid " + eid + "failed!");
303 public synchronized void processDeleteEndpoint(AddressEndpointWithLocation addressEp) {
306 if (lispStateHelper.isMetadataPort(addressEp)) {
310 EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp);
312 LispState lispState = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName());
314 if (lispState == null) {
315 LOG.debug("Endpoint not configured for LISP. EndPoint: {}", addressEp);
317 long vni = getVni(addressEp.getTenant().getValue());
318 Eid eid = lispStateHelper.getEid(addressEp, vni);
319 String eidMappingName = lispStateHelper.constructEidMappingName(addressEp);
321 deleteEidFromLocalEidTableOfHostIfNeeded(endpointHost, lispState, eid, eidMappingName);
323 if (lispState.eidCount() == 0) {
324 deleteLispStatesFromHost(endpointHost);
325 deleteNativeForwardPathsTables(endpointHost);
328 } catch (LispConfigCommandFailedException e) {
329 LOG.warn("Lisp command execution failed: {}", e.getMessage());
333 private void deleteEidFromLocalEidTableOfHostIfNeeded(EndpointHost endpointHost, LispState lispState, Eid eid,
334 String eidMappingName) throws LispConfigCommandFailedException {
335 if (lispState.eidSetContains(eid)) {
336 deleteEidFromLocalEidTableOfHost(endpointHost, lispState, eid, eidMappingName);
340 private void deleteEidFromLocalEidTableOfHost(EndpointHost endpointHost,
343 String eidMappingName) throws LispConfigCommandFailedException {
344 long value = eid.getVirtualNetworkId().getValue();
346 AbstractLispCommand<LocalMapping> deleteLocalMappingCommand = LispCommandWrapper
347 .deleteLocalMappingFromEidTable(eidMappingName, value);
349 if (LispStateCommandExecutor
350 .executeDeleteCommand(endpointHost.getHostName(), deleteLocalMappingCommand)) {
351 LOG.debug("Successfully deleted eid {} from host {}", eid, endpointHost.getHostName());
352 lispState.deleteEid(eid);
354 throw new LispConfigCommandFailedException("Lisp delete local mapping command failed!");
359 private void deleteLispStatesFromHost(EndpointHost endpointHost) throws LispConfigCommandFailedException {
360 AbstractLispCommand<LispFeatureData> deleteLispFeatureData = LispCommandWrapper.deleteLispFeatureData();
362 if (LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostName(), deleteLispFeatureData)) {
363 hostRelatedInfoContainer.deleteLispStateOfHost(endpointHost.getHostName());
364 LOG.debug("Deleted all lisp data for host {}", endpointHost.getHostName());
366 throw new LispConfigCommandFailedException("Lisp delete feature data command failed!");
370 private void deleteNativeForwardPathsTables(EndpointHost endpointHost)
371 throws LispConfigCommandFailedException {
372 AbstractLispCommand<NativeForwardPathsTables> deleteNativeForwardPathsTables = LispCommandWrapper
373 .deleteNativeForwardPathsTables();
375 if (!LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostName(),
376 deleteNativeForwardPathsTables)) {
377 throw new LispConfigCommandFailedException("Delete Native Forward Paths Tables command failed!");
381 private long getVni(String tenantUuid) {
382 return neutronTenantToVniMapper.getVni(tenantUuid);