d3f96d3f585dea592fdf2dcd68b823fd8206ad1a
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / utilities / SouthboundUtils.java
1 /*
2  * Copyright (c) 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.genius.interfacemanager.renderer.ovs.utilities;
9
10 import com.google.common.collect.ImmutableBiMap;
11 import com.google.common.collect.Maps;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
17 import org.opendaylight.genius.interfacemanager.renderer.hwvtep.utilities.*;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.*;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
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     static final String BFD_PARAM_MIN_TX = "min_tx";
53     static final String BFD_PARAM_MIN_RX = "min_rx";
54     static final String BFD_PARAM_DECAY_MIN_RX = "decay_min_rx";
55     static final String BFD_PARAM_FORWARDING_IF_RX = "forwarding_if_rx";
56     static final String BFD_PARAM_CPATH_DOWN = "cpath_down";
57     static final String BFD_PARAM_CHECK_TNL_KEY = "check_tnl_key";
58     // bfd params
59     public static final String BFD_OP_STATE = "state";
60     public static final String BFD_STATE_UP = "up";
61     private static final String BFD_MIN_RX_VAL = "1000";
62     private static final String BFD_MIN_TX_VAL = "100";
63     private static final String BFD_DECAY_MIN_RX_VAL = "200";
64     private static final String BFD_FORWARDING_IF_RX_VAL = "true";
65     private static final String BFD_CPATH_DOWN_VAL = "false";
66     private static final String BFD_CHECK_TNL_KEY_VAL = "false";
67
68     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
69
70     public static final ImmutableBiMap<Class<? extends TunnelTypeBase>,
71             Class<? extends InterfaceTypeBase>> TUNNEL_TYPE_MAP =
72             new ImmutableBiMap.Builder<Class<? extends TunnelTypeBase>, Class<? extends InterfaceTypeBase>>()
73                     .put(TunnelTypeGre.class, InterfaceTypeGre.class)
74                     .put(TunnelTypeVxlan.class, InterfaceTypeVxlan.class)
75                     .build();
76
77     public static void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface,
78                                        OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
79                                        String portName, DataBroker dataBroker, List<ListenableFuture<Void>> futures) {
80         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
81         IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
82         if (ifTunnel != null) {
83             addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, tx);
84         }
85         futures.add(tx.submit());
86     }
87
88     /*
89      *  add all tunnels ports corresponding to the bridge to the topology config DS
90      */
91     public static void addAllPortsToBridge(BridgeEntry bridgeEntry, DataBroker dataBroker,
92                                            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
93                                            OvsdbBridgeAugmentation bridgeNew,
94                                            List<ListenableFuture<Void>> futures){
95         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
96         String bridgeName = bridgeNew.getBridgeName().getValue();
97         LOG.debug("adding all ports to bridge: {}", bridgeName);
98         List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
99         if(bridgeInterfaceEntries != null) {
100             for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
101                 String portName = bridgeInterfaceEntry.getInterfaceName();
102                 InterfaceKey interfaceKey = new InterfaceKey(portName);
103                 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
104                 if (iface != null) {
105                     IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
106                     if (ifTunnel != null) {
107                         addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, writeTransaction);
108                     }
109                 } else {
110                     LOG.debug("Interface {} not found in config DS", portName);
111                 }
112             }
113         }
114         futures.add(writeTransaction.submit());
115     }
116
117     /*
118      *  add all tunnels ports corresponding to the bridge to the topology config DS
119      */
120     public static void removeAllPortsFromBridge(BridgeEntry bridgeEntry, DataBroker dataBroker,
121                                                 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
122                                                 OvsdbBridgeAugmentation bridgeNew,
123                                                 List<ListenableFuture<Void>> futures){
124         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
125         String bridgeName = bridgeNew.getBridgeName().getValue();
126         LOG.debug("removing all ports from bridge: {}", bridgeName);
127         List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
128         if(bridgeInterfaceEntries != null) {
129             for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
130                 String portName = bridgeInterfaceEntry.getInterfaceName();
131                 InterfaceKey interfaceKey = new InterfaceKey(portName);
132                 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
133                 if (iface != null) {
134                     IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
135                     if (ifTunnel != null) {
136                         removeTerminationEndPoint(futures, dataBroker, bridgeIid, iface.getName());
137                     }
138                 } else {
139                     LOG.debug("Interface {} not found in config DS", portName);
140                 }
141             }
142         }
143         futures.add(writeTransaction.submit());
144     }
145
146     private static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan, IfTunnel ifTunnel,
147                                             OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
148                                             String portName, DataBroker dataBroker, WriteTransaction t) {
149         if(ifL2vlan.getVlanId() != null) {
150             addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, ifL2vlan.getVlanId().getValue(), null, null,
151                     ifTunnel, t);
152         }
153     }
154
155     private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
156                                               OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
157                                               String portName, DataBroker dataBroker, WriteTransaction t) {
158         LOG.debug("adding tunnel port {} to bridge {}",portName, bridgeName);
159
160         Class<? extends InterfaceTypeBase> type = TUNNEL_TYPE_MAP.get(ifTunnel.getTunnelInterfaceType());
161
162         if (type == null) {
163             LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
164             return;
165         }
166
167         int vlanId = 0;
168         IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
169         if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
170             vlanId = ifL2vlan.getVlanId().getValue();
171         }
172
173         Map<String, String> options = Maps.newHashMap();
174         if((!ifTunnel.getTunnelInterfaceType().equals(TunnelTypeMplsOverGre.class) ) ){
175             options.put("key", "flow");
176         }
177
178         IpAddress localIp = ifTunnel.getTunnelSource();
179         options.put("local_ip", localIp.getIpv4Address().getValue());
180
181         IpAddress remoteIp = ifTunnel.getTunnelDestination();
182         options.put("remote_ip", remoteIp.getIpv4Address().getValue());
183
184         addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, ifTunnel, t);
185     }
186
187     // Update is allowed only for tunnel monitoring attributes
188     public static void updateBfdParamtersForTerminationPoint(InstanceIdentifier<?> bridgeIid, IfTunnel ifTunnel, String portName,
189                                                              WriteTransaction transaction){
190         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
191                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
192         LOG.debug("update bfd parameters for interface {}", tpIid);
193         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
194         List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
195         tpAugmentationBuilder.setInterfaceBfd(bfdParams);
196
197         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
198         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
199         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
200
201         transaction.merge(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
202     }
203
204     private static void addTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
205                                             String bridgeName, String portName, int vlanId, Class<? extends InterfaceTypeBase> type,
206                                             Map<String, String> options, IfTunnel ifTunnel, WriteTransaction t) {
207         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
208                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
209         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
210
211         tpAugmentationBuilder.setName(portName);
212
213         if (type != null) {
214             tpAugmentationBuilder.setInterfaceType(type);
215         }
216
217         if (options != null) {
218             List<Options> optionsList = new ArrayList<Options>();
219             for (Map.Entry<String, String> entry : options.entrySet()) {
220                 OptionsBuilder optionsBuilder = new OptionsBuilder();
221                 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
222                 optionsBuilder.setOption(entry.getKey());
223                 optionsBuilder.setValue(entry.getValue());
224                 optionsList.add(optionsBuilder.build());
225             }
226             tpAugmentationBuilder.setOptions(optionsList);
227         }
228
229         if (vlanId != 0) {
230             tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
231             tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
232         }
233
234
235         if(bfdMonitoringEnabled(ifTunnel)) {
236             List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
237             tpAugmentationBuilder.setInterfaceBfd(bfdParams);
238         }
239
240         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
241         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
242         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
243
244         t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
245
246     }
247
248     private static List<InterfaceBfd> getBfdParams(IfTunnel ifTunnel) {
249         List<InterfaceBfd> bfdParams = new ArrayList<>();
250         bfdParams.add(getIfBfdObj(BFD_PARAM_ENABLE,ifTunnel != null ? ifTunnel.isMonitorEnabled().toString() :"false"));
251         bfdParams.add(getIfBfdObj(BFD_PARAM_MIN_TX, ifTunnel != null ? ifTunnel.getMonitorInterval().toString() : BFD_MIN_TX_VAL));
252         bfdParams.add(getIfBfdObj(BFD_PARAM_MIN_RX, BFD_MIN_RX_VAL));
253         bfdParams.add(getIfBfdObj(BFD_PARAM_DECAY_MIN_RX, BFD_DECAY_MIN_RX_VAL));
254         bfdParams.add(getIfBfdObj(BFD_PARAM_FORWARDING_IF_RX, BFD_FORWARDING_IF_RX_VAL));
255         bfdParams.add(getIfBfdObj(BFD_PARAM_CPATH_DOWN, BFD_CPATH_DOWN_VAL));
256         bfdParams.add(getIfBfdObj(BFD_PARAM_CHECK_TNL_KEY, BFD_CHECK_TNL_KEY_VAL));
257         return bfdParams;
258     }
259
260     private static InterfaceBfd getIfBfdObj(String key, String value) {
261         InterfaceBfdBuilder bfdBuilder = new InterfaceBfdBuilder();
262         bfdBuilder.setBfdKey(key).
263                 setKey(new InterfaceBfdKey(key)).setBfdValue(value);
264         return bfdBuilder.build();
265     }
266
267     public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
268                                                                                                 String portName){
269         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
270                 .create(NetworkTopology.class)
271                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
272                 .child(Node.class,nodekey)
273                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
274
275         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
276         return terminationPointPath;
277     }
278
279     public static void removeTerminationEndPoint(List<ListenableFuture<Void>> futures, DataBroker dataBroker, InstanceIdentifier<?> bridgeIid,
280                                                  String interfaceName) {
281         LOG.debug("removing termination point for {}", interfaceName);
282         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
283         InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
284                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceName);
285         transaction.delete(LogicalDatastoreType.CONFIGURATION, tpIid);
286         futures.add(transaction.submit());
287     }
288
289     public static boolean bfdMonitoringEnabled(IfTunnel ifTunnel){
290         if(ifTunnel.isMonitorEnabled() && TunnelMonitoringTypeBfd.class.isAssignableFrom(ifTunnel.getMonitorProtocol())) {
291             return true;
292         }
293         return false;
294     }
295
296     public static boolean isMonitorProtocolBfd(IfTunnel ifTunnel){
297         if(TunnelMonitoringTypeBfd.class.isAssignableFrom(ifTunnel.getMonitorProtocol())) {
298             return true;
299         }
300         return false;
301
302     }
303 }