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
8 package org.opendaylight.vpnservice.interfacemgr;
10 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
12 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan;
18 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
19 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.Future;
29 import org.opendaylight.yangtools.yang.common.RpcResult;
30 import org.opendaylight.idmanager.IdManager;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
32 import java.util.ArrayList;
33 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
35 import java.util.List;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
39 import java.util.concurrent.ConcurrentHashMap;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
42 import com.google.common.util.concurrent.Futures;
43 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
45 import com.google.common.util.concurrent.FutureCallback;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
54 import org.opendaylight.vpnservice.AbstractDataChangeListener;
55 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
56 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
57 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
58 import org.opendaylight.yangtools.concepts.ListenerRegistration;
59 import org.opendaylight.yangtools.yang.binding.DataObject;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
62 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
63 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
64 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70 import com.google.common.base.Optional;
72 public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
73 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
74 private ListenerRegistration<DataChangeListener> listenerRegistration;
75 private final DataBroker broker;
76 private final IdManager idManager;
77 private final Map<NodeConnectorId, String> mapNcToInterfaceName = new ConcurrentHashMap<>();
78 private final Map<NodeId, String> dbDpnEndpoints = new ConcurrentHashMap<>();
80 private static final FutureCallback<Void> DEFAULT_CALLBACK =
81 new FutureCallback<Void>() {
82 public void onSuccess(Void result) {
83 LOG.debug("Success in Datastore write operation");
86 public void onFailure(Throwable error) {
87 LOG.error("Error in Datastore write operation", error);
91 public InterfaceManager(final DataBroker db, final IdManager idmgr) {
92 super(Interface.class);
99 public void close() throws Exception {
100 if (listenerRegistration != null) {
102 listenerRegistration.close();
103 } catch (final Exception e) {
104 LOG.error("Error when cleaning up DataChangeListener.", e);
106 listenerRegistration = null;
108 LOG.info("Interface Manager Closed");
111 private void registerListener(final DataBroker db) {
113 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
114 getWildCardPath(), InterfaceManager.this, DataChangeScope.SUBTREE);
115 } catch (final Exception e) {
116 LOG.error("InterfaceManager DataChange listener registration fail!", e);
117 throw new IllegalStateException("InterfaceManager registration Listener failed.", e);
122 protected void add(final InstanceIdentifier<Interface> identifier,
123 final Interface imgrInterface) {
124 LOG.trace("Adding interface key: " + identifier + ", value=" + imgrInterface );
125 addInterface(identifier, imgrInterface);
128 private InstanceIdentifier<Interface> buildId(final InstanceIdentifier<Interface> identifier) {
129 //TODO Make this generic and move to AbstractDataChangeListener or Utils.
130 final InterfaceKey key = identifier.firstKeyOf(Interface.class, InterfaceKey.class);
131 return buildId(key.getName());
134 private InstanceIdentifier<Interface> buildId(String interfaceName) {
135 //TODO Make this generic and move to AbstractDataChangeListener or Utils.
136 InstanceIdentifierBuilder<Interface> idBuilder =
137 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
138 InstanceIdentifier<Interface> id = idBuilder.build();
142 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
143 //TODO Make this generic and move to AbstractDataChangeListener or Utils.
144 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
145 InstanceIdentifier.builder(InterfacesState.class)
146 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
147 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
148 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
152 private void addInterface(final InstanceIdentifier<Interface> identifier,
153 final Interface interf) {
154 NodeConnector nodeConn = getNodeConnectorFromDataStore(interf);
155 NodeConnectorId ncId = null;
156 updateInterfaceState(identifier, interf, nodeConn);
157 if (nodeConn == null) {
158 ncId = getNodeConnectorIdFromInterface(interf);
160 ncId = nodeConn.getId();
162 mapNcToInterfaceName.put(ncId, interf.getName());
163 LOG.info("interf.getType(: {}",interf.getType());
164 if(interf.getType().isInstance(L3tunnel.class)) {
165 NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
166 IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
167 LOG.info("l3Tunnel: {}",l3Tunnel);
168 this.dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
172 private void updateInterfaceState(InstanceIdentifier<Interface> identifier,
173 Interface interf, NodeConnector nodeConn) {
174 /* Update InterfaceState
175 * 1. Get interfaces-state Identifier
176 * 2. Add interface to interfaces-state/interface
177 * 3. Get interface-id from id manager
178 * 4. Update interface-state with following:
179 * admin-status = set to enable value
180 * oper-status = Down [?]
181 * if-index = interface-id
183 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
184 buildStateInterfaceId(interf.getName());
185 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
186 read(LogicalDatastoreType.OPERATIONAL, id);
187 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
188 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
189 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
190 if(!stateIf.isPresent()) {
191 // TODO: Get interface-id from IdManager
192 String ifName = interf.getName();
193 ifaceBuilder.setAdminStatus((interf.isEnabled()) ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
194 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
195 ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
197 ifaceBuilder.setIfIndex(getIfIndex(ifName)).setName(ifName).setType(interf.getType());
198 ifaceBuilder.setKey(getStateInterfaceKeyFromName(ifName));
199 stateIface = ifaceBuilder.build();
200 LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id);
201 asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
203 if(interf.isEnabled() != null) {
204 ifaceBuilder.setAdminStatus((interf.isEnabled()) ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
205 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
207 if(interf.getType() != null) {
208 ifaceBuilder.setType(interf.getType());
210 ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
211 stateIface = ifaceBuilder.build();
212 LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id);
213 asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
218 private void setAugmentations(
219 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder,
220 InstanceIdentifier<Interface> identifier, Interface interf) {
221 // TODO Add code for all augmentations
222 InstanceIdentifier<IfL3tunnel> ifL3TunnelPath = identifier.augmentation(IfL3tunnel.class);
223 Optional<IfL3tunnel> l3Tunnel = read(LogicalDatastoreType.CONFIGURATION, ifL3TunnelPath);
224 String ifName = interf.getName();
225 if(l3Tunnel.isPresent()) {
231 private Integer getIfIndex(String ifName) {
232 GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
233 .setPoolName("interfaces").setIdKey(ifName)
235 //TODO: Proper error handling once IdManager code is complete
237 Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
238 RpcResult<GetUniqueIdOutput> rpcResult = result.get();
239 return rpcResult.getResult().getIdValue().intValue();
240 } catch (NullPointerException | InterruptedException | ExecutionException e) {
243 /* This currently returns null, so let us get it from IdManager DS
244 * TODO: Start-delete-me
247 InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
248 InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey("interfaces"));
249 InstanceIdentifier<IdPool> id = idBuilder.build();
250 Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id);
251 Long newIdValue = null;
252 if (globalPool.isPresent()) {
253 IdPool pool = globalPool.get();
254 List<GeneratedIds> generatedIds = pool.getGeneratedIds();
255 if ((generatedIds != null) && !generatedIds.isEmpty()) {
256 for (GeneratedIds gen_id : generatedIds) {
257 if (gen_id.getIdKey().equals(ifName)) {
258 newIdValue = gen_id.getIdValue();
259 LOG.debug("Id {} found for interface %s ", newIdValue, ifName);
260 return newIdValue.intValue();
265 //TODO: End-delete-me
266 LOG.debug("Unable to get valid ifIndex for interface {}", ifName);
270 private OperStatus getOperStatus(NodeConnector nodeConn) {
271 LOG.trace("nodeConn is {}", nodeConn);
272 if(nodeConn == null) {
273 return OperStatus.Down;
275 return OperStatus.Up;
279 private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
281 return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
284 private NodeConnector getNodeConnectorFromDataStore(Interface interf) {
285 NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
286 //TODO: Replace with MDSAL Util method
287 NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
288 InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
289 .child(Node.class, new NodeKey(nodeId))
290 .child(NodeConnector.class, new NodeConnectorKey(ncId)).build();
292 Optional<NodeConnector> nc = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
294 NodeConnector nodeConn = nc.get();
295 LOG.trace("nodeConnector: {}",nodeConn);
301 private NodeConnectorId getNodeConnectorIdFromInterface(Interface interf) {
302 return interf.getAugmentation(BaseIds.class).getOfPortId();
305 private void delInterface(final InstanceIdentifier<Interface> identifier,
306 final Interface delInterface) {
307 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
308 buildStateInterfaceId(delInterface.getName());
309 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
310 read(LogicalDatastoreType.OPERATIONAL, id);
311 if(stateIf.isPresent()) {
312 LOG.trace("deleting interfaces:state OPERATIONAL data store with id {}", id);
313 asyncRemove(LogicalDatastoreType.OPERATIONAL, id, DEFAULT_CALLBACK);
314 NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
316 mapNcToInterfaceName.remove(ncId);
317 if(delInterface.getType().isInstance(L3tunnel.class)) {
318 Node node = getNodeFromDataStore(delInterface);
319 if((node != null) &&(node.getNodeConnector().isEmpty())) {
320 this.dbDpnEndpoints.remove(node.getId());
327 private Node getNodeFromDataStore(Interface interf) {
328 NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
329 //TODO: Replace with MDSAL Util method
330 NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
331 InstanceIdentifier<Node> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
332 .child(Node.class, new NodeKey(nodeId)).build();
334 Optional<Node> dpn = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
335 if(dpn.isPresent()) {
336 Node node = dpn.get();
337 LOG.trace("node: {}",node);
343 private void updateInterface(final InstanceIdentifier<Interface> identifier,
344 final Interface original, final Interface update) {
345 InstanceIdentifier<Interface> id = buildId(identifier);
346 Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
347 if(port.isPresent()) {
348 Interface interf = port.get();
349 NodeConnector nc = getNodeConnectorFromDataStore(update);
350 updateInterfaceState(identifier, update, nc);
352 * Alternative is to get from interf and update map irrespective if NCID changed or not.
355 // Name doesn't change. Is it present in update?
356 mapNcToInterfaceName.put(nc.getId(), original.getName());
357 if(interf.getType().isInstance(L3tunnel.class)) {
358 NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
359 IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
360 this.dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
366 private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
367 InstanceIdentifier<T> path) {
369 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
371 Optional<T> result = Optional.absent();
373 result = tx.read(datastoreType, path).get();
374 } catch (Exception e) {
375 throw new RuntimeException(e);
381 private InstanceIdentifier<Interface> getWildCardPath() {
382 return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
386 protected void remove(InstanceIdentifier<Interface> identifier, Interface del) {
387 LOG.trace("remove - key: " + identifier + ", value=" + del );
388 delInterface(identifier, del);
392 protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
393 LOG.trace("update - key: " + identifier + ", original=" + original + ", update=" + update );
394 updateInterface(identifier, original, update);
397 private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
398 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
399 WriteTransaction tx = broker.newWriteOnlyTransaction();
400 tx.put(datastoreType, path, data, true);
401 Futures.addCallback(tx.submit(), callback);
404 private <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
405 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
406 WriteTransaction tx = broker.newWriteOnlyTransaction();
407 tx.merge(datastoreType, path, data, true);
408 Futures.addCallback(tx.submit(), callback);
411 private <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
412 InstanceIdentifier<T> path, FutureCallback<Void> callback) {
413 WriteTransaction tx = broker.newWriteOnlyTransaction();
414 tx.delete(datastoreType, path);
415 Futures.addCallback(tx.submit(), callback);
418 void processPortAdd(NodeConnector port) {
419 NodeConnectorId portId = port.getId();
420 FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
421 LOG.debug("PortAdd: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}");
422 String ifName = this.mapNcToInterfaceName.get(portId);
423 setInterfaceOperStatus(ifName, OperStatus.Up);
426 void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
427 //TODO: Currently nothing to do here.
428 LOG.trace("ifMap: {}, dpnMap: {}", mapNcToInterfaceName, dbDpnEndpoints);
431 void processPortDelete(NodeConnector port) {
432 NodeConnectorId portId = port.getId();
433 FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
434 LOG.debug("PortDelete: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}");
435 String ifName = this.mapNcToInterfaceName.get(portId);
436 setInterfaceOperStatus(ifName, OperStatus.Down);
439 private void setInterfaceOperStatus(String ifName, OperStatus opStatus) {
440 if (ifName != null) {
441 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
442 buildStateInterfaceId(ifName);
443 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
444 read(LogicalDatastoreType.OPERATIONAL, id);
445 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
446 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
447 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
448 if (stateIf.isPresent()) {
449 stateIface = ifaceBuilder.setOperStatus(opStatus).build();
450 LOG.trace("Setting OperStatus for {} to {} in OPERATIONAL DS", ifName, opStatus);
451 asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
456 private Interface getInterfaceByIfName(String ifName) {
457 InstanceIdentifier<Interface> id = buildId(ifName);
458 Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
459 if(port.isPresent()) {
465 Long getPortForInterface(String ifName) {
466 Interface iface = getInterfaceByIfName(ifName);
467 return getPortNumForInterface(iface);
470 long getDpnForInterface(String ifName) {
471 Interface iface = getInterfaceByIfName(ifName);
473 NodeConnector port = getNodeConnectorFromDataStore(iface);
474 //TODO: This should be an MDSAL Util method
475 return Long.parseLong(getDpnFromNodeConnectorId(port.getId()));
476 } catch (NullPointerException e) {
477 LOG.error("OFPort for Interface {} not found", ifName);
482 String getEndpointIpForDpn(long dpnId) {
483 //TODO: This should be MDSAL Util function
484 NodeId dpnNodeId = buildDpnNodeId(dpnId);
485 return dbDpnEndpoints.get(dpnNodeId);
488 List<MatchInfo> getInterfaceIngressRule(String ifName){
489 Interface iface = getInterfaceByIfName(ifName);
490 List<MatchInfo> matches = new ArrayList<MatchInfo>();
491 Class<? extends InterfaceType> ifType = iface.getType();
492 long dpn = this.getDpnForInterface(ifName);
493 long portNo = this.getPortNumForInterface(iface).longValue();
494 matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo}));
495 if(ifType.isInstance(L2vlan.class)) {
496 IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
497 matches.add(new MatchInfo(MatchFieldType.vlan_vid,
498 new long[] {vlanIface.getVlanId().longValue()}));
499 LOG.trace("L2Vlan: {}",vlanIface);
500 } else if (ifType.isInstance(L3tunnel.class)) {
501 //TODO: Handle different tunnel types
502 IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
503 Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
504 LOG.trace("L3Tunnel: {}",ifL3Tunnel);
505 } else if (ifType.isInstance(StackedVlan.class)) {
506 IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
507 LOG.trace("StackedVlan: {}",ifStackedVlan);
508 } else if (ifType.isInstance(Mpls.class)) {
509 IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
510 LOG.trace("Mpls: {}",ifMpls);
515 public List<InstructionInfo> getInterfaceEgressActions(String ifName) {
516 Interface iface = getInterfaceByIfName(ifName);
518 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
519 List<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
520 Class<? extends Class> ifType = iface.getType().getClass();
521 long dpn = this.getDpnForInterface(ifName);
522 long portNo = this.getPortNumForInterface(iface).longValue();
523 instructions.add(new InstructionInfo(InstructionType.apply_actions,
525 /*TODO: Refer getInterfaceIngressRules on how to get interface details
533 private String getDpnFromNodeConnectorId(NodeConnectorId portId) {
535 * NodeConnectorId is of form 'openflow:dpnid:portnum'
537 String[] split = portId.getValue().split(":");
541 private NodeId buildDpnNodeId(long dpnId) {
542 // TODO Auto-generated method stub
543 return new NodeId("openflow:" + dpnId);
546 private NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
547 return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
550 private Long getPortNumForInterface(Interface iface) {
552 NodeConnector port = getNodeConnectorFromDataStore(iface);
553 FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
554 return ofPort.getPortNumber().getUint32();
555 } catch (Exception e) {
556 LOG.error("OFPort for Interface {} not found", iface.getName());