Merge "L2 Gw create changes related to ITM Tunnels creation in neutronvpn module"
[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.vpnservice.mdsalutil.NwConstants;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.opendaylight.vpnservice.interfacemgr.renderer.hwvtep.utilities.*;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import java.util.ArrayList;
45 import java.util.List;
46 import java.util.Map;
47
48 public class SouthboundUtils {
49     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
50
51     public static final String BFD_PARAM_ENABLE = "enable";
52     public static final String BFD_PARAM_INTERVAL = "min_tx";
53     // bfd params
54     public static final String BFD_OP_STATE = "state";
55     public static final String BFD_STATE_UP = "up";
56
57     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
58
59     public static void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface,
60                                        OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
61                                        String portName, DataBroker dataBroker, List<ListenableFuture<Void>> futures) {
62         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
63         IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
64         if (ifTunnel != null) {
65             addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, tx);
66         }
67         futures.add(tx.submit());
68     }
69
70     /*
71      *  add all tunnels ports corresponding to the bridge to the topology config DS
72      */
73     public static void addAllPortsToBridge(BridgeEntry bridgeEntry, DataBroker dataBroker,
74                                            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
75                                            OvsdbBridgeAugmentation bridgeNew,
76                                            WriteTransaction writeTransaction){
77         String bridgeName = bridgeNew.getBridgeName().getValue();
78         LOG.debug("adding all ports to bridge: {}", bridgeName);
79         List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
80         for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
81             String portName = bridgeInterfaceEntry.getInterfaceName();
82             InterfaceKey interfaceKey = new InterfaceKey(portName);
83             Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
84             IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
85             if (ifTunnel != null) {
86                 addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, writeTransaction);
87             }
88         }
89     }
90
91     public static void addBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
92                                  OvsdbBridgeAugmentation bridgeAugmentation,
93                                  DataBroker dataBroker, List<ListenableFuture<Void>> futures){
94         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
95         NodeId nodeId = InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)).getNodeId();
96         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
97         bridgeNodeBuilder.setNodeId(nodeId);
98         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentation);
99         tx.put(LogicalDatastoreType.CONFIGURATION, createNodeInstanceIdentifier(nodeId), bridgeNodeBuilder.build(), true);
100         futures.add(tx.submit());
101     }
102
103     public static void deleteBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
104                                  DataBroker dataBroker, List<ListenableFuture<Void>> futures){
105         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
106         NodeId nodeId = InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)).getNodeId();
107         tx.delete(LogicalDatastoreType.CONFIGURATION, createNodeInstanceIdentifier(nodeId));
108         futures.add(tx.submit());
109     }
110
111     private static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan, IfTunnel ifTunnel,
112                                               OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
113                                               String portName, DataBroker dataBroker, WriteTransaction t) {
114         if(ifL2vlan.getVlanId() != null) {
115             addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, ifL2vlan.getVlanId().getValue(), null, null,
116                             ifTunnel, t);
117         }
118     }
119
120     private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
121                                              OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
122                                              String portName, DataBroker dataBroker, WriteTransaction t) {
123         Class type = null;
124         LOG.debug("adding tunnel port {} to bridge {}",portName, bridgeName);
125
126         if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class) ||
127                 ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class)) {
128             type = InterfaceTypeGre.class;
129         } else if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
130             type = InterfaceTypeVxlan.class;
131         }
132
133         if (type == null) {
134             LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
135             return;
136         }
137
138         int vlanId = 0;
139         IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
140         if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
141             vlanId = ifL2vlan.getVlanId().getValue();
142         }
143
144         Map<String, String> options = Maps.newHashMap();
145         options.put("key", "flow");
146
147         IpAddress localIp = ifTunnel.getTunnelSource();
148         options.put("local_ip", localIp.getIpv4Address().getValue());
149
150         IpAddress remoteIp = ifTunnel.getTunnelDestination();
151         options.put("remote_ip", remoteIp.getIpv4Address().getValue());
152
153         addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, ifTunnel, t);
154     }
155
156     // Update is allowed only for tunnel monitoring attributes
157     public static void updateBfdParamtersForTerminationPoint(InstanceIdentifier<?> bridgeIid, IfTunnel ifTunnel, String portName,
158                                                WriteTransaction transaction){
159         if( !ifTunnel.isInternal() && ifTunnel.getTunnelInterfaceType().equals(TunnelTypeVxlan.class) ) {
160             InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
161                     InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
162             LOG.debug("update bfd parameters for interface {}", tpIid);
163             OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
164             List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
165             tpAugmentationBuilder.setInterfaceBfd(bfdParams);
166
167             TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
168             tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
169             tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
170
171             transaction.merge(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
172         }
173     }
174
175     private static void addTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode, String bridgeName, String portName, int vlanId, Class type,
176                                             Map<String, String> options, IfTunnel ifTunnel, WriteTransaction t) {
177         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
178                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
179         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
180
181         tpAugmentationBuilder.setName(portName);
182
183         if (type != null) {
184             tpAugmentationBuilder.setInterfaceType(type);
185         }
186
187         if (options != null) {
188             List<Options> optionsList = new ArrayList<Options>();
189             for (Map.Entry<String, String> entry : options.entrySet()) {
190                 OptionsBuilder optionsBuilder = new OptionsBuilder();
191                 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
192                 optionsBuilder.setOption(entry.getKey());
193                 optionsBuilder.setValue(entry.getValue());
194                 optionsList.add(optionsBuilder.build());
195             }
196             tpAugmentationBuilder.setOptions(optionsList);
197         }
198
199         if (vlanId != 0) {
200                 tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
201                 tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
202         }
203
204
205         if( !ifTunnel.isInternal() && ifTunnel.getTunnelInterfaceType().equals(TunnelTypeVxlan.class) ) {
206             List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
207             tpAugmentationBuilder.setInterfaceBfd(bfdParams);
208         }
209
210         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
211         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
212         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
213
214         t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
215
216     }
217
218     private static List<InterfaceBfd> getBfdParams(IfTunnel ifTunnel) {
219         List<InterfaceBfd> bfdParams = new ArrayList<>();
220         bfdParams.add(getIfBfdObj(BFD_PARAM_ENABLE,
221                         Boolean.toString(ifTunnel.isMonitorEnabled())));
222         bfdParams.add(getIfBfdObj(BFD_PARAM_INTERVAL,
223                 ifTunnel.getMonitorInterval().toString()));
224         return bfdParams;
225     }
226
227     private static InterfaceBfd getIfBfdObj(String key, String value) {
228         InterfaceBfdBuilder bfdBuilder = new InterfaceBfdBuilder();
229         bfdBuilder.setBfdKey(key).
230                         setKey(new InterfaceBfdKey(key)).setBfdValue(value);
231         return bfdBuilder.build();
232     }
233
234     private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node,
235                                                                                                  String portName){
236         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
237                 .create(NetworkTopology.class)
238                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
239                 .child(Node.class,node.getKey())
240                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
241
242         LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
243         return terminationPointPath;
244     }
245
246     public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
247                                                                                                 String portName){
248         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
249                 .create(NetworkTopology.class)
250                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
251                 .child(Node.class,nodekey)
252                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
253
254         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
255         return terminationPointPath;
256     }
257
258     public static InstanceIdentifier<Node> createNodeInstanceIdentifier(NodeId nodeId) {
259         return InstanceIdentifier
260                 .create(NetworkTopology.class)
261                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
262                 .child(Node.class,new NodeKey(nodeId));
263     }
264 }