2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. 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.unimgr.mef.netvirt;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.UUID;
17 import org.apache.commons.net.util.SubnetUtils;
18 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
25 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddressBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
80 import com.google.common.base.Optional;
82 public class NetvirtVpnUtils {
83 private static final Logger logger = LoggerFactory.getLogger(NetvirtVpnUtils.class);
84 private final static String ELAN_PREFIX = "elan.";
85 private final static String IP_ADDR_SUFFIX = "/32";
86 private final static String IP_MUSK_SEPARATOR = "/";
88 public static void createVpnInstance(DataBroker dataBroker, String instanceName) {
89 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
90 createVpnInstance(instanceName, tx);
91 MdsalUtils.commitTransaction(tx);
94 public static void createVpnInstance(String instanceName, WriteTransaction tx) {
95 VpnInstanceBuilder builder = new VpnInstanceBuilder();
96 builder.setVpnInstanceName(instanceName);
97 Ipv4FamilyBuilder ipv4FamilyBuilder = new Ipv4FamilyBuilder();
98 VpnTargetsBuilder vpnTargetsB = new VpnTargetsBuilder();
99 vpnTargetsB.setVpnTarget(new ArrayList<VpnTarget>());
100 ipv4FamilyBuilder.setVpnTargets(vpnTargetsB.build());
102 // WA till netvirt will allow creation of VPN without RD
103 UUID vpnId = UUID.fromString(instanceName);
104 String rd = String.valueOf(Math.abs(vpnId.getLeastSignificantBits()));
105 ipv4FamilyBuilder.setRouteDistinguisher(rd);
106 builder.setIpv4Family(ipv4FamilyBuilder.build());
108 tx.put(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName), builder.build());
111 public static void removeVpnInstance(String instanceName, WriteTransaction tx) {
112 tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName));
115 private static InstanceIdentifier<VpnInstance> getVpnInstanceInstanceIdentifier(String instanceName) {
116 return InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(instanceName))
120 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(
122 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
123 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
124 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(
129 public static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String rd) {
130 return InstanceIdentifier.builder(VpnInstanceOpData.class)
131 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
134 public static void createUpdateVpnInterface(DataBroker dataBroker, String vpnName, String interfaceName,
135 String ifAddr, String macAddress, boolean primary, String gwIpAddress, String directSubnetId) {
136 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
137 createUpdateVpnInterface(vpnName, interfaceName, ifAddr, macAddress, primary, gwIpAddress, directSubnetId, tx);
138 MdsalUtils.commitTransaction(tx);
141 public static void createUpdateVpnInterface(String vpnName, String interfaceName, IpPrefix ifPrefix,
142 String macAddress, boolean primary, IpPrefix gwIpAddress, String directSubnetId, WriteTransaction tx) {
143 synchronized (interfaceName.intern()) {
144 String ipAddress = null;
145 String nextHopIp = null;
147 ipAddress = getAddressFromSubnet(ipPrefixToString(ifPrefix));
149 ipAddress = ipPrefixToString(ifPrefix);
150 nextHopIp = getIpAddressFromPrefix(ipPrefixToString(gwIpAddress));
152 createUpdateVpnInterface(vpnName, interfaceName, ipAddress, macAddress, primary, nextHopIp, directSubnetId,
157 public static void createUpdateVpnInterface(String vpnName, String interfaceName, String ipAddress,
158 String macAddress, boolean primary, String nextHopIp, String subnetId, WriteTransaction tx) {
159 synchronized (interfaceName.intern()) {
160 Adjacencies adjancencies = buildInterfaceAdjacency(ipAddress, macAddress, primary, nextHopIp, subnetId);
161 VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, adjancencies);
163 tx.merge(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName),
164 einterfaceBuilder.build());
168 private static VpnInterfaceBuilder createVpnInterface(String instanceName, String interfaceName,
169 Adjacencies adjacencies) {
170 VpnInterfaceBuilder einterfaceBuilder = new VpnInterfaceBuilder();
171 einterfaceBuilder.setVpnInstanceName(instanceName);
172 einterfaceBuilder.setName(interfaceName);
173 einterfaceBuilder.addAugmentation(Adjacencies.class, adjacencies);
174 return einterfaceBuilder;
177 private static Adjacencies buildInterfaceAdjacency(String ipAddress, String macAddress, boolean primary,
178 String nextHopIp, String subnetId) {
179 AdjacenciesBuilder builder = new AdjacenciesBuilder();
180 List<Adjacency> list = new ArrayList<>();
182 AdjacencyBuilder aBuilder = new AdjacencyBuilder();
183 aBuilder.setIpAddress(ipAddress);
184 if (macAddress != null) {
185 aBuilder.setMacAddress(macAddress);
187 aBuilder.setPrimaryAdjacency(primary);
188 if (subnetId != null) {
189 aBuilder.setSubnetId(new Uuid(subnetId));
191 if (nextHopIp != null) {
192 aBuilder.setNextHopIpList(Arrays.asList(nextHopIp));
194 list.add(aBuilder.build());
196 builder.setAdjacency(list);
197 return builder.build();
200 public static void removeVpnInterface(String interfaceName, WriteTransaction tx) {
201 synchronized (interfaceName.intern()) {
202 tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName));
206 public static void removeVpnInterfaceAdjacencies(DataBroker dataBroker, String vpnName, String interfaceName) {
207 InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceInstanceIdentifier(interfaceName);
208 InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
209 Optional<Adjacencies> adjacencies = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
210 List<Adjacency> adjacenciesList = adjacencies.isPresent() && adjacencies.get().getAdjacency() != null
211 ? adjacencies.get().getAdjacency() : Collections.emptyList();
212 adjacenciesList.forEach(a -> {
213 String ipStr = getIpAddressFromPrefix(a.getIpAddress());
214 InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, ipStr);
215 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
218 AdjacenciesBuilder builder = new AdjacenciesBuilder();
219 List<Adjacency> list = new ArrayList<>();
220 builder.setAdjacency(list);
221 VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, builder.build());
223 MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
224 getVpnInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
228 public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpPrefix ifPrefix) {
229 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
230 String ipAddress = ipPrefixToString(ifPrefix);
231 removeVpnInterfaceAdjacency(interfaceName, ipAddress, tx);
232 MdsalUtils.commitTransaction(tx);
235 public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpAddress ifAddress) {
236 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
237 String ifAddressStr = getAddressFromSubnet(ipAddressToString(ifAddress));
238 removeVpnInterfaceAdjacency(interfaceName, ifAddressStr, tx);
239 MdsalUtils.commitTransaction(tx);
242 private static void removeVpnInterfaceAdjacency(String interfaceName, String ipAddress, WriteTransaction tx) {
243 synchronized (interfaceName.intern()) {
245 InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
246 .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).augmentation(Adjacencies.class)
247 .child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
249 tx.delete(LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
253 private static InstanceIdentifier<VpnInterface> getVpnInterfaceInstanceIdentifier(String interfaceName) {
254 return InstanceIdentifier.builder(VpnInterfaces.class)
255 .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).build();
258 public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, IpPrefix ipAddress,
259 MacAddress macAddress) {
260 String fixedIpPrefix = ipPrefixToString(ipAddress);
261 String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
263 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
264 createVpnPortFixedIp(vpnName, portName, fixedIp, macAddress, tx);
265 MdsalUtils.commitTransaction(tx);
268 private static void createVpnPortFixedIp(String vpnName, String portName, String fixedIp, MacAddress macAddress,
269 WriteTransaction tx) {
270 synchronized ((vpnName + fixedIp).intern()) {
271 InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
272 VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder()
273 .setKey(new VpnPortipToPortKey(fixedIp, vpnName)).setVpnName(vpnName).setPortFixedip(fixedIp)
274 .setPortName(portName).setMacAddress(macAddress.getValue()).setSubnetIp(true);
275 tx.put(LogicalDatastoreType.OPERATIONAL, id, builder.build());
277 "Interface to fixedIp added: {}, vpn {}, interface {}, mac {} added to " + "VpnPortipToPort DS",
278 fixedIp, vpnName, portName, macAddress);
282 public static VpnPortipToPort getVpnPortFixedIp(DataBroker dataBroker, String vpnName, String fixedIp) {
283 InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
284 Optional<VpnPortipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
285 return opt != null && opt.isPresent() ? opt.get() : null;
288 public static void removeVpnPortFixedIp(String vpnName, IpPrefix ipAddress, WriteTransaction tx) {
289 String fixedIpPrefix = ipPrefixToString(ipAddress);
290 String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
291 InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
292 tx.delete(LogicalDatastoreType.OPERATIONAL, id);
295 public static void registerDirectSubnetForVpn(DataBroker dataBroker, Uuid subnetName, IpAddress gwIpAddress) {
296 final SubnetKey subnetkey = new SubnetKey(subnetName);
298 final InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class)
299 .child(Subnets.class).child(Subnet.class, subnetkey);
301 SubnetBuilder subnetBuilder = new SubnetBuilder();
302 subnetBuilder.setIpVersion(IpVersionV4.class);
303 subnetBuilder.setGatewayIp(gwIpAddress);
304 subnetBuilder.setKey(subnetkey);
305 MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetidentifier, subnetBuilder.build());
308 public static void unregisterDirectSubnetForVpn(DataBroker dataBroker, Uuid subnetName) {
309 final SubnetKey subnetkey = new SubnetKey(subnetName);
310 final InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class)
311 .child(Subnets.class).child(Subnet.class, subnetkey);
313 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
316 public static void addDirectSubnetToVpn(DataBroker dataBroker,
317 final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
318 IpPrefix subnetIpPrefix, String interfaceName, String intfMac, int waitForElan) {
319 InstanceIdentifier<ElanInstance> elanIdentifierId = NetvirtUtils.getElanInstanceInstanceIdentifier(subnetName);
321 @SuppressWarnings("resource") // AutoCloseable
322 DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<>(dataBroker, elanIdentifierId,
323 10, LogicalDatastoreType.CONFIGURATION, el -> el.getElanTag());
324 if (!elanTagWaiter.waitForData()) {
325 logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
329 Uuid subnetId = new Uuid(subnetName);
330 logger.info("Adding subnet {} {} to elan map", subnetId, subnetId);
331 createSubnetToNetworkMapping(dataBroker, subnetId, subnetId);
333 String subnetIp = getSubnetFromPrefix(ipPrefixToString(subnetIpPrefix));
334 logger.info("Adding subnet {} {} to vpn {}", subnetName, subnetIp, vpnName);
335 updateSubnetNode(dataBroker, new Uuid(vpnName), subnetId, subnetIp, intfMac);
337 logger.info("Adding port {} to subnet {}", interfaceName, subnetName);
338 updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null, vpnName);
340 Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
342 Long elanTag = elanInstance.get().getElanTag();
344 logger.info("Publish subnet {}", subnetName);
345 publishSubnetAddNotification(notificationPublishService, subnetId, subnetIp, vpnName, elanTag);
346 logger.info("Finished Working on subnet {}", subnetName);
349 public static void removeDirectSubnetFromVpn(DataBroker dataBroker,
350 final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
351 String interfaceName) {
352 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
353 .child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
354 Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
356 if (!elanInstance.isPresent()) {
357 logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
360 Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
361 : elanInstance.get().getSegmentationId();
362 Uuid subnetId = new Uuid(subnetName);
364 logger.info("Publish subnet remove {}", subnetName);
365 publishSubnetRemoveNotification(notificationPublishService, subnetId, vpnName, elanTag);
367 logger.info("Removing port {} from subnet {}", interfaceName, subnetName);
368 updateSubnetmapNodeWithPorts(dataBroker, subnetId, null, new Uuid(interfaceName), vpnName);
370 logger.info("Removing subnet {} from vpn {}", subnetName, vpnName);
371 removeSubnetNode(dataBroker, new Uuid(vpnName));
373 logger.info("Removing subnet {} to elan map", subnetId);
374 removeSubnetToNetworkMapping(dataBroker, subnetId);
376 logger.info("Finished Working on subnet {}", subnetName);
379 private static void createSubnetToNetworkMapping(DataBroker dataBroker, Uuid subnetId, Uuid networkId) {
380 InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
381 Optional<NetworkMap> optionalNetworkMap = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
382 networkMapIdentifier);
383 NetworkMapBuilder nwMapBuilder = null;
384 if (optionalNetworkMap.isPresent()) {
385 nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
387 nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
388 logger.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
390 List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
391 if (subnetIdList == null) {
392 subnetIdList = new ArrayList<>();
394 subnetIdList.add(subnetId);
395 nwMapBuilder.setSubnetIdList(subnetIdList);
396 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
397 logger.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
398 networkId.getValue());
401 private static void removeSubnetToNetworkMapping(DataBroker dataBroker, Uuid networkId) {
402 InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
403 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier);
404 logger.debug("Deleted subnet-network mapping for network {}", networkId.getValue());
407 protected static void updateSubnetNode(DataBroker dataBroker, Uuid vpnId, Uuid subnetId, String subnetIp,
409 Subnetmap subnetmap = null;
410 SubnetmapBuilder builder = null;
411 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
412 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
414 synchronized (subnetId.getValue().intern()) {
415 Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
416 if (sn.isPresent()) {
417 builder = new SubnetmapBuilder(sn.get());
418 logger.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
420 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
421 logger.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
424 builder.setSubnetIp(subnetIp);
425 builder.setNetworkId(subnetId);
426 builder.setVpnId(vpnId);
427 builder.setRouterIntfMacAddress(intfMac);
429 subnetmap = builder.build();
430 logger.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
431 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
435 protected static void removeSubnetNode(DataBroker dataBroker, Uuid subnetId) {
436 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
437 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
439 synchronized (subnetId.getValue().intern()) {
440 logger.debug("Deleting subnetMap node: {} ", subnetId.getValue());
441 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
445 private static void updateSubnetmapNodeWithPorts(DataBroker dataBroker, Uuid subnetId, Uuid portIdToAdd,
446 Uuid portIdToRemove, String vpnName) {
447 Subnetmap subnetmap = null;
448 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
449 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
450 synchronized (subnetId.getValue().intern()) {
451 Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
452 if (sn.isPresent()) {
453 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
454 if (null != portIdToAdd) {
455 List<Uuid> portList = builder.getPortList();
456 if (null == portList) {
457 portList = new ArrayList<>();
459 if (portIdToAdd != null) {
460 portList.add(portIdToAdd);
461 logger.debug("Updating subnetmap node {} with port {}", subnetId.getValue(),
462 portIdToAdd.getValue());
465 if (portIdToRemove != null) {
466 portList.remove(portIdToRemove);
467 logger.debug("Updating subnetmap node {} removing port {}", subnetId.getValue(),
468 portIdToRemove.getValue());
471 builder.setRouterId(new Uuid(vpnName));
472 builder.setPortList(portList);
474 subnetmap = builder.build();
475 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
477 logger.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
482 private static InstanceIdentifier<NetworkMap> getNetworkMapIdentifier(Uuid networkId) {
483 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
484 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
488 private static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
489 InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
490 .child(VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
494 public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier() {
495 return InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class).build();
498 private static void publishSubnetAddNotification(final NotificationPublishService notificationPublishService,
499 Uuid subnetId, String subnetIp, String vpnName, Long elanTag) {
500 SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
502 logger.info("publish notification called for network creation");
504 builder.setSubnetId(subnetId);
505 builder.setSubnetIp(subnetIp);
506 builder.setVpnName(vpnName);
507 builder.setExternalVpn(true);
508 builder.setElanTag(elanTag);
511 notificationPublishService.putNotification(builder.build());
512 } catch (InterruptedException e) {
513 logger.error("Fail to publish notification {}", builder, e);
514 throw new RuntimeException(e.getMessage());
518 private static void publishSubnetRemoveNotification(final NotificationPublishService notificationPublishService,
519 Uuid subnetId, String vpnName, Long elanTag) {
520 SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
522 logger.info("publish notification called for network deletion");
524 builder.setSubnetId(subnetId);
525 builder.setVpnName(vpnName);
526 builder.setExternalVpn(true);
527 builder.setElanTag(elanTag);
530 notificationPublishService.putNotification(builder.build());
531 } catch (InterruptedException e) {
532 logger.error("Fail to publish notification {}", builder, e);
533 throw new RuntimeException(e.getMessage());
537 public static void sendArpRequest(OdlArputilService arpUtilService, IpAddress srcIpAddress, IpAddress dstIpAddress,
540 List<InterfaceAddress> interfaceAddresses = new ArrayList<>();
542 .add(new InterfaceAddressBuilder().setInterface(interf).setIpAddress(srcIpAddress).build());
544 SendArpRequestInput sendArpRequestInput = new SendArpRequestInputBuilder().setIpaddress(dstIpAddress)
545 .setInterfaceAddress(interfaceAddresses).build();
546 arpUtilService.sendArpRequest(sendArpRequestInput);
547 } catch (Exception e) {
548 logger.error("Failed to send ARP request to IP {} from interfaces {}",
549 dstIpAddress.getIpv4Address().getValue(), interf, e);
550 throw new RuntimeException(e.getMessage());
554 public static String getElanNameForVpnPort(String uniId, String ipUniId) {
555 return getUUidFromString(ELAN_PREFIX + uniId + ipUniId);
558 public static String getIpAddressFromPrefix(String prefix) {
559 return prefix.split(IP_MUSK_SEPARATOR)[0];
562 private static String getMaskFromPrefix(String prefix) {
563 return prefix.split(IP_MUSK_SEPARATOR)[1];
566 public static String getSubnetFromPrefix(String prefix) {
567 SubnetInfo subnet = new SubnetUtils(prefix).getInfo();
568 return subnet.getNetworkAddress() + IP_MUSK_SEPARATOR + getMaskFromPrefix(prefix);
571 public static String getSubnetFromPrefix(IpPrefix prefix) {
572 String prefixStr = ipPrefixToString(prefix);
573 return getSubnetFromPrefix(prefixStr);
576 private static String getAddressFromSubnet(String prefix) {
577 String myAddress = getIpAddressFromPrefix(prefix);
578 return myAddress + IP_ADDR_SUFFIX;
581 public static String getUUidFromString(String key) {
582 return java.util.UUID.nameUUIDFromBytes(key.getBytes()).toString();
585 public static String ipPrefixToString(IpPrefix ipAddress) {
586 if (ipAddress.getIpv4Prefix() != null) {
587 return ipAddress.getIpv4Prefix().getValue();
590 return ipAddress.getIpv6Prefix().getValue();
593 public static String ipAddressToString(IpAddress ipAddress) {
594 if (ipAddress.getIpv4Address() != null) {
595 return ipAddress.getIpv4Address().getValue();
598 return ipAddress.getIpv6Address().getValue();