Bulk merge of l2gw changes
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / utils / L2gwZeroDayConfigUtil.java
1 /*
2  * Copyright (c) 2020 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 package org.opendaylight.netvirt.elan.l2gw.utils;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.stream.Collectors;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
18 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
19 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
20 import org.opendaylight.netvirt.elan.utils.ElanConstants;
21 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
22 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSetBuilder;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41
42 @Singleton
43 public class L2gwZeroDayConfigUtil {
44
45     public static final String ZERO_DAY_LS_NAME = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA";
46     private static final String ZERO_DAY_LS_VNI = "65535";
47
48     L2GatewayCache l2GatewayCache;
49
50     @Inject
51     public L2gwZeroDayConfigUtil(L2GatewayCache l2GatewayCache) {
52         this.l2GatewayCache = l2GatewayCache;
53     }
54
55     public void createZeroDayConfig(TypedWriteTransaction<Configuration> tx,
56                                     InstanceIdentifier<Node> dstPsPath,
57                                     L2GatewayDevice l2GatewayDevice,
58                                     Collection<TransportZone> zones) {
59         writeZeroDayLogicalSwitch(dstPsPath, tx, true);
60         writeMcastsForZeroDayConfig(dstPsPath, l2GatewayDevice, zones, tx, true);
61     }
62
63     public void deleteZeroDayConfig(TypedWriteTransaction tx,
64                                     InstanceIdentifier<Node> dstPsPath,
65                                     L2GatewayDevice l2GatewayDevice) {
66         writeZeroDayLogicalSwitch(dstPsPath, tx, false);
67         writeMcastsForZeroDayConfig(dstPsPath, l2GatewayDevice, Collections.emptyList(), tx, false);
68     }
69
70     private List<IpAddress> getDpnTeps(Collection<TransportZone> zones) {
71         return zones.stream()
72                 .filter(zone -> zone.getVteps() != null)
73                 .flatMap(zone -> zone.getVteps().values().stream())
74                 .filter(vtep -> vtep.getIpAddress() != null)
75                 .map(vtep -> vtep.getIpAddress())
76                 .collect(Collectors.toList());
77     }
78
79     private List<IpAddress> getOtherTorTeps(L2GatewayDevice l2GatewayDevice) {
80         return l2GatewayCache.getAll().stream()
81                 .filter(device -> !device.getDeviceName().equals(l2GatewayDevice.getDeviceName()))
82                 .filter(device -> device.getTunnelIp() != null)
83                 .map(device -> device.getTunnelIp())
84                 .collect(Collectors.toList());
85     }
86
87     private void writeMcastsForZeroDayConfig(InstanceIdentifier<Node> dstPath,
88                                              L2GatewayDevice l2GatewayDevice,
89                                              Collection<TransportZone> zones,
90                                              TypedWriteTransaction<Configuration> tx,
91                                              boolean add) {
92         List<IpAddress> otherTorTeps = getOtherTorTeps(l2GatewayDevice);
93         List<IpAddress> dpnsTepIps = getDpnTeps(zones);
94         ArrayList<IpAddress> remoteTepIps = new ArrayList<>(dpnsTepIps);
95         remoteTepIps.addAll(otherTorTeps);
96
97         List<LocatorSet> locators = new ArrayList<>();
98         NodeId nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
99         if (add) {
100             for (IpAddress tepIp : remoteTepIps) {
101                 HwvtepPhysicalLocatorAugmentation phyLocatorAug = HwvtepSouthboundUtils
102                         .createHwvtepPhysicalLocatorAugmentation(tepIp.stringValue());
103                 HwvtepPhysicalLocatorRef phyLocRef = new HwvtepPhysicalLocatorRef(
104                         HwvtepSouthboundUtils.createPhysicalLocatorInstanceIdentifier(nodeId, phyLocatorAug));
105                 locators.add(new LocatorSetBuilder().setLocatorRef(phyLocRef).build());
106             }
107         }
108         HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(HwvtepSouthboundUtils
109                 .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(ZERO_DAY_LS_NAME)));
110         RemoteMcastMacs remoteMcastMac = new RemoteMcastMacsBuilder()
111                 .setMacEntryKey(new MacAddress(ElanConstants.UNKNOWN_DMAC)).setLogicalSwitchRef(lsRef)
112                 .setLocatorSet(locators).build();
113         InstanceIdentifier<RemoteMcastMacs> iid = HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(nodeId,
114                 remoteMcastMac.key());
115         if (add) {
116             tx.mergeParentStructurePut(iid, remoteMcastMac);
117         } else {
118             tx.delete(iid);
119         }
120     }
121
122     private void writeZeroDayLogicalSwitch(InstanceIdentifier<Node> dstPsPath,
123         TypedWriteTransaction<Configuration> tx, boolean add) {
124
125         String vniToUse = System.getProperty("zero.day.ls.vni");
126         vniToUse = (vniToUse == null) ? ZERO_DAY_LS_VNI : vniToUse;
127         LogicalSwitches logicalSwitch = new LogicalSwitchesBuilder()
128                 .setHwvtepNodeName(new HwvtepNodeName(ZERO_DAY_LS_NAME))
129                 .setTunnelKey(vniToUse)
130                 .build();
131         InstanceIdentifier<LogicalSwitches> path = dstPsPath
132                 .augmentation(HwvtepGlobalAugmentation.class)
133                 .child(LogicalSwitches.class, new LogicalSwitchesKey(logicalSwitch.key()));
134         if (add) {
135             tx.mergeParentStructurePut(path, logicalSwitch);
136         } else {
137             tx.delete(path);
138         }
139     }
140 }