Bug 5463 : Fixing datapath-id changing behaviour seen while testing with mininet
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / renderer / ovs / utilities / SouthboundUtils.java
1 /*
2  * Copyright (c) 2015 - 2016 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.vpnservice.interfacemgr.renderer.ovs.utilities;
9
10 import com.google.common.collect.Maps;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.Map;
45
46 public class SouthboundUtils {
47     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
48     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
49
50     public static void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface,
51                                        OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
52                                        String portName, DataBroker dataBroker, List<ListenableFuture<Void>> futures) {
53         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
54         IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
55         if (ifTunnel != null) {
56             addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, tx);
57         }
58         futures.add(tx.submit());
59     }
60
61     /*
62      *  add all tunnels ports corresponding to the bridge to the topology config DS
63      */
64     public static void addAllPortsToBridge(BridgeEntry bridgeEntry, DataBroker dataBroker,
65                                            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
66                                            OvsdbBridgeAugmentation bridgeNew,
67                                            WriteTransaction writeTransaction){
68         String bridgeName = bridgeNew.getBridgeName().getValue();
69         LOG.debug("adding all ports to bridge: {}", bridgeName);
70         List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
71         for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
72             String portName = bridgeInterfaceEntry.getInterfaceName();
73             InterfaceKey interfaceKey = new InterfaceKey(portName);
74             Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
75             IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
76             if (ifTunnel != null) {
77                 addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, writeTransaction);
78             }
79         }
80     }
81
82     public static void addBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
83                                  OvsdbBridgeAugmentation bridgeAugmentation,
84                                  DataBroker dataBroker, List<ListenableFuture<Void>> futures){
85         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
86         NodeId nodeId = InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)).getNodeId();
87         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
88         bridgeNodeBuilder.setNodeId(nodeId);
89         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentation);
90         tx.put(LogicalDatastoreType.CONFIGURATION, createNodeInstanceIdentifier(nodeId), bridgeNodeBuilder.build(), true);
91         futures.add(tx.submit());
92     }
93
94     public static void deleteBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
95                                  DataBroker dataBroker, List<ListenableFuture<Void>> futures){
96         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
97         NodeId nodeId = InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)).getNodeId();
98         tx.delete(LogicalDatastoreType.CONFIGURATION, createNodeInstanceIdentifier(nodeId));
99         futures.add(tx.submit());
100     }
101
102     private static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
103                                               OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
104                                               String portName, DataBroker dataBroker, WriteTransaction t) {
105         if(ifL2vlan.getVlanId() != null) {
106             addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, ifL2vlan.getVlanId().getValue(), null, null, dataBroker, t);
107         }
108     }
109
110     private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
111                                              OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
112                                              String portName, DataBroker dataBroker, WriteTransaction t) {
113         Class type = null;
114         LOG.debug("adding tunnel port {} to bridge {}",portName, bridgeName);
115
116         if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class) ||
117                 ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class)) {
118             type = InterfaceTypeGre.class;
119         } else if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
120             type = InterfaceTypeVxlan.class;
121         }
122
123         if (type == null) {
124             LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
125             return;
126         }
127
128         int vlanId = 0;
129         IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
130         if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
131             vlanId = ifL2vlan.getVlanId().getValue();
132         }
133
134         Map<String, String> options = Maps.newHashMap();
135         options.put("key", "flow");
136
137         IpAddress localIp = ifTunnel.getTunnelSource();
138         options.put("local_ip", localIp.getIpv4Address().getValue());
139
140         IpAddress remoteIp = ifTunnel.getTunnelDestination();
141         options.put("remote_ip", remoteIp.getIpv4Address().getValue());
142
143         addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, dataBroker, t);
144     }
145
146     private static void addTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
147                                             String bridgeName, String portName, int vlanId, Class type,
148                                             Map<String, String> options, DataBroker dataBroker, WriteTransaction t) {
149         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
150                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
151         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
152
153         tpAugmentationBuilder.setName(portName);
154
155         if (type != null) {
156             tpAugmentationBuilder.setInterfaceType(type);
157         }
158
159         if (options != null) {
160             List<Options> optionsList = new ArrayList<Options>();
161             for (Map.Entry<String, String> entry : options.entrySet()) {
162                 OptionsBuilder optionsBuilder = new OptionsBuilder();
163                 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
164                 optionsBuilder.setOption(entry.getKey());
165                 optionsBuilder.setValue(entry.getValue());
166                 optionsList.add(optionsBuilder.build());
167             }
168             tpAugmentationBuilder.setOptions(optionsList);
169         }
170
171         if (vlanId != 0) {
172                 tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
173                 tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
174         }
175
176         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
177         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
178         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
179
180         t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
181     }
182
183     private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node,
184                                                                                                  String portName){
185         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
186                 .create(NetworkTopology.class)
187                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
188                 .child(Node.class,node.getKey())
189                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
190
191         LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
192         return terminationPointPath;
193     }
194
195     public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
196                                                                                                 String portName){
197         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
198                 .create(NetworkTopology.class)
199                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
200                 .child(Node.class,nodekey)
201                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
202
203         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
204         return terminationPointPath;
205     }
206
207     public static InstanceIdentifier<Node> createNodeInstanceIdentifier(NodeId nodeId) {
208         return InstanceIdentifier
209                 .create(NetworkTopology.class)
210                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
211                 .child(Node.class,new NodeKey(nodeId));
212     }
213 }