Upgrade to the Neon base platform
[netvirt.git] / coe / impl / src / main / java / org / opendaylight / netvirt / coe / utils / CoeUtils.java
1 /*
2  * Copyright (c) 2017 - 2018 Ericsson India Global Services Pvt Ltd. and others.  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.netvirt.coe.utils;
10
11 import com.google.common.collect.ImmutableBiMap;
12
13 import java.nio.charset.StandardCharsets;
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.UUID;
18 import java.util.concurrent.ExecutionException;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22
23 import org.opendaylight.genius.infra.Datastore;
24 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
25 import org.opendaylight.genius.infra.TypedWriteTransaction;
26 import org.opendaylight.genius.mdsalutil.NwConstants;
27 import org.opendaylight.netvirt.coe.api.SouthboundInterfaceInfo;
28 import org.opendaylight.netvirt.coe.api.SouthboundInterfaceInfoBuilder;
29 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
40 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv6FamilyBuilder;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
45 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames;
46 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNamesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNamesKey;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.NetworkAttributes;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.PodidentifierInfo;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifier;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeGre;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVlan;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
93 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96
97 public final class CoeUtils {
98     private static final Logger LOG = LoggerFactory.getLogger(CoeUtils.class);
99
100     private static final String SEPARATOR = ":";
101     public static final ImmutableBiMap<NetworkAttributes.NetworkType, Class<? extends SegmentTypeBase>>
102             NETWORK_MAP =
103             new ImmutableBiMap.Builder<NetworkAttributes.NetworkType, Class<? extends SegmentTypeBase>>()
104                     .put(NetworkAttributes.NetworkType.FLAT, SegmentTypeFlat.class)
105                     .put(NetworkAttributes.NetworkType.GRE, SegmentTypeGre.class)
106                     .put(NetworkAttributes.NetworkType.VLAN, SegmentTypeVlan.class)
107                     .put(NetworkAttributes.NetworkType.VXLAN, SegmentTypeVxlan.class)
108                     .build();
109
110     private CoeUtils() { }
111
112     public static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
113         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
114                 .interfaces.Interface> id = InstanceIdentifier.builder(Interfaces.class).child(
115                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
116                         .Interface.class, new InterfaceKey(interfaceName)).build();
117         return id;
118     }
119
120     public static String buildInterfaceName(String networkNS, String podName) {
121         return new StringBuilder().append(networkNS).append(SEPARATOR).append(podName).toString();
122     }
123
124     static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
125             .Interface buildInterface(String interfaceName) {
126         IfL2vlan.L2vlanMode l2VlanMode = IfL2vlan.L2vlanMode.Trunk;
127         InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
128         IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
129         ifL2vlanBuilder.setL2vlanMode(l2VlanMode);
130
131         interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
132                 .addAugmentation(IfL2vlan.class, ifL2vlanBuilder.build());
133
134         return interfaceBuilder.build();
135     }
136
137     static ElanInstance buildElanInstance(String elanInstanceName, Class<? extends SegmentTypeBase> segmentType,
138                                            String segmentationId,
139                                            Boolean isExternal) {
140         ElanInstanceBuilder elanInstanceBuilder = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName);
141         if (segmentType != null) {
142             elanInstanceBuilder.setSegmentType(segmentType);
143             if (segmentationId != null) {
144                 elanInstanceBuilder.setSegmentationId(Long.valueOf(segmentationId));
145             }
146         }
147
148         elanInstanceBuilder.setExternal(isExternal);
149         elanInstanceBuilder.withKey(new ElanInstanceKey(elanInstanceName));
150         return elanInstanceBuilder.build();
151     }
152
153     public static void createElanInterface(String elanInterfaceName, String elanInstanceName,
154                                            TypedReadWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
155         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
156                 .class, new ElanInterfaceKey(elanInterfaceName)).build();
157         ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
158                 .setName(elanInterfaceName).withKey(new ElanInterfaceKey(elanInterfaceName)).build();
159         wrtConfigTxn.put(id, elanInterface);
160         LOG.debug("Creating new ELAN Interface {}", elanInterface);
161     }
162
163     public static void updateElanInterfaceWithStaticMac(String macAddress, IpAddress ipAddress,
164                                                         String elanInterfaceName,
165                                                         TypedReadWriteTransaction<Datastore.Configuration>
166                                                                 wrtConfigTxn) {
167         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
168                 .class, new ElanInterfaceKey(elanInterfaceName)).build();
169         PhysAddress physAddress = PhysAddress.getDefaultInstance(macAddress);
170         List<StaticMacEntries> staticMacEntriesList = new ArrayList<>();
171         StaticMacEntries staticMacEntries = new StaticMacEntriesBuilder().withKey(new StaticMacEntriesKey(
172                 physAddress)).setMacAddress(physAddress).setIpPrefix(ipAddress).build();
173         staticMacEntriesList.add(staticMacEntries);
174         ElanInterface elanInterface = new ElanInterfaceBuilder().setName(elanInterfaceName)
175                 .withKey(new ElanInterfaceKey(elanInterfaceName)).setStaticMacEntries(staticMacEntriesList).build();
176         wrtConfigTxn.merge(id, elanInterface);
177         LOG.debug("Updating ELAN Interface with static mac {}", elanInterface);
178     }
179
180     public static void createPodNameToPodUuidMap(String podName, InstanceIdentifier<Pods> pod,
181                                                  TypedWriteTransaction<Datastore.Operational> writeTransaction) {
182         InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
183                 .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
184         PodIdentifier podIdentifier = new PodIdentifierBuilder().withKey(new PodIdentifierKey(podName))
185                 .setPodName(podName).setPodUuid(pod).build();
186         writeTransaction.put(id, podIdentifier);
187         LOG.debug("Creating podnametouuid map {} to {}", podName, pod);
188     }
189
190     public static void deletePodNameToPodUuidMap(String podName,
191                                                  TypedWriteTransaction<Datastore.Operational> writeTransaction) {
192         InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
193                 .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
194         writeTransaction.delete(id);
195         LOG.debug("Deleting podnametouuid map for {}", podName);
196     }
197
198     public static InstanceIdentifier<Pods> getPodUUIDforPodName(String podName, DataBroker dataBroker)
199             throws ExecutionException, InterruptedException {
200         ReadTransaction readTransaction = dataBroker.newReadOnlyTransaction();
201         InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
202                 .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
203         InstanceIdentifier<?> instanceIdentifier = readTransaction.read(LogicalDatastoreType.OPERATIONAL, id)
204                 .get().toJavaUtil().map(PodIdentifier::getPodUuid).orElse(null);
205         if (instanceIdentifier != null) {
206             return (InstanceIdentifier<Pods>) instanceIdentifier;
207         }
208         return null;
209     }
210
211     public static void deleteElanInterface(String elanInterfaceName,
212                                            TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
213         InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
214                 .class, new ElanInterfaceKey(elanInterfaceName)).build();
215         wrtConfigTxn.delete(id);
216         LOG.debug("Deleting ELAN Interface {}", elanInterfaceName);
217     }
218
219     public static String createOfPortInterface(String interfaceName,
220                                                TypedReadWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
221         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface inf =
222                 buildInterface(interfaceName);
223         String infName = inf.getName();
224         LOG.info("Creating OFPort Interface {}", infName);
225         InstanceIdentifier interfaceIdentifier = CoeUtils.buildVlanInterfaceIdentifier(infName);
226         wrtConfigTxn.put(interfaceIdentifier, inf);
227         return infName;
228     }
229
230     public static void deleteOfPortInterface(String infName,
231                                              TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
232         LOG.debug("Deleting OFPort Interface {}", infName);
233         InstanceIdentifier interfaceIdentifier = CoeUtils.buildVlanInterfaceIdentifier(infName);
234         wrtConfigTxn.delete(interfaceIdentifier);
235     }
236
237     static InstanceIdentifier<ElanInstance> createElanInstanceIdentifier(String elanInstanceName) {
238         InstanceIdentifier<ElanInstance> id = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
239                 new ElanInstanceKey(elanInstanceName)).build();
240         return id;
241     }
242
243     public static Class<? extends SegmentTypeBase> getSegmentTypeFromNetwork(
244             org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.pod_attributes.Interface
245                     elanInterface) {
246         return CoeUtils.NETWORK_MAP.get(elanInterface.getNetworkType());
247     }
248
249     public static String buildElanInstanceName(String nodeIp, String networkNS) {
250         return new StringBuilder().append(nodeIp).append(SEPARATOR).append(networkNS).toString();
251     }
252
253     public static ElanInstance
254         createElanInstanceForTheFirstPodInTheNetwork(String networkNS, String nodeIp,
255                                                  org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod
256                                                          .rev170611.pod_attributes.Interface podInterface,
257                                                  TypedReadWriteTransaction<Datastore.Configuration> wrtConfigTxn)
258             throws ExecutionException, InterruptedException {
259         String elanInstanceName = buildElanInstanceName(nodeIp, networkNS);
260         InstanceIdentifier<ElanInstance> id = createElanInstanceIdentifier(elanInstanceName);
261         ElanInstance existingElanInstance = wrtConfigTxn.read(id).get().orNull();
262         if (existingElanInstance != null) {
263             return existingElanInstance;
264         }
265         Class<? extends SegmentTypeBase> segmentType = getSegmentTypeFromNetwork(podInterface);
266         String segmentationId = String.valueOf(podInterface.getSegmentationId());
267         //FIXME String physicalNetworkName = ??
268         // TODO external network support not added currently
269         Boolean isExternal = false;
270         ElanInstance elanInstance = CoeUtils.buildElanInstance(elanInstanceName, segmentType,
271                 segmentationId, isExternal);
272         wrtConfigTxn.put(id, elanInstance);
273         LOG.info("ELAN instance created for the first pod in the network {}", podInterface.getUid());
274         return elanInstance;
275     }
276
277     public static SouthboundInterfaceInfo getSouthboundInterfaceDetails(OvsdbTerminationPointAugmentation ovsdbTp) {
278         SouthboundInterfaceInfoBuilder southboundInterfaceInfoBuilder = new SouthboundInterfaceInfoBuilder();
279         if (ovsdbTp != null) {
280             List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
281             if (ifaceExtIds != null) {
282                 Iterator var2 = ifaceExtIds.iterator();
283                 while (var2.hasNext()) {
284                     InterfaceExternalIds entry = (InterfaceExternalIds)var2.next();
285                     if (entry.getExternalIdKey().equals("iface-id")) {
286                         southboundInterfaceInfoBuilder.setInterfaceName(entry.getExternalIdValue());
287                         continue;
288                     }
289                     if (entry.getExternalIdKey().equals("attached-mac")) {
290                         southboundInterfaceInfoBuilder.setMacAddress(entry.getExternalIdValue());
291                         continue;
292                     }
293                     if (entry.getExternalIdKey().equals("ip-address")) {
294                         southboundInterfaceInfoBuilder.setNodeIp(entry.getExternalIdValue());
295                         continue;
296                     }
297                     if (entry.getExternalIdKey().equals("is-service-gateway")) {
298                         southboundInterfaceInfoBuilder.setIsServiceGateway(true);
299                         continue;
300                     }
301                 }
302             }
303         }
304
305         return southboundInterfaceInfoBuilder.build();
306     }
307
308     public static InstanceIdentifier<PodIdentifier> getPodMetaInstanceId(String externalInterfaceId) {
309         return InstanceIdentifier.builder(PodidentifierInfo.class)
310                 .child(PodIdentifier.class, new PodIdentifierKey(externalInterfaceId)).build();
311     }
312
313     public static void createVpnInstance(String vpnName, List<String> rd, List<String> irt, List<String> ert,
314                                          VpnInstance.Type type, long l3vni, IpVersionChoice ipVersion,
315                                          TypedReadWriteTransaction<Datastore.Configuration> tx) {
316         List<VpnTarget> vpnTargetList = new ArrayList<>();
317         LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
318
319         VpnInstanceBuilder builder = new VpnInstanceBuilder().withKey(new VpnInstanceKey(vpnName))
320                 .setVpnInstanceName(vpnName)
321                 .setType(type).setL3vni(l3vni);
322         if (irt != null && !irt.isEmpty()) {
323             if (ert != null && !ert.isEmpty()) {
324                 List<String> commonRT = new ArrayList<>(irt);
325                 commonRT.retainAll(ert);
326
327                 for (String common : commonRT) {
328                     irt.remove(common);
329                     ert.remove(common);
330                     VpnTarget vpnTarget =
331                             new VpnTargetBuilder().withKey(new VpnTargetKey(common)).setVrfRTValue(common)
332                                     .setVrfRTType(VpnTarget.VrfRTType.Both).build();
333                     vpnTargetList.add(vpnTarget);
334                 }
335             }
336             for (String importRT : irt) {
337                 VpnTarget vpnTarget =
338                         new VpnTargetBuilder().withKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
339                                 .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
340                 vpnTargetList.add(vpnTarget);
341             }
342         }
343
344         if (ert != null && !ert.isEmpty()) {
345             for (String exportRT : ert) {
346                 VpnTarget vpnTarget =
347                         new VpnTargetBuilder().withKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
348                                 .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
349                 vpnTargetList.add(vpnTarget);
350             }
351         }
352
353         VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
354
355         Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
356         Ipv6FamilyBuilder ipv6vpnBuilder = new Ipv6FamilyBuilder().setVpnTargets(vpnTargets);
357
358         if (rd != null && !rd.isEmpty()) {
359             ipv4vpnBuilder.setRouteDistinguisher(rd);
360             ipv6vpnBuilder.setRouteDistinguisher(rd);
361         }
362
363         if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
364             builder.setIpv4Family(ipv4vpnBuilder.build());
365         }
366         if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
367             builder.setIpv6Family(ipv6vpnBuilder.build());
368         }
369         if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.UNDEFINED)) {
370             builder.setIpv4Family(ipv4vpnBuilder.build());
371         }
372         VpnInstance newVpn = builder.build();
373         LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
374         InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
375                 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
376         tx.put(vpnIdentifier, newVpn);
377     }
378
379     static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
380         InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).child(VpnInterface
381                 .class, new VpnInterfaceKey(ifName)).build();
382         return id;
383     }
384
385     public static void createVpnInterface(String vpnName, Pods pod, String interfaceName, String macAddress,
386                                           boolean isRouterInterface,
387                                           TypedReadWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
388         LOG.trace("createVpnInterface for Port: {}, isRouterInterface: {}", interfaceName, isRouterInterface);
389         List<VpnInstanceNames> listVpn = new ArrayList<>();
390         listVpn.add(new VpnInstanceNamesBuilder().withKey(new VpnInstanceNamesKey(vpnName))
391                 .setVpnName(vpnName).setAssociatedSubnetType(VpnInstanceNames.AssociatedSubnetType
392                         .V4Subnet).build());
393         VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().withKey(new VpnInterfaceKey(interfaceName))
394                 .setName(interfaceName)
395                 .setVpnInstanceNames(listVpn)
396                 .setRouterInterface(isRouterInterface);
397         Adjacencies adjs = createPortIpAdjacencies(pod, interfaceName, macAddress);
398         if (adjs != null) {
399             vpnb.addAugmentation(Adjacencies.class, adjs);
400         }
401         VpnInterface vpnIf = vpnb.build();
402         LOG.info("Creating vpn interface {}", vpnIf);
403         InstanceIdentifier<VpnInterface> vpnIfIdentifier = buildVpnInterfaceIdentifier(interfaceName);
404         wrtConfigTxn.put(vpnIfIdentifier, vpnIf);
405
406     }
407
408     public static void deleteVpnInterface(String interfaceName,
409                                           TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
410         LOG.trace("deleteVpnInterface for Pod {}", interfaceName);
411         InstanceIdentifier<VpnInterface> vpnIfIdentifier = buildVpnInterfaceIdentifier(interfaceName);
412         wrtConfigTxn.delete(vpnIfIdentifier);
413     }
414
415     static Adjacencies createPortIpAdjacencies(Pods pod, String interfaceName, String macAddress) {
416         List<Adjacency> adjList = new ArrayList<>();
417         LOG.trace("create config adjacencies for Port: {}", interfaceName);
418         IpAddress ip = pod.getInterface().get(0).getIpAddress();
419         String ipValue = ip.getIpv4Address() != null ? ip.getIpv4Address().getValue() : ip.getIpv6Address().getValue();
420         String ipPrefix = ip.getIpv4Address() != null ? ipValue + "/32" : ipValue + "/128";
421         String hostIp = pod.getHostIpAddress().stringValue();
422         UUID subnetId = UUID.nameUUIDFromBytes(hostIp.getBytes(StandardCharsets.UTF_8));
423         String gatewayIP = ipValue.replaceFirst("\\d+$", "1");
424         Adjacency vmAdj = new AdjacencyBuilder().withKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
425                 .setMacAddress(macAddress).setAdjacencyType(Adjacency.AdjacencyType.PrimaryAdjacency)
426                 .setSubnetId(new Uuid(subnetId.toString())).setSubnetGatewayIp(gatewayIP).build();
427         if (!adjList.contains(vmAdj)) {
428             adjList.add(vmAdj);
429         }
430
431         //if (isRouterInterface) {
432             // TODO
433             // create extraroute Adjacence for each ipValue,
434             // because router can have IPv4 and IPv6 subnet ports, or can have
435             // more that one IPv4 subnet port or more than one IPv6 subnet port
436             //List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
437             //if (!erAdjList.isEmpty()) {
438             //    adjList.addAll(erAdjList);
439             //}
440         //}
441         return new AdjacenciesBuilder().setAdjacency(adjList).build();
442     }
443
444     public static InstanceIdentifier<BoundServices> buildKubeProxyServicesIId(String interfaceName) {
445         return InstanceIdentifier.builder(ServiceBindings.class)
446                 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, ServiceModeIngress.class))
447                 .child(BoundServices.class, new BoundServicesKey(NwConstants.COE_KUBE_PROXY_SERVICE_INDEX)).build();
448     }
449
450     public static void unbindKubeProxyService(String interfaceName, TypedWriteTransaction<Datastore.Configuration> tx) {
451         tx.delete(buildKubeProxyServicesIId(interfaceName));
452     }
453 }