Fix metadata for route, arp and overlay
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / lisp / LispStateManager.java
1 /*
2  * Copyright (c) 2017 Cisco Systems. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp;
10
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.mappers.NeutronTenantToVniMapper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.feature.data.grouping.GpeFeatureData;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.Lisp;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.LocalMapping;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.eid.table.grouping.eid.table.VniTable;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.lisp.feature.data.grouping.LispFeatureData;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.locator.sets.grouping.locator.sets.LocatorSet;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.register.grouping.MapRegister;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.resolvers.grouping.map.resolvers.MapResolver;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.map.servers.grouping.map.servers.MapServer;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import javax.annotation.Nonnull;
38 import java.util.HashMap;
39 import java.util.concurrent.ExecutionException;
40
41 /**
42  * Created by Shakib Ahmed on 3/29/17.
43  */
44 public class LispStateManager {
45     private static final Logger LOG = LoggerFactory.getLogger(LispStateManager.class);
46
47     private HashMap<String, LispState> lispStateMapper;
48     private MountedDataBrokerProvider mountedDataBrokerProvider;
49     private ConfigManagerHelper lispStateHelper;
50
51     private NeutronTenantToVniMapper neutronTenantToVniMapper;
52
53     private static final short DEFAULT_PRIORITY = 1;
54     private static final short DEFAULT_WEIGHT = 1;
55     public static final String DEFAULT_XTR_KEY = "admin";
56     public static final String DEFAULT_LOCATOR_SET_NAME_PREFIX = "LS";
57     public static final String DEFAULT_MAPPINGRECORD_NAME_PREFIX = "MR";
58
59     public LispStateManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
60         Preconditions.checkNotNull(mountedDataBrokerProvider,
61                 "MountedDataBrokerProvider found to be null!");
62         lispStateMapper = new HashMap<>();
63         this.mountedDataBrokerProvider= mountedDataBrokerProvider;
64         this.lispStateHelper = new ConfigManagerHelper(this.mountedDataBrokerProvider);
65         neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
66     }
67
68     public synchronized void configureEndPoint(AddressEndpointWithLocation addressEp) {
69         try {
70             if (lispStateHelper.isMetadataPort(addressEp)) {
71                 return;
72             }
73             DataBroker dataBroker = lispStateHelper.getPotentialExternalDataBroker(addressEp).get();
74             String hostName = lispStateHelper.getHostName(addressEp).get();
75             LispState lispStateOfNode = configureHostIfNeeded(hostName, dataBroker);
76
77             long vni = getVni(addressEp.getTenant().getValue());
78             long vrf = vni;
79             addVniToVrfMappingIfNeeded(dataBroker, lispStateOfNode, vni, vrf);
80
81             Eid eid = lispStateHelper.getEid(addressEp, vni);
82
83             if(!lispStateOfNode.eidSetContains(eid)) {
84                 addEidInEidTable(dataBroker, lispStateOfNode, eid);
85             }
86
87         } catch (LispConfigCommandFailedException e) {
88             LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp);
89         }
90     }
91
92     public synchronized LispState configureHostIfNeeded(String hostName, DataBroker vppDataBroker) throws LispConfigCommandFailedException {
93         LispState lispStateOfNode = lispStateMapper.get(hostName);
94
95         if (lispStateOfNode == null) {
96             lispStateOfNode = new LispState(hostName);
97             try {
98                 enableLispForNode(vppDataBroker, lispStateOfNode);
99
100                 if (ConfigUtil.getInstance().isL3FlatEnabled()) {
101                     enableGpeForNode(vppDataBroker, lispStateOfNode);
102                 }
103
104                 addLocatorSet(vppDataBroker, lispStateOfNode);
105                 addMapResolver(vppDataBroker, lispStateOfNode);
106                 if (ConfigUtil.getInstance().isLispMapRegisterEnabled()) {
107                     enableMapRegister(vppDataBroker, lispStateOfNode);
108                     addMapServer(vppDataBroker, lispStateOfNode);
109                 }
110                 lispStateMapper.put(hostName, lispStateOfNode);
111             } catch (LispNotFoundException e) {
112                 LOG.warn("Lisp host configuration failed: ", e.getMessage());
113                 throw new LispConfigCommandFailedException("Failed LISP configuration!");
114             }
115         }
116         return lispStateOfNode;
117     }
118
119     public synchronized void deleteLispConfigurationForEndpoint(AddressEndpointWithLocation addressEp) {
120         try {
121             DataBroker vppDataBroker = lispStateHelper.getPotentialExternalDataBroker(addressEp).get();
122             String hostName = lispStateHelper.getHostName(addressEp).get();
123
124             LispState lispState = lispStateMapper.get(hostName);
125
126             if (lispState == null) {
127                 LOG.debug("Endpoint not configured for LISP. EndPoint: {}", addressEp);
128             } else {
129                 long vni = getVni(addressEp.getTenant().getValue());
130                 Eid eid = lispStateHelper.getEid(addressEp, vni);
131
132                 if (lispState.eidSetContains(eid)) {
133                     deleteEidFromEidTable(vppDataBroker, lispState, eid);
134                 }
135
136                 if (lispState.eidCount() == 0) {
137                     deleteLispStatesInEndPoints(vppDataBroker, lispState);
138                 }
139             }
140         } catch (LispConfigCommandFailedException e) {
141             LOG.warn("Lisp command execution failed: {}", e.getMessage());
142         }
143     }
144
145     private void enableLispForNode(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
146         AbstractLispCommand<Lisp>
147                 lispEnableCommand = LispCommandWrapper.enableLisp();
148         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, lispEnableCommand)) {
149             lispState.setLispEnabled(true);
150         } else {
151             throw new LispConfigCommandFailedException("Lisp Enable Command failed execution!");
152         }
153     }
154
155     private void enableGpeForNode(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
156         AbstractLispCommand<GpeFeatureData>
157                 gpeEnableCommand = LispCommandWrapper.enableGpe();
158         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, gpeEnableCommand)) {
159             lispState.setGpeEnabled(true);
160         } else {
161             throw new LispConfigCommandFailedException("GPE Enable Command failed execution!");
162         }
163     }
164
165     private void addLocatorSet(DataBroker vppDataBroker, LispState lispState) throws LispNotFoundException, LispConfigCommandFailedException {
166         try {
167             String locatorSetName = lispStateHelper.constructLocatorSetName(lispState.getLocatorCount());
168             String interfaceName = lispStateHelper.readRlocInterface(lispState.getHostName(), vppDataBroker).get();
169             AbstractLispCommand<LocatorSet> addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName,
170                     interfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT);
171             if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addLocatorSetCommand)) {
172                 lispState.setLocIntfToLocSetNameMapping(interfaceName, locatorSetName);
173             } else {
174                 throw new LispConfigCommandFailedException("Lisp add locator set failed for host "
175                         + lispState.getHostName() + " and locator interface " + interfaceName);
176             }
177         } catch (InterruptedException | ExecutionException e) {
178             throw new LispNotFoundException("No interface with Ip Address found!");
179         }
180
181     }
182
183     private void addMapResolver(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
184         IpAddress mapResolverIpAddress = ConfigUtil.getInstance().getOdlTenantIp();
185         Preconditions.checkNotNull(mapResolverIpAddress, "Map Resolver ip not properly configured!");
186
187         AbstractLispCommand<MapResolver> addMapResolverCommand = LispCommandWrapper.
188                 addMapResolver(mapResolverIpAddress);
189         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addMapResolverCommand)) {
190             lispState.addInMapResolverSet(mapResolverIpAddress);
191         } else {
192             throw new LispConfigCommandFailedException("Lisp add map resolver for host " + lispState.getHostName()
193                     + " failed for ODL ip " + mapResolverIpAddress);
194         }
195     }
196
197     private void addMapServer(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
198         IpAddress mapServerIpAddress = ConfigUtil.getInstance().getOdlTenantIp();
199         Preconditions.checkNotNull(mapServerIpAddress, "Mapserver ip not properly configured!");
200         AbstractLispCommand<MapServer> addMapServerCommand = LispCommandWrapper.addMapServer(mapServerIpAddress);
201
202         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addMapServerCommand)) {
203             lispState.addInMapServerSet(mapServerIpAddress);
204         } else {
205             throw new LispConfigCommandFailedException("Lisp add map server for host " + lispState.getHostName()
206                     + " failed for ODL ip " + mapServerIpAddress);
207         }
208     }
209
210     private void enableMapRegister(DataBroker vppDataBroker, LispState lispState) throws LispConfigCommandFailedException {
211         AbstractLispCommand<MapRegister> enableMapRegisterCommand = LispCommandWrapper.enableMapRegister();
212
213         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, enableMapRegisterCommand)) {
214             lispState.setMapRegisteredEnabled(true);
215         } else {
216             throw new LispConfigCommandFailedException("Lisp enable mapregistration for host "
217                     + lispState.getHostName() + " failed!");
218         }
219
220     }
221
222     private void addVniToVrfMappingIfNeeded(DataBroker vppDataBroker,
223                                             LispState lispState,
224                                             long vni, long vrf) throws LispConfigCommandFailedException {
225         if (!lispState.vniSetContains(vni)) {
226             AbstractLispCommand<VniTable> addVniToVrfMapping = LispCommandWrapper.mapVniToVrf(vni, vrf);
227             addVniToVrfMapping.setOptions(General.Operations.PUT);
228             if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addVniToVrfMapping)) {
229                 lispState.addInVniSet(vni);
230             } else {
231                 throw new LispConfigCommandFailedException("Lisp add vrf " + vrf +" for vni " +vni
232                         + " command failed!");
233             }
234         }
235     }
236
237     private void addEidInEidTable(DataBroker vppDataBroker,
238                                   LispState lispState,
239                                   Eid eid) throws LispConfigCommandFailedException {
240         String mappingId = lispStateHelper.constructMappingName(lispState.getInterfaceId());
241         AbstractLispCommand<LocalMapping> addLocalMappingInEidTableCommand = LispCommandWrapper
242                 .addLocalMappingInEidTable(mappingId,
243                         eid,
244                         lispStateHelper.getFirstLocatorSetName(lispState),
245                         lispStateHelper.getDefaultHmacKey());
246         if (LispStateCommandExecutor.executePutCommand(vppDataBroker, addLocalMappingInEidTableCommand)) {
247             lispState.addInEidSet(eid, mappingId);
248         } else {
249             throw new LispConfigCommandFailedException("Lisp add local mapping for eid " + eid + "failed!");
250         }
251     }
252
253     private void deleteLispStatesInEndPoints(DataBroker vppDataBroker,
254                                              LispState lispState) throws LispConfigCommandFailedException {
255         AbstractLispCommand<LispFeatureData> deleteLispFeatureData = LispCommandWrapper.deleteLispFeatureData();
256
257         if (LispStateCommandExecutor.executeDeleteCommand(vppDataBroker, deleteLispFeatureData)) {
258             String computeNode = lispState.getHostName();
259             lispStateMapper.remove(computeNode);
260         } else {
261             throw new LispConfigCommandFailedException("Lisp delete feature data command failed!");
262         }
263     }
264
265     private void deleteEidFromEidTable(DataBroker vppDataBroker,
266                                        LispState lispState,
267                                        Eid eid) throws LispConfigCommandFailedException {
268         String mappingId = lispState.getEidMapping(eid);
269         long value = eid.getVirtualNetworkId().getValue();
270
271         AbstractLispCommand<LocalMapping> deleteLocalMappingCommand = LispCommandWrapper
272                 .deleteLocalMappingFromEidTable(mappingId, value);
273
274         if (LispStateCommandExecutor.executeDeleteCommand(vppDataBroker, deleteLocalMappingCommand)) {
275             lispState.deleteEid(eid);
276         } else {
277             throw new LispConfigCommandFailedException("Lisp delete local mapping command failed!");
278         }
279     }
280
281     private long getVni(String tenantUuid) {
282         return neutronTenantToVniMapper.getVni(tenantUuid);
283     }
284 }