Bulk merge of l2gw changes
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / utils / L2gwZeroDayConfigUtil.java
diff --git a/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/L2gwZeroDayConfigUtil.java b/elanmanager/impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/L2gwZeroDayConfigUtil.java
new file mode 100644 (file)
index 0000000..28c4d53
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.elan.l2gw.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
+import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
+import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
+import org.opendaylight.netvirt.elan.utils.ElanConstants;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSetBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@Singleton
+public class L2gwZeroDayConfigUtil {
+
+    public static final String ZERO_DAY_LS_NAME = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA";
+    private static final String ZERO_DAY_LS_VNI = "65535";
+
+    L2GatewayCache l2GatewayCache;
+
+    @Inject
+    public L2gwZeroDayConfigUtil(L2GatewayCache l2GatewayCache) {
+        this.l2GatewayCache = l2GatewayCache;
+    }
+
+    public void createZeroDayConfig(TypedWriteTransaction<Configuration> tx,
+                                    InstanceIdentifier<Node> dstPsPath,
+                                    L2GatewayDevice l2GatewayDevice,
+                                    Collection<TransportZone> zones) {
+        writeZeroDayLogicalSwitch(dstPsPath, tx, true);
+        writeMcastsForZeroDayConfig(dstPsPath, l2GatewayDevice, zones, tx, true);
+    }
+
+    public void deleteZeroDayConfig(TypedWriteTransaction tx,
+                                    InstanceIdentifier<Node> dstPsPath,
+                                    L2GatewayDevice l2GatewayDevice) {
+        writeZeroDayLogicalSwitch(dstPsPath, tx, false);
+        writeMcastsForZeroDayConfig(dstPsPath, l2GatewayDevice, Collections.emptyList(), tx, false);
+    }
+
+    private List<IpAddress> getDpnTeps(Collection<TransportZone> zones) {
+        return zones.stream()
+                .filter(zone -> zone.getVteps() != null)
+                .flatMap(zone -> zone.getVteps().values().stream())
+                .filter(vtep -> vtep.getIpAddress() != null)
+                .map(vtep -> vtep.getIpAddress())
+                .collect(Collectors.toList());
+    }
+
+    private List<IpAddress> getOtherTorTeps(L2GatewayDevice l2GatewayDevice) {
+        return l2GatewayCache.getAll().stream()
+                .filter(device -> !device.getDeviceName().equals(l2GatewayDevice.getDeviceName()))
+                .filter(device -> device.getTunnelIp() != null)
+                .map(device -> device.getTunnelIp())
+                .collect(Collectors.toList());
+    }
+
+    private void writeMcastsForZeroDayConfig(InstanceIdentifier<Node> dstPath,
+                                             L2GatewayDevice l2GatewayDevice,
+                                             Collection<TransportZone> zones,
+                                             TypedWriteTransaction<Configuration> tx,
+                                             boolean add) {
+        List<IpAddress> otherTorTeps = getOtherTorTeps(l2GatewayDevice);
+        List<IpAddress> dpnsTepIps = getDpnTeps(zones);
+        ArrayList<IpAddress> remoteTepIps = new ArrayList<>(dpnsTepIps);
+        remoteTepIps.addAll(otherTorTeps);
+
+        List<LocatorSet> locators = new ArrayList<>();
+        NodeId nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
+        if (add) {
+            for (IpAddress tepIp : remoteTepIps) {
+                HwvtepPhysicalLocatorAugmentation phyLocatorAug = HwvtepSouthboundUtils
+                        .createHwvtepPhysicalLocatorAugmentation(tepIp.stringValue());
+                HwvtepPhysicalLocatorRef phyLocRef = new HwvtepPhysicalLocatorRef(
+                        HwvtepSouthboundUtils.createPhysicalLocatorInstanceIdentifier(nodeId, phyLocatorAug));
+                locators.add(new LocatorSetBuilder().setLocatorRef(phyLocRef).build());
+            }
+        }
+        HwvtepLogicalSwitchRef lsRef = new HwvtepLogicalSwitchRef(HwvtepSouthboundUtils
+                .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(ZERO_DAY_LS_NAME)));
+        RemoteMcastMacs remoteMcastMac = new RemoteMcastMacsBuilder()
+                .setMacEntryKey(new MacAddress(ElanConstants.UNKNOWN_DMAC)).setLogicalSwitchRef(lsRef)
+                .setLocatorSet(locators).build();
+        InstanceIdentifier<RemoteMcastMacs> iid = HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(nodeId,
+                remoteMcastMac.key());
+        if (add) {
+            tx.mergeParentStructurePut(iid, remoteMcastMac);
+        } else {
+            tx.delete(iid);
+        }
+    }
+
+    private void writeZeroDayLogicalSwitch(InstanceIdentifier<Node> dstPsPath,
+        TypedWriteTransaction<Configuration> tx, boolean add) {
+
+        String vniToUse = System.getProperty("zero.day.ls.vni");
+        vniToUse = (vniToUse == null) ? ZERO_DAY_LS_VNI : vniToUse;
+        LogicalSwitches logicalSwitch = new LogicalSwitchesBuilder()
+                .setHwvtepNodeName(new HwvtepNodeName(ZERO_DAY_LS_NAME))
+                .setTunnelKey(vniToUse)
+                .build();
+        InstanceIdentifier<LogicalSwitches> path = dstPsPath
+                .augmentation(HwvtepGlobalAugmentation.class)
+                .child(LogicalSwitches.class, new LogicalSwitchesKey(logicalSwitch.key()));
+        if (add) {
+            tx.mergeParentStructurePut(path, logicalSwitch);
+        } else {
+            tx.delete(path);
+        }
+    }
+}
\ No newline at end of file