34813d31b2c3b4109a1c5ff4b70c3826ec84c709
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / confighelpers / OvsInterfaceConfigAddHelper.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.confighelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.concurrent.Callable;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
18 import org.opendaylight.genius.interfacemanager.IfmConstants;
19 import org.opendaylight.genius.interfacemanager.IfmUtil;
20 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
21 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
22 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
23 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
24 import org.opendaylight.genius.mdsalutil.NwConstants;
25 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class OvsInterfaceConfigAddHelper {
44     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigAddHelper.class);
45
46     public static List<ListenableFuture<Void>> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
47                                                                 Interface interfaceNew, IdManagerService idManager,
48                                                                 AlivenessMonitorService alivenessMonitorService,
49                                                                 IMdsalApiManager mdsalApiManager) {
50         List<ListenableFuture<Void>> futures = new ArrayList<>();
51         WriteTransaction defaultConfigShardTransaction = dataBroker.newWriteOnlyTransaction();
52         WriteTransaction defaultOperShardTransaction = dataBroker.newWriteOnlyTransaction();
53         IfTunnel ifTunnel = interfaceNew.getAugmentation(IfTunnel.class);
54         if (ifTunnel != null) {
55             addTunnelConfiguration(dataBroker, parentRefs, interfaceNew, idManager, alivenessMonitorService, ifTunnel,
56                     mdsalApiManager, futures);
57         }else {
58             addVlanConfiguration(interfaceNew, parentRefs, dataBroker, idManager, defaultConfigShardTransaction,
59                     defaultOperShardTransaction, futures);
60         }
61         futures.add(defaultConfigShardTransaction.submit());
62         futures.add(defaultOperShardTransaction.submit());
63         return futures;
64     }
65
66     private static void addVlanConfiguration(Interface interfaceNew, ParentRefs parentRefs, DataBroker dataBroker, IdManagerService idManager,
67                                              WriteTransaction defaultConfigShardTransaction, WriteTransaction defaultOperShardTransaction,
68                                              List<ListenableFuture<Void>> futures) {
69         IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
70         if (ifL2vlan == null || IfL2vlan.L2vlanMode.Trunk != ifL2vlan.getL2vlanMode() && IfL2vlan.L2vlanMode.Transparent != ifL2vlan.getL2vlanMode()) {
71             return;
72         }
73         if (!InterfaceManagerCommonUtils.createInterfaceChildEntryIfNotPresent(dataBroker, defaultConfigShardTransaction,
74                 parentRefs.getParentInterface(), interfaceNew.getName(), ifL2vlan.getL2vlanMode())) {
75             return;
76         }
77         LOG.info("adding vlan configuration for interface {}",interfaceNew.getName());
78         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
79                 InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker);
80
81         InterfaceManagerCommonUtils.addStateEntry(interfaceNew.getName(), dataBroker, defaultOperShardTransaction,
82                 idManager, futures, ifState);
83
84         DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
85         VlanMemberStateAddWorker vlanMemberStateAddWorker = new VlanMemberStateAddWorker(dataBroker, idManager,
86                 interfaceNew.getName(), ifState);
87         coordinator.enqueueJob(interfaceNew.getName(), vlanMemberStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
88     }
89
90     private static void addTunnelConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
91                                                Interface interfaceNew, IdManagerService idManager,
92                                                AlivenessMonitorService alivenessMonitorService,
93                                                IfTunnel ifTunnel, IMdsalApiManager mdsalApiManager,
94                                                List<ListenableFuture<Void>> futures) {
95         if (parentRefs == null) {
96             LOG.warn("ParentRefs for interface: {} Not Found. " +
97                     "Creation of Tunnel OF-Port not supported when dpid not provided.", interfaceNew.getName());
98             return;
99         }
100
101         BigInteger dpId = parentRefs.getDatapathNodeIdentifier();
102         if (dpId == null) {
103             LOG.warn("dpid for interface: {} Not Found. No DPID provided. " +
104                     "Creation of OF-Port not supported.", interfaceNew.getName());
105             return;
106         }
107         LOG.info("adding tunnel configuration for interface {}", interfaceNew.getName());
108         boolean createTunnelPort = true;
109         String tunnelName = interfaceNew.getName();
110         if(SouthboundUtils.isOfTunnel(ifTunnel)) {
111             BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(dpId, dataBroker);
112             createTunnelPort = bridgeEntry == null || bridgeEntry.getBridgeInterfaceEntry() == null ?
113                     true : bridgeEntry.getBridgeInterfaceEntry().isEmpty();
114             tunnelName = SouthboundUtils.generateOfTunnelName(dpId, ifTunnel);
115             InterfaceManagerCommonUtils.createInterfaceChildEntry(tunnelName, interfaceNew.getName());
116         }
117
118         LOG.debug("creating bridge interfaceEntry in ConfigDS {}", dpId);
119         InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(dpId, interfaceNew.getName());
120
121         // create bridge on switch, if switch is connected
122         BridgeRefEntry bridgeRefEntry =
123                 InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpId, dataBroker);
124         if(bridgeRefEntry != null && bridgeRefEntry.getBridgeReference() != null) {
125             LOG.debug("creating bridge interface on dpn {}", dpId);
126             InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
127                     (InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry.getBridgeReference().getValue();
128             if(createTunnelPort) {
129                 SouthboundUtils.addPortToBridge(bridgeIid, interfaceNew, tunnelName, dataBroker, futures);
130             }
131
132             // if TEP is already configured on switch, start LLDP monitoring and program tunnel ingress flow
133             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
134                     InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker);
135             if(ifState != null){
136                 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
137                 if(ncId != null) {
138                     long portNo = IfmUtil.getPortNumberFromNodeConnectorId(ncId);
139                     InterfaceManagerCommonUtils.makeTunnelIngressFlow(futures, mdsalApiManager, ifTunnel,
140                             dpId, portNo, interfaceNew.getName(),
141                             ifState.getIfIndex(), NwConstants.ADD_FLOW);
142                     // start LLDP monitoring for the tunnel interface
143                     AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker,
144                             ifTunnel, interfaceNew.getName());
145                 }
146             }
147         }
148     }
149
150     private static class VlanMemberStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
151
152         private final DataBroker dataBroker;
153         private final IdManagerService idManager;
154         private final String interfaceName;
155         private final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState;
156
157         public VlanMemberStateAddWorker(DataBroker dataBroker, IdManagerService idManager, String interfaceName,
158                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
159             this.dataBroker = dataBroker;
160             this.idManager = idManager;
161             this.interfaceName = interfaceName;
162             this.ifState = ifState;
163         }
164
165         @Override
166         public List<ListenableFuture<Void>> call() {
167             InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(interfaceName);
168             InterfaceParentEntry interfaceParentEntry = InterfaceMetaUtils
169                     .getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
170             if (interfaceParentEntry == null || interfaceParentEntry.getInterfaceChildEntry() == null) {
171                 return null;
172             }
173
174             List<ListenableFuture<Void>> futures = new ArrayList<>();
175             WriteTransaction operShardTransaction = dataBroker.newWriteOnlyTransaction();
176             // FIXME: If the no. of child entries exceeds 100, perform txn
177             // updates in batches of 100.
178             for (InterfaceChildEntry interfaceChildEntry : interfaceParentEntry.getInterfaceChildEntry()) {
179                 LOG.debug("adding interface state for vlan trunk member {}", interfaceChildEntry.getChildInterface());
180                 InterfaceManagerCommonUtils.addStateEntry(interfaceChildEntry.getChildInterface(), dataBroker,
181                         operShardTransaction, idManager, futures, ifState);
182             }
183
184             futures.add(operShardTransaction.submit());
185             return futures;
186         }
187
188         @Override
189         public String toString() {
190             return "VlanMemberStateAddWorker [interfaceName=" + interfaceName + ", ifState=" + ifState + "]";
191         }
192     }
193 }