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