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