2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.vpnservice.interfacemgr.commons;
11 import com.google.common.base.Optional;
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.idmanager.IdManager;
17 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
18 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
19 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
20 import org.opendaylight.vpnservice.mdsalutil.*;
21 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnelBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeMplsOverGre;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 import java.math.BigInteger;
50 import java.util.ArrayList;
51 import java.util.List;
53 public class InterfaceManagerCommonUtils {
54 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
55 public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
56 DataBroker dataBroker) {
57 NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
58 InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
59 .child(Node.class, new NodeKey(nodeId))
60 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
62 Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
63 ncIdentifier, dataBroker);
64 if (!nodeConnectorOptional.isPresent()) {
67 return nodeConnectorOptional.get();
70 public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
71 InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
72 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
73 return interfaceInstanceIdentifierBuilder.build();
76 public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
77 InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
78 Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
79 if (!interfaceOptional.isPresent()) {
83 return interfaceOptional.get();
86 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) {
87 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
88 IfmUtil.buildStateInterfaceId(interfaceName);
89 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
90 IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
91 if (!ifStateOptional.isPresent()) {
95 return ifStateOptional.get();
97 public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
98 IfTunnel tunnel, BigInteger dpnId, long portNo, Interface iface, int ifIndex, int addOrRemoveFlow) {
99 LOG.debug("make tunnel ingress flow for {}",iface.getName());
100 String flowRef = InterfaceManagerCommonUtils.getTunnelInterfaceFlowRef(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, iface.getName());
101 List<MatchInfo> matches = new ArrayList<MatchInfo>();
102 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
103 if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
104 matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {
105 dpnId, BigInteger.valueOf(portNo) }));
106 mkInstructions.add(new InstructionInfo(
107 InstructionType.write_metadata, new BigInteger[] {
108 MetaDataUtil.getLportTagMetaData(ifIndex),
109 MetaDataUtil.METADATA_MASK_LPORT_TAG}));
110 short tableId = tunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class) ? NwConstants.L3_LFIB_TABLE :
111 tunnel.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.EXTERNAL_TUNNEL_TABLE;
112 mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] {tableId}));
115 BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
116 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
117 IfmConstants.DEFAULT_FLOW_PRIORITY, iface.getName(), 0, 0, COOKIE_VM_INGRESS_TABLE, matches, mkInstructions);
118 if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
119 futures.add(mdsalApiManager.installFlow(dpnId, flowEntity));
121 futures.add(mdsalApiManager.removeFlow(dpnId, flowEntity));
124 public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
125 return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
128 public static void setOpStateForInterface(DataBroker broker, String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
129 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil.buildStateInterfaceId(interfaceName);
130 InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setKey(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
131 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder.setOperStatus(opStatus).build();
132 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
135 public static void updateTunnelMonitorDetailsInConfigDS(DataBroker broker, String interfaceName, boolean monitorEnabled, long monitorInterval) {
136 InstanceIdentifier<Interface> id = IfmUtil.buildId(interfaceName);
137 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder ifaceBuilder = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder();
138 ifaceBuilder.setKey(new InterfaceKey(interfaceName));
139 IfTunnelBuilder ifTunnelBuilder = new IfTunnelBuilder();
140 ifTunnelBuilder.setMonitorEnabled(monitorEnabled);
141 ifTunnelBuilder.setMonitorInterval(monitorInterval);
142 ifaceBuilder.addAugmentation(IfTunnel.class, ifTunnelBuilder.build());
144 LOG.trace("Updating trunk interface {} in Config DS", interfaceName);
145 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, ifaceBuilder.build());
148 public static void createInterfaceParentEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t,
149 String parentInterface){
150 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
151 InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier =
152 InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
153 InterfaceParentEntry interfaceParentEntry =
154 InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
156 if(interfaceParentEntry != null){
157 LOG.info("Not Found entry for Parent Interface: {} in Vlan Trunk-Member Interface Renderer ConfigDS. " +
158 "Creating...", parentInterface);
159 InterfaceParentEntryBuilder interfaceParentEntryBuilder = new InterfaceParentEntryBuilder()
160 .setKey(interfaceParentEntryKey).setParentInterface(parentInterface);
161 t.put(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier,
162 interfaceParentEntryBuilder.build(), true);
166 public static void createInterfaceChildEntry( WriteTransaction t,
167 String parentInterface, String childInterface){
168 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
169 InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
170 InstanceIdentifier<InterfaceChildEntry> intfId =
171 InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
172 InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
173 .setChildInterface(childInterface);
174 t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true);
177 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus
178 updateStateEntry(Interface interfaceNew, DataBroker dataBroker, WriteTransaction transaction,
179 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
180 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus;
181 if (!interfaceNew.isEnabled()) {
182 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
184 String ncStr = ifState.getLowerLayerIf().get(0);
185 NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
186 NodeConnector nodeConnector =
187 InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
188 FlowCapableNodeConnector flowCapableNodeConnector =
189 nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
190 //State state = flowCapableNodeConnector.getState();
191 operStatus = flowCapableNodeConnector == null ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
194 String ifName = interfaceNew.getName();
195 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
196 IfmUtil.buildStateInterfaceId(interfaceNew.getName());
197 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
198 ifaceBuilder.setOperStatus(operStatus);
199 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
200 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
204 public static void updateOperStatus(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
205 WriteTransaction transaction) {
206 LOG.debug("updating operational status for interface {}",interfaceName);
207 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
208 IfmUtil.buildStateInterfaceId(interfaceName);
209 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
210 ifaceBuilderChild.setOperStatus(operStatus);
211 ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
212 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
215 public static void addStateEntry(String interfaceName, WriteTransaction transaction, DataBroker dataBroker, IdManagerService idManager,
216 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
217 LOG.debug("adding interface state for {}",interfaceName);
218 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = ifState.getOperStatus();
219 PhysAddress physAddress = ifState.getPhysAddress();
220 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus = ifState.getAdminStatus();
221 NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
222 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
223 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface interfaceInfo =
224 InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
226 if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
227 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
230 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
231 IfmUtil.buildStateInterfaceId(interfaceName);
232 List<String> childLowerLayerIfList = new ArrayList<>();
233 childLowerLayerIfList.add(0, nodeConnectorId.getValue());
234 InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
235 .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
237 Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
238 ifaceBuilder.setIfIndex(ifIndex);
240 if(interfaceInfo != null){
241 ifaceBuilder.setType(interfaceInfo.getType());
243 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
244 transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
246 // create lportTag Interface Map
247 InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
249 // install ingress flow
250 BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
251 long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
252 if(interfaceInfo.isEnabled() && ifState.getOperStatus() == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
253 List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, interfaceInfo);
254 FlowBasedServicesUtils.installVlanFlow(dpId, portNo, interfaceInfo, transaction, matches, ifIndex);
258 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
259 addStateEntry(Interface interfaceInfo, String portName, WriteTransaction transaction, IdManagerService idManager,
260 PhysAddress physAddress, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
261 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus,
262 NodeConnectorId nodeConnectorId) {
263 LOG.debug("adding interface state for {}",portName);
264 if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
265 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
267 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
268 IfmUtil.buildStateInterfaceId(portName);
269 List<String> childLowerLayerIfList = new ArrayList<>();
270 childLowerLayerIfList.add(0, nodeConnectorId.getValue());
271 InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
272 .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
274 Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, portName);
275 ifaceBuilder.setIfIndex(ifIndex);
277 if(interfaceInfo != null){
278 ifaceBuilder.setType(interfaceInfo.getType());
280 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
281 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder.build();
282 transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId,ifState , true);
284 // allocate lport tag and set in if-index
285 InterfaceMetaUtils.createLportTagInterfaceMap(transaction, portName, ifIndex);
289 public static void deleteStateEntry(String interfaceName, WriteTransaction transaction) {
290 LOG.debug("removing interface state for {}",interfaceName);
291 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
292 IfmUtil.buildStateInterfaceId(interfaceName);
293 transaction.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);