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.math.BigInteger;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.Future;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.EvcElan;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpn;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.EvcChoice;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.IpvcChoice;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizon;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizonBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.DhcpAllocationPool;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.Network;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.NetworkKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.network.AllocationPool;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.network.AllocationPoolBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.network.AllocationPoolKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstanceBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterfaceBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.unimgr.unimgr.dhcp.rev161214.unimgr.dhcp.unimgr.services.network.UnimgrAllocationPool;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
70 import org.opendaylight.yangtools.yang.common.RpcResult;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
74 import com.google.common.base.Optional;
76 public class NetvirtUtils {
78 private static final Logger logger = LoggerFactory.getLogger(NetvirtUtils.class);
79 private static final long DEFAULT_MAC_TIMEOUT = 300;
81 public static void createElanInstance(DataBroker dataBroker, String instanceName, boolean isEtree,
82 Long segmentationId) {
83 createElanInstance(dataBroker, instanceName, isEtree, segmentationId, DEFAULT_MAC_TIMEOUT);
86 public static void createElanInstance(DataBroker dataBroker, String instanceName, boolean isEtree,
87 Long segmentationId, Long macTimeout) {
88 ElanInstanceBuilder einstBuilder = createElanInstanceBuilder(instanceName, segmentationId, macTimeout);
91 EtreeInstance etreeInstance = new EtreeInstanceBuilder().build();
92 einstBuilder.addAugmentation(EtreeInstance.class, etreeInstance).build();
95 MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
96 getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
99 public static void updateElanInstance(DataBroker dataBroker, String instanceName) {
100 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
101 updateElanInstance(instanceName, tx);
102 MdsalUtils.commitTransaction(tx);
105 public static void updateElanInstance(String instanceName, WriteTransaction tx) {
106 ElanInstanceBuilder einstBuilder = createElanInstanceBuilder(instanceName);
107 saveElanInstance(instanceName, tx, einstBuilder);
110 public static void updateElanInstance(String instanceName, WriteTransaction tx, Long segmentationId) {
111 ElanInstanceBuilder einstBuilder = createElanInstanceBuilder(instanceName, segmentationId);
112 saveElanInstance(instanceName, tx, einstBuilder);
115 public static void updateElanInstance(String instanceName, WriteTransaction tx, Long segmentationId,
117 ElanInstanceBuilder einstBuilder = createElanInstanceBuilder(instanceName, segmentationId, macTimeout);
118 saveElanInstance(instanceName, tx, einstBuilder);
121 private static void saveElanInstance(String instanceName, WriteTransaction tx, ElanInstanceBuilder einstBuilder) {
122 tx.merge(LogicalDatastoreType.CONFIGURATION, getElanInstanceInstanceIdentifier(instanceName),
123 einstBuilder.build());
126 public static void updateElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
127 ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
129 MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
130 getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
133 public static void deleteElanInstance(DataBroker dataBroker, String instanceName) {
134 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
135 getElanInstanceInstanceIdentifier(instanceName));
138 public static void deleteElanInstance(String instanceName, WriteTransaction tx) {
139 tx.delete(LogicalDatastoreType.CONFIGURATION, getElanInstanceInstanceIdentifier(instanceName));
142 public static void deleteElanInterface(DataBroker dataBroker, String interfaceName) {
143 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
144 deleteElanInterface(interfaceName, tx);
145 MdsalUtils.commitTransaction(tx);
148 public static void deleteElanInterface(String interfaceName, WriteTransaction tx) {
149 tx.delete(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName));
152 public static Interface createTrunkInterface(String interfaceName, String parentIfaceName) {
153 IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
154 ifL2vlanBuilder.setL2vlanMode(IfL2vlan.L2vlanMode.Trunk);
155 return createInterface(interfaceName, parentIfaceName, ifL2vlanBuilder.build());
158 public static Interface createTrunkMemberInterface(String interfaceName, String parentIfaceName, int vlanId) {
159 IfL2vlanBuilder ifL2vlanBuilder = new IfL2vlanBuilder();
160 ifL2vlanBuilder.setL2vlanMode(IfL2vlan.L2vlanMode.TrunkMember).setVlanId(new VlanId(vlanId));
161 return createInterface(interfaceName, parentIfaceName, ifL2vlanBuilder.build());
164 private static Interface createInterface(String interfaceName, String parentIfaceName, IfL2vlan ifL2vlan) {
165 InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
166 SplitHorizon sh = new SplitHorizonBuilder().setOverrideSplitHorizonProtection(true).build();
167 ParentRefsBuilder parentRefsBuilder = new ParentRefsBuilder().setParentInterface(parentIfaceName);
168 interfaceBuilder.setEnabled(true).setName(interfaceName).setType(L2vlan.class)
169 .addAugmentation(SplitHorizon.class, sh).addAugmentation(IfL2vlan.class, ifL2vlan)
170 .addAugmentation(ParentRefs.class, parentRefsBuilder.build());
171 return interfaceBuilder.build();
174 public static void addAclToInterface(String interfaceName, List<Uuid> securityGroups, WriteTransaction tx) {
175 InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
176 interfaceBuilder.setName(interfaceName);
177 InterfaceAclBuilder interfaceAclBuilder = new InterfaceAclBuilder();
178 interfaceAclBuilder.setPortSecurityEnabled(true);
179 interfaceAclBuilder.setSecurityGroups(securityGroups);
180 interfaceAclBuilder.setAllowedAddressPairs(Collections.emptyList());
181 interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
182 tx.merge(LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName), interfaceBuilder.build());
185 private static ElanInstanceBuilder createElanInstanceBuilder(String instanceName) {
186 return createElanInstanceBuilder(instanceName, Long.valueOf(Math.abs((short) instanceName.hashCode())));
189 private static ElanInstanceBuilder createElanInstanceBuilder(String instanceName, Long segmentationId) {
190 return createElanInstanceBuilder(instanceName, segmentationId, DEFAULT_MAC_TIMEOUT);
193 private static ElanInstanceBuilder createElanInstanceBuilder(String instanceName, Long segmentationId,
195 if (segmentationId == null) {
196 segmentationId = Long.valueOf(Math.abs((short) instanceName.hashCode()));
198 ElanInstanceBuilder einstBuilder = new ElanInstanceBuilder();
199 einstBuilder.setElanInstanceName(instanceName);
200 einstBuilder.setKey(new ElanInstanceKey(instanceName));
201 einstBuilder.setMacTimeout(macTimeout);
202 einstBuilder.setSegmentationId(segmentationId);
203 einstBuilder.setSegmentType(SegmentTypeVxlan.class);
207 private static ElanInterfaceBuilder createElanInterface(String instanceName, String interfaceName) {
208 ElanInterfaceBuilder einterfaceBuilder = new ElanInterfaceBuilder();
209 einterfaceBuilder.setElanInstanceName(instanceName);
210 einterfaceBuilder.setName(interfaceName);
211 return einterfaceBuilder;
214 private static ElanInterfaceBuilder createEtreeInterface(String instanceName, String interfaceName,
215 EtreeInterfaceType interfaceType) {
216 ElanInterfaceBuilder einterfaceBuilder = new ElanInterfaceBuilder();
217 einterfaceBuilder.setElanInstanceName(instanceName);
218 einterfaceBuilder.setName(interfaceName);
219 EtreeInterface etreeInterface = new EtreeInterfaceBuilder().setEtreeInterfaceType(interfaceType).build();
220 einterfaceBuilder.addAugmentation(EtreeInterface.class, etreeInterface);
221 return einterfaceBuilder;
224 public static InstanceIdentifier<ElanInstance> getElanInstanceInstanceIdentifier() {
225 return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class).build();
228 public static InstanceIdentifier<ElanInterfaces> getElanInterfacesInstanceIdentifier() {
229 return InstanceIdentifier.builder(ElanInterfaces.class).build();
232 public static InstanceIdentifier<ElanInstance> getElanInstanceInstanceIdentifier(String instanceName) {
233 return InstanceIdentifier.builder(ElanInstances.class)
234 .child(ElanInstance.class, new ElanInstanceKey(instanceName)).build();
237 private static InstanceIdentifier<ElanInterface> getElanInterfaceInstanceIdentifier(String interfaceName) {
238 return InstanceIdentifier.builder(ElanInterfaces.class)
239 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
242 public static InstanceIdentifier<Interface> getInterfaceIdentifier(String interfaceName) {
243 InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier.builder(Interfaces.class)
244 .child(Interface.class, new InterfaceKey(interfaceName));
245 InstanceIdentifier<Interface> id = idBuilder.build();
249 public static Optional<Interface> getIetfInterface(DataBroker dataBroker, String interfaceName) {
250 return MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
253 public static void writeInterface(Interface iface, WriteTransaction tx) {
254 String interfaceName = iface.getName();
255 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
256 tx.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, iface, true);
259 public static void deleteInterface(String interfaceName, WriteTransaction tx) {
260 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
261 tx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
264 private static InstanceIdentifier<Interface> createInterfaceIdentifier(String interfaceName) {
265 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
269 public static void createElanInterface(DataBroker dataBroker, String instanceName, String interfaceName,
270 EtreeInterfaceType etreeInterfaceType, boolean isEtree) {
271 WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
272 createElanInterface(instanceName, interfaceName, etreeInterfaceType, isEtree, tx);
273 MdsalUtils.commitTransaction(tx);
276 public static void createElanInterface(String instanceName, String interfaceName,
277 EtreeInterfaceType etreeInterfaceType, boolean isEtree, WriteTransaction tx) {
278 logger.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
281 NetvirtUtils.createEtreeInterface(instanceName, interfaceName, etreeInterfaceType, tx);
283 NetvirtUtils.createElanInterface(instanceName, interfaceName, tx);
287 private static void createEtreeInterface(String instanceName, String interfaceName, EtreeInterfaceType type,
288 WriteTransaction tx) {
289 ElanInterfaceBuilder einterfaceBuilder = createEtreeInterface(instanceName, interfaceName, type);
291 tx.put(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName),
292 einterfaceBuilder.build());
295 private static void createElanInterface(String instanceName, String interfaceName, WriteTransaction tx) {
296 ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
298 tx.put(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName),
299 einterfaceBuilder.build());
302 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
303 BigInteger nodeId = BigInteger.ZERO;
305 GetDpidFromInterfaceInput dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
306 Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput = interfaceManagerRpcService
307 .getDpidFromInterface(dpIdInput);
308 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
309 if (dpIdResult.isSuccessful()) {
310 nodeId = dpIdResult.getResult().getDpid();
312 logger.error("Could not retrieve DPN Id for interface {}", ifName);
314 } catch (NullPointerException | InterruptedException | ExecutionException e) {
315 logger.error("Exception when getting dpn for interface {}", ifName, e);
320 public static void safeSleep() {
324 } catch (InterruptedException e) {
328 public static void safeSleep(short sec) {
331 Thread.sleep(1000 * sec);
332 } catch (InterruptedException e) {
336 public static void createDhcpAllocationPool(DataBroker dataBroker, UnimgrAllocationPool unimgrAllocationPool,
337 String unimgrNetworkId, RetailSvcIdType svcId) {
338 String networkId = convertNetworkToNetvirtNetwork(dataBroker, unimgrNetworkId, svcId);
339 if (networkId != null) {
340 // add allocation pool to netvirt
341 MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
342 createDhcpAllocationPoolInstanceIdentifier(networkId, unimgrAllocationPool.getKey().getSubnet()),
343 buildDhcpAllocationPool(unimgrAllocationPool));
345 logger.warn("no network found for svc-id {}", svcId);
349 public static void removeDhcpAllocationPool(DataBroker dataBroker, String unimgrNetworkId, RetailSvcIdType svcId,
351 String networkId = convertNetworkToNetvirtNetwork(dataBroker, unimgrNetworkId, svcId);
352 if (networkId != null) {
353 // remove allocation pool from netvirt
354 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
355 createDhcpAllocationPoolInstanceIdentifier(networkId, subnet));
357 logger.warn("no network found for svc-id {}", svcId);
361 private static String convertNetworkToNetvirtNetwork(DataBroker dataBroker, String unimgrNetworkId,
362 RetailSvcIdType svcId) {
363 Optional<MefService> optionalOpMefService = MefServicesUtils.getOpMefServiceBySvcId(dataBroker, svcId);
364 if (!optionalOpMefService.isPresent()) {
365 logger.warn("no mef-service found for svc-id {}", svcId);
368 MefService opMefService = optionalOpMefService.get();
369 return MefServicesUtils.getNetworkIdFromOpMefService(opMefService, unimgrNetworkId);
372 private static InstanceIdentifier<AllocationPool> createDhcpAllocationPoolInstanceIdentifier(String networkId,
374 return InstanceIdentifier.builder(DhcpAllocationPool.class).child(Network.class, new NetworkKey(networkId))
375 .child(AllocationPool.class, new AllocationPoolKey(subnet)).build();
378 private static AllocationPool buildDhcpAllocationPool(UnimgrAllocationPool unimgrAllocationPool) {
379 AllocationPool allocationPool = new AllocationPoolBuilder()
380 .setKey(new AllocationPoolKey(unimgrAllocationPool.getSubnet()))
381 .setSubnet(unimgrAllocationPool.getSubnet()).setAllocateFrom(unimgrAllocationPool.getAllocateFrom())
382 .setAllocateTo(unimgrAllocationPool.getAllocateTo()).setDnsServers(unimgrAllocationPool.getDnsServers())
383 .setGateway(unimgrAllocationPool.getGateway()).build();
384 return allocationPool;