<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
<feature version='${openflowplugin.version}'>odl-openflowplugin-nsf-model</feature>
- <feature version="${ovsdb.version}">odl-ovsdb-southbound-api</feature>
<bundle>mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
</feature>
<feature name='odl-vpnservice-impl' version='${project.version}' description='OpenDaylight :: vpnservice :: impl '>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature version="${ovsdb.version}">odl-ovsdb-southbound-api</feature>
+ <feature version="${ovsdb.version}">odl-ovsdb-southbound-impl-rest</feature>
<feature version='${project.version}'>odl-vpnservice-api</feature>
<feature version="${openflowplugin.version}">odl-openflowplugin-southbound</feature>
<feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+@Deprecated
public interface IInterfaceManager {
-
+ @Deprecated
public Long getPortForInterface(String ifName);
+
+ @Deprecated
public BigInteger getDpnForInterface(String ifName);
+
+ @Deprecated
public BigInteger getDpnForInterface(Interface intrf);
+
+ @Deprecated
public String getEndpointIpForDpn(BigInteger dpnId);
+
+ @Deprecated
public List<MatchInfo> getInterfaceIngressRule(String ifName);
+
+ @Deprecated
public List<ActionInfo> getInterfaceEgressActions(String ifName);
+
+ @Deprecated
public Long getPortForInterface(Interface intf);
}
\ No newline at end of file
leaf interface-name {
type string;
}
- leaf tp-id-ref {
- type southbound:ovsdb-termination-point-ref;
- }
}
}
}
}
}
}
+
+ container interface-child-info {
+ description "The container of all Child-Interfaces for a given interface.";
+ list interface-parent-entry {
+ key parent-interface;
+ leaf parent-interface {
+ type string;
+ }
+
+ list interface-child-entry {
+ key child-interface;
+ leaf child-interface {
+ type string;
+ }
+ }
+ }
+ }
}
\ No newline at end of file
description "ODL Specific Interface Manager Rpcs Module";
}
-/* RPCs */
- rpc get-interface-from-lporttag {
- description "Used to retrieve the interface-name using lporttag";
- input {
- leaf lportag {
- type uint32;
- }
- }
- output {
- leaf intf-name {
- type string;
- }
- }
- }
-
- rpc get-lporttag-from-interface {
- description "Used to retrieve the lporttag from interface-name";
- input {
- leaf intf-name {
- type string;
- }
- }
- output {
- leaf lportag {
- type uint32;
- }
- }
- }
-
- rpc get-interface-from-groupid {
- description "Used to retrieve the interface-name using groupid";
- input {
- leaf groupid {
- type uint32;
- }
- }
- output {
- leaf intf-name {
- type string;
- }
- }
- }
-
- rpc get-groupid-from-interface {
- description "Used to retrieve the interface-name using groupid";
- input {
- leaf intf-name {
- type string;
- }
- }
- output {
- leaf groupid {
- type uint32;
- }
- }
- }
+ /* RPCs */
rpc get-dpid-from-interface {
description "used to retrieve dpid from interface name";
}
}
- leaf interface-name {
- type string;
- }
-
leaf service-name {
type string;
}
prefix inv; revision-date 2013-08-19;
}
+ import opendaylight-l2-types { prefix ethertype; revision-date "2013-08-27";}
+
import config {
prefix config; revision-date 2013-04-05;
}
reference "MPLS interface";
}
+ /* Tunnel (GRE, VxLAN) logical port */
identity l3tunnel {
status deprecated;
base if:interface-type;
- reference
- "l3 tunnel interface";
+ reference "l3 tunnel interface";
}
- /* Tunnel (GRE, VxLAN) logical port */
identity tunnel-type-base {
description "Base identity for all tunnel-types";
}
ext:augment-identifier "if-l2vlan";
when "if:type = 'ianaift:l2vlan'";
leaf vlan-id {
- type uint16 {
- range "1..4094";
+ type ethertype:vlan-id;
+ }
+
+ leaf l2vlan-mode {
+ description "The VLAN mode of the L2Vlan Interface.";
+ type enumeration {
+ enum "access" {
+ value 1;
+ description
+ "The VLAN mode access.";
+ }
+ enum "native-tagged" {
+ value 2;
+ description
+ "The VLAN mode native-tagged.";
+ }
+ enum "native-untagged" {
+ value 3;
+ description
+ "The VLAN mode native-untagged.";
+ }
+ enum "trunk" {
+ value 4;
+ description
+ "The VLAN mode trunk.";
+ }
+ enum "trunk-member" {
+ value 5;
+ description
+ "The VLAN mode trunk-member.";
+ }
+ enum "transparent" {
+ value 6;
+ description
+ "The VLAN mode transparent.";
+ }
}
}
}
base tunnel-type-base;
}
}
+
leaf local-ip {
type inet:ip-address;
description "Local Endpoint IP address";
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
</broker>
+ <rpc-registry>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
</module>
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
public static final String OF_URI_PREFIX = "openflow:";
public static final String OF_URI_SEPARATOR = ":";
public static final int DEFAULT_IFINDEX = 65536;
+ public static final String IFM_LPORT_TAG_IDPOOL_NAME = "vlaninterfaces.lporttag";
+ public static final short VLAN_INTERFACE_INGRESS_TABLE = 0;
}
package org.opendaylight.vpnservice.interfacemgr;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
InstanceIdentifier.builder(InterfacesState.class)
.child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
- new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
return id;
}
InstanceIdentifier<IdPool> id = idBuilder.build();
return id;
}
+
+ public static List<String> getPortNameAndSuffixFromInterfaceName(String intfName) {
+ List<String> strList = new ArrayList<>(2);
+ int index = intfName.indexOf(":");
+ if (index != -1) {
+ strList.add(0, intfName.substring(0, index));
+ strList.add(1, intfName.substring(index));
+ }
+ return strList;
+ }
+
+ public static List<String> getDpIdPortNameAndSuffixFromInterfaceName(String intfName) {
+ List<String> strList = new ArrayList<>(3);
+ int index1 = intfName.indexOf(":");
+ if (index1 != -1) {
+ int index2 = intfName.indexOf(":", index1 + 1 );
+ strList.add(0, intfName.substring(0, index1));
+ if (index2 != -1) {
+ strList.add(1, intfName.substring(index1, index2));
+ strList.add(2, intfName.substring(index2));
+ } else {
+ strList.add(1, intfName.substring(index1));
+ strList.add(2, "");
+ }
+ }
+ return strList;
+ }
+
+ public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, DataBroker broker) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+ return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+ }
+
+ public static BigInteger[] mergeOpenflowMetadataWriteInstructions(List<Instruction> instructions) {
+ BigInteger metadata = new BigInteger("0", 16);
+ BigInteger metadataMask = new BigInteger("0", 16);
+ if (instructions != null && !instructions.isEmpty()) {
+ // check if metadata write instruction is present
+ for (Instruction instruction : instructions) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction actualInstruction = instruction.getInstruction();
+ if (actualInstruction instanceof WriteMetadataCase) {
+ WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction ;
+ WriteMetadata availableMetaData = writeMetaDataInstruction.getWriteMetadata();
+ metadata = metadata.or(availableMetaData.getMetadata());
+ metadataMask = metadataMask.or(availableMetaData.getMetadataMask());
+ }
+ }
+ }
+ return new BigInteger[] { metadata, metadataMask };
+ }
+
+
+
}
*/
package org.opendaylight.vpnservice.interfacemgr;
-import java.math.BigInteger;
-
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
ncId = nodeConn.getId();
}
mapNcToInterfaceName.put(ncId, interf.getName());
- if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+ if(interf.getType().isAssignableFrom(Tunnel.class)) {
NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
- IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
- dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+ IfTunnel tunnel = interf.getAugmentation(IfTunnel.class);
+ dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue());
LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
}
}
NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
if(ncId != null) {
mapNcToInterfaceName.remove(ncId);
- if(delInterface.getType().isAssignableFrom(L3tunnel.class)) {
+ if(delInterface.getType().isAssignableFrom(Tunnel.class)) {
NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
dbDpnEndpoints.remove(nodeId);
LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
if(nc != null) {
// Name doesn't change. Is it present in update?
mapNcToInterfaceName.put(nc.getId(), original.getName());
- if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+ if(interf.getType().isAssignableFrom(Tunnel.class)) {
NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
- IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
- dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+ IfTunnel tunnel = interf.getAugmentation(IfTunnel.class);
+ dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue());
LOG.trace("dbEndpoints: {}",dbDpnEndpoints);
}
}
if (ifType.isInstance(L2vlan.class)) {
IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
- long vlanVid = vlanIface.getVlanId().longValue();
+ long vlanVid = vlanIface.getVlanId().getValue().longValue();
if (vlanVid != 0) {
matches.add(new MatchInfo(MatchFieldType.vlan_vid,
new long[] {vlanVid}));
LOG.trace("L2Vlan: {}",vlanIface);
}
- } else if (ifType.isInstance(L3tunnel.class)) {
+ } else if (ifType.isInstance(Tunnel.class)) {
//TODO: Handle different tunnel types
- IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
- Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
- LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+ IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+ Class<? extends TunnelTypeBase> tunnType = ifTunnel.getTunnelInterfaceType();
+ LOG.trace("L3Tunnel: {}",ifTunnel);
} else if (ifType.isAssignableFrom(StackedVlan.class)) {
IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
LOG.trace("StackedVlan: {}",ifStackedVlan);
if(ifType.isAssignableFrom(L2vlan.class)) {
IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
LOG.trace("L2Vlan: {}",vlanIface);
- long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId();
+ long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue().longValue();
if (vlanVid != 0) {
listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
}
listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
- } else if (ifType.isAssignableFrom(L3tunnel.class)) {
+ } else if (ifType.isAssignableFrom(Tunnel.class)) {
//TODO: Handle different tunnel types
- IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
- Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
- LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+ IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+ Class<? extends TunnelTypeBase> tunnType = ifTunnel.getTunnelInterfaceType();
+ LOG.trace("L3Tunnel: {}",ifTunnel);
//TODO: check switch_type and configure accordingly
listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
*/
package org.opendaylight.vpnservice.interfacemgr;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-
-import java.math.BigInteger;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceConfigListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceInventoryStateListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceTopologyStateListener;
import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.interfacemgr.rpcservice.InterfaceManagerRpcService;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesConfigListener;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesInterfaceStateListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.VlanMemberConfigListener;
import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager {
private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
+ private RpcProviderRegistry rpcProviderRegistry;
+
private InterfaceManager interfaceManager;
private IfmNodeConnectorListener ifmNcListener;
private IdManager idManager;
+ private InterfaceConfigListener interfaceConfigListener;
+ private InterfaceTopologyStateListener topologyStateListener;
+ private InterfaceInventoryStateListener interfaceInventoryStateListener;
+ private FlowBasedServicesInterfaceStateListener flowBasedServicesInterfaceStateListener;
+ private FlowBasedServicesConfigListener flowBasedServicesConfigListener;
+ private VlanMemberConfigListener vlanMemberConfigListener;
+
+ private InterfaceManagerRpcService interfaceManagerRpcService;
+ private BindingAwareBroker.RpcRegistration<OdlInterfaceRpcService> rpcRegistration;
+
+ public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) {
+ this.rpcProviderRegistry = rpcProviderRegistry;
+ }
+
@Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("InterfacemgrProvider Session Initiated");
try {
final DataBroker dataBroker = session.getSALService(DataBroker.class);
idManager = new IdManager(dataBroker);
- interfaceManager = new InterfaceManager(dataBroker, idManager);
- ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);
createIdPool();
+
+ interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker);
+ rpcRegistration = getRpcProviderRegistry().addRpcImplementation(
+ OdlInterfaceRpcService.class, interfaceManagerRpcService);
+
+ interfaceConfigListener = new InterfaceConfigListener(dataBroker, idManager);
+ interfaceConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+ interfaceInventoryStateListener = new InterfaceInventoryStateListener(dataBroker);
+ interfaceInventoryStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+ topologyStateListener = new InterfaceTopologyStateListener(dataBroker);
+ topologyStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+ flowBasedServicesConfigListener = new FlowBasedServicesConfigListener(dataBroker);
+ flowBasedServicesConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+ flowBasedServicesInterfaceStateListener =
+ new FlowBasedServicesInterfaceStateListener(dataBroker);
+ flowBasedServicesInterfaceStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+ vlanMemberConfigListener =
+ new VlanMemberConfigListener(dataBroker, idManager);
+ vlanMemberConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+
+ /*interfaceManager = new InterfaceManager(dataBroker, idManager);
+ ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);*/
} catch (Exception e) {
LOG.error("Error initializing services", e);
}
LOG.info("InterfacemgrProvider Closed");
interfaceManager.close();
ifmNcListener.close();
+ interfaceConfigListener.close();
+ rpcRegistration.close();
+ }
+
+ public RpcProviderRegistry getRpcProviderRegistry() {
+ return rpcProviderRegistry;
}
@Override
public Long getPortForInterface(String ifName) {
- return interfaceManager.getPortForInterface(ifName);
+ GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
+ Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
+ try {
+ RpcResult<GetPortFromInterfaceOutput> port = output.get();
+ if(port.isSuccessful()){
+ return port.getResult().getPortno();
+ }
+ }catch(NullPointerException | InterruptedException | ExecutionException e){
+ LOG.warn("Exception when getting port for interface",e);
+ }
+ return null;
}
@Override
public Long getPortForInterface(Interface intf) {
- return interfaceManager.getPortForInterface(intf);
+ GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
+ Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
+ try {
+ RpcResult<GetPortFromInterfaceOutput> port = output.get();
+ if(port.isSuccessful()){
+ return port.getResult().getPortno();
+ }
+ }catch(NullPointerException | InterruptedException | ExecutionException e){
+ LOG.warn("Exception when getting port for interface",e);
+ }
+ return null;
}
-
@Override
public BigInteger getDpnForInterface(String ifName) {
- return interfaceManager.getDpnForInterface(ifName);
+ GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
+ Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
+ try {
+ RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
+ if(dpn.isSuccessful()){
+ return dpn.getResult().getDpid();
+ }
+ }catch(NullPointerException | InterruptedException | ExecutionException e){
+ LOG.warn("Exception when getting port for interface",e);
+ }
+ return null;
}
@Override
public String getEndpointIpForDpn(BigInteger dpnId) {
- return interfaceManager.getEndpointIpForDpn(dpnId);
+ GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
+ Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
+ try {
+ RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
+ if(ipForDpnOutputRpcResult.isSuccessful()){
+ List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
+ if(!localIps.isEmpty()) {
+ return localIps.get(0).getIpv4Address().getValue();
+ }
+ }
+ }catch(NullPointerException | InterruptedException | ExecutionException e){
+ LOG.warn("Exception when getting port for interface",e);
+ }
+ return null;
}
@Override
@Override
public List<ActionInfo> getInterfaceEgressActions(String ifName) {
- return interfaceManager.getInterfaceEgressActions(ifName);
+ return interfaceManagerRpcService.getEgressActionInfosForInterface(ifName);
}
@Override
public BigInteger getDpnForInterface(Interface intrf) {
- // TODO Auto-generated method stub
- return interfaceManager.getDpnForInterface(intrf);
+ return getDpnForInterface(intrf.getName());
}
-}
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.commons;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class InterfaceManagerCommonUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
+ public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
+ DataBroker dataBroker) {
+ NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+ InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId))
+ .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
+
+ Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
+ ncIdentifier, dataBroker);
+ if (!nodeConnectorOptional.isPresent()) {
+ return null;
+ }
+ return nodeConnectorOptional.get();
+ }
+
+ /*public static void addInterfaceEntryToInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag, String interfaceName,
+ DataBroker dataBroker, WriteTransaction t) {
+ NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+ TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+ InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId))
+ .augmentation(TunnelInterfaceNames.class)
+ .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+ TunnelInterfaceInventoryInfoBuilder builder = new TunnelInterfaceInventoryInfoBuilder().setKey(tunnelInterfaceInventoryInfoKey)
+ .setTunIntfName(interfaceName);
+ t.put(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier, builder.build(), true);
+ }
+
+ public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag,
+ String interfaceName, DataBroker dataBroker,
+ WriteTransaction t) {
+ NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+ TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+ InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId))
+ .augmentation(TunnelInterfaceNames.class)
+ .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+ t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier);
+ }
+
+ public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag,
+ DataBroker dataBroker) {
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+ TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+ InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId))
+ .augmentation(TunnelInterfaceNames.class)
+ .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+ t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier);
+ t.submit(); // This is a Best-Effort Deletion. If Node is already removed, this may fail.
+ } */
+
+ public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
+ return interfaceInstanceIdentifierBuilder.build();
+ }
+
+ public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
+ InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
+ Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
+ if (!interfaceOptional.isPresent()) {
+ return null;
+ }
+
+ return interfaceOptional.get();
+ }
+
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceName);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
+ if (!ifStateOptional.isPresent()) {
+ return null;
+ }
+
+ return ifStateOptional.get();
+ }
+
+ public static Integer getUniqueId(IdManager idManager, String idKey) {
+ GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+ .setPoolName(IfmConstants.IFM_LPORT_TAG_IDPOOL_NAME)
+ .setIdKey(idKey).build();
+
+ try {
+ Future<RpcResult<GetUniqueIdOutput>> result = idManager.
+ getUniqueId(getIdInput);
+ RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+ if(rpcResult.isSuccessful()) {
+ return rpcResult.getResult().getIdValue().intValue();
+ } else {
+ LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
+ }
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.warn("Exception when getting Unique Id",e);
+ }
+ return 0;
+ }
+
+ public static String getJobKey(String dpId, String portName) {
+ String jobKey = "";
+ if (dpId != null && !"".equals(dpId)) {
+ jobKey = dpId.toString() + ":";
+ }
+ jobKey = jobKey + portName;
+ return jobKey;
+ }
+
+ public static String getJobKey(BigInteger dpId, String portName) {
+ String jobKey = "";
+ if (dpId != null && dpId.longValue() != 0) {
+ jobKey = dpId.toString() + ":";
+ }
+ jobKey = jobKey + portName;
+ return jobKey;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.commons;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeInterfaceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeRefInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class InterfaceMetaUtils {
+ public static InstanceIdentifier<BridgeRefEntry> getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<BridgeRefEntry> bridgeRefEntryInstanceIdentifierBuilder =
+ InstanceIdentifier.builder(BridgeRefInfo.class)
+ .child(BridgeRefEntry.class, bridgeRefEntryKey);
+ return bridgeRefEntryInstanceIdentifierBuilder.build();
+ }
+
+ public static BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid,
+ DataBroker dataBroker) {
+ Optional<BridgeRefEntry> bridgeRefEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnBridgeEntryIid, dataBroker);
+ if (!bridgeRefEntryOptional.isPresent()) {
+ return null;
+ }
+ return bridgeRefEntryOptional.get();
+ }
+
+ public static InstanceIdentifier<BridgeEntry> getBridgeEntryIdentifier(BridgeEntryKey bridgeEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<BridgeEntry> bridgeEntryIdBuilder =
+ InstanceIdentifier.builder(BridgeInterfaceInfo.class).child(BridgeEntry.class, bridgeEntryKey);
+ return bridgeEntryIdBuilder.build();
+ }
+
+ public static BridgeEntry getBridgeEntryFromConfigDS(InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier,
+ DataBroker dataBroker) {
+ Optional<BridgeEntry> bridgeEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, dataBroker);
+ if (!bridgeEntryOptional.isPresent()) {
+ return null;
+ }
+ return bridgeEntryOptional.get();
+ }
+
+ public static InstanceIdentifier<BridgeInterfaceEntry> getBridgeInterfaceEntryIdentifier(BridgeEntryKey bridgeEntryKey,
+ BridgeInterfaceEntryKey bridgeInterfaceEntryKey) {
+ return InstanceIdentifier.builder(BridgeInterfaceInfo.class)
+ .child(BridgeEntry.class, bridgeEntryKey)
+ .child(BridgeInterfaceEntry.class, bridgeInterfaceEntryKey).build();
+
+ }
+
+ public static BridgeInterfaceEntry getBridgeInterfaceEntryFromConfigDS(
+ InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryInstanceIdentifier, DataBroker dataBroker) {
+ Optional<BridgeInterfaceEntry> bridgeInterfaceEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryInstanceIdentifier, dataBroker);
+ if (!bridgeInterfaceEntryOptional.isPresent()) {
+ return null;
+ }
+ return bridgeInterfaceEntryOptional.get();
+ }
+
+
+ public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey,
+ BridgeInterfaceEntryKey bridgeInterfaceEntryKey,
+ String childInterface,
+ WriteTransaction t) {
+ InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+ InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey);
+ BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey)
+ .setInterfaceName(childInterface);
+ t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true);
+ }
+
+ public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey,
+ BridgeInterfaceEntryKey bridgeInterfaceEntryKey,
+ String childInterface,
+ InstanceIdentifier<TerminationPoint> tpIid,
+ WriteTransaction t) {
+ if (tpIid == null) {
+ createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey, childInterface, t);
+ return;
+ }
+
+ InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+ InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey);
+ BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey)
+ .setInterfaceName(childInterface);
+ t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true);
+ }
+
+ public static InstanceIdentifier<InterfaceParentEntry> getInterfaceParentEntryIdentifier(
+ InterfaceParentEntryKey interfaceParentEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<InterfaceParentEntry> intfIdBuilder =
+ InstanceIdentifier.builder(InterfaceChildInfo.class)
+ .child(InterfaceParentEntry.class, interfaceParentEntryKey);
+ return intfIdBuilder.build();
+ }
+
+ public static InstanceIdentifier<InterfaceChildEntry> getInterfaceChildEntryIdentifier(
+ InterfaceParentEntryKey interfaceParentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<InterfaceChildEntry> intfIdBuilder =
+ InstanceIdentifier.builder(InterfaceChildInfo.class)
+ .child(InterfaceParentEntry.class, interfaceParentEntryKey)
+ .child(InterfaceChildEntry.class, interfaceChildEntryKey);
+ return intfIdBuilder.build();
+ }
+
+ public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS(
+ InterfaceParentEntryKey interfaceParentEntryKey, DataBroker dataBroker) {
+ InstanceIdentifier<InterfaceParentEntry> intfParentIid =
+ getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+
+ return getInterfaceParentEntryFromConfigDS(intfParentIid, dataBroker);
+ }
+
+ public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS(
+ InstanceIdentifier<InterfaceParentEntry> intfId, DataBroker dataBroker) {
+ Optional<InterfaceParentEntry> interfaceParentEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfId, dataBroker);
+ if (!interfaceParentEntryOptional.isPresent()) {
+ return null;
+ }
+ return interfaceParentEntryOptional.get();
+ }
+
+ public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(InterfaceParentEntryKey interfaceParentEntryKey,
+ InterfaceChildEntryKey interfaceChildEntryKey,
+ DataBroker dataBroker) {
+ InstanceIdentifier<InterfaceChildEntry> intfChildIid =
+ getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+
+ return getInterfaceChildEntryFromConfigDS(intfChildIid, dataBroker);
+ }
+
+ public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(
+ InstanceIdentifier<InterfaceChildEntry> intfChildIid, DataBroker dataBroker) {
+ Optional<InterfaceChildEntry> interfaceChildEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfChildIid, dataBroker);
+ if (!interfaceChildEntryOptional.isPresent()) {
+ return null;
+ }
+ return interfaceChildEntryOptional.get();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * This class listens for interface creation/removal/update in Configuration DS.
+ * This is used to handle interfaces for base of-ports.
+ */
+public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Interface, InterfaceConfigListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class);
+ private DataBroker dataBroker;
+ private IdManager idManager;
+
+ public InterfaceConfigListener(final DataBroker dataBroker, final IdManager idManager) {
+ super(Interface.class, InterfaceConfigListener.class);
+ this.dataBroker = dataBroker;
+ this.idManager = idManager;
+ }
+
+ @Override
+ protected InstanceIdentifier<Interface> getWildCardPath() {
+ return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+ }
+
+ @Override
+ protected InterfaceConfigListener getDataTreeChangeListener() {
+ return InterfaceConfigListener.this;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
+ LOG.debug("Received Interface Remove Event: {}, {}", key, interfaceOld);
+ String ifName = interfaceOld.getName();
+ String parentInterface = null;
+
+ ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class);
+ if (parentRefs != null) {
+ parentInterface = parentRefs.getParentInterface();
+ if (parentInterface != null && !parentInterface.equals(ifName)) {
+ return;
+ }
+ if (parentRefs.getDatapathNodeIdentifier() == null) {
+ return;
+ }
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, interfaceOld, ifName, parentRefs);
+ coordinator.enqueueJob(ifName, configWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
+ LOG.debug("Received Interface Update Event: {}, {}, {}", key, interfaceOld, interfaceNew);
+ String ifNameNew = interfaceNew.getName();
+ String parentInterface = null;
+
+ ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+ if (parentRefs != null) {
+ parentInterface = parentRefs.getParentInterface();
+ }
+
+ if (parentInterface != null && !parentInterface.equals(ifNameNew)) {
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigUpdateWorker worker = new RendererConfigUpdateWorker(key, interfaceOld, interfaceNew, ifNameNew);
+ coordinator.enqueueJob(ifNameNew, worker);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
+ LOG.debug("Received Interface Add Event: {}, {}", key, interfaceNew);
+ String ifName = interfaceNew.getName();
+ String parentInterface = null;
+
+ ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+ if (parentRefs != null) {
+ parentInterface = parentRefs.getParentInterface();
+ }
+
+ if (parentInterface != null && !parentInterface.equals(ifName)) {
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifName);
+ coordinator.enqueueJob(ifName, configWorker);
+ }
+
+ private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceNew;
+ String portName;
+ ParentRefs parentRefs;
+
+ public RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+ ParentRefs parentRefs, String portName) {
+ this.key = key;
+ this.interfaceNew = interfaceNew;
+ this.portName = portName;
+ this.parentRefs = parentRefs;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, idManager);
+ }
+
+ @Override
+ public String toString() {
+ return "RendererConfigAddWorker{" +
+ "key=" + key +
+ ", interfaceNew=" + interfaceNew +
+ ", portName='" + portName + '\'' +
+ '}';
+ }
+ }
+
+ /**
+ *
+ */
+ private class RendererConfigUpdateWorker implements Callable {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceOld;
+ Interface interfaceNew;
+ String portNameNew;
+
+ public RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceOld,
+ Interface interfaceNew, String portNameNew) {
+ this.key = key;
+ this.interfaceOld = interfaceOld;
+ this.interfaceNew = interfaceNew;
+ this.portNameNew = portNameNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, idManager, interfaceNew, interfaceOld);
+ }
+
+ @Override
+ public String toString() {
+ return "RendererConfigUpdateWorker{" +
+ "key=" + key +
+ ", interfaceOld=" + interfaceOld +
+ ", interfaceNew=" + interfaceNew +
+ ", portNameNew='" + portNameNew + '\'' +
+ '}';
+ }
+ }
+
+ /**
+ *
+ */
+ private class RendererConfigRemoveWorker implements Callable {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceOld;
+ String portName;
+ ParentRefs parentRefs;
+
+ public RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld, String portName,
+ ParentRefs parentRefs) {
+ this.key = key;
+ this.interfaceOld = interfaceOld;
+ this.portName = portName;
+ this.parentRefs = parentRefs;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager, parentRefs);
+ }
+
+ @Override
+ public String toString() {
+ return "RendererConfigRemoveWorker{" +
+ "key=" + key +
+ ", interfaceOld=" + interfaceOld +
+ ", portName='" + portName + '\'' +
+ '}';
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.Callable;
+
+/**
+ *
+ * This Class is a Data Change Listener for FlowCapableNodeConnector updates.
+ * This creates an entry in the interface-state OperDS for every node-connector used.
+ *
+ * NOTE: This class just creates an ifstate entry whose interface-name will be the same as the node-connector portname.
+ * If PortName is not unique across DPNs, this implementation can have problems.
+ */
+
+public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase<FlowCapableNodeConnector, InterfaceInventoryStateListener> implements AutoCloseable{
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceInventoryStateListener.class);
+ private DataBroker dataBroker;
+
+ public InterfaceInventoryStateListener(final DataBroker dataBroker) {
+ super(FlowCapableNodeConnector.class, InterfaceInventoryStateListener.class);
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
+ .augmentation(FlowCapableNodeConnector.class);
+ }
+
+ @Override
+ protected DataChangeListener getDataChangeListener() {
+ return InterfaceInventoryStateListener.this;
+ }
+
+ @Override
+ protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
+ return AsyncDataBroker.DataChangeScope.BASE;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<FlowCapableNodeConnector> key,
+ FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+ LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnectorOld);
+ String portName = flowCapableNodeConnectorOld.getName();
+ NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
+ InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(key,
+ flowCapableNodeConnectorOld, portName);
+ coordinator.enqueueJob(portName, interfaceStateRemoveWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorOld,
+ FlowCapableNodeConnector fcNodeConnectorNew) {
+ LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew);
+ String portName = fcNodeConnectorNew.getName();
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
+ InterfaceStateUpdateWorker interfaceStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld,
+ fcNodeConnectorNew, portName);
+ coordinator.enqueueJob(portName, interfaceStateUpdateWorker);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorNew) {
+ LOG.debug("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew);
+ String portName = fcNodeConnectorNew.getName();
+ NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ InterfaceStateAddWorker ifStateAddWorker = new InterfaceStateAddWorker(nodeConnectorId,
+ fcNodeConnectorNew, portName);
+ coordinator.enqueueJob(portName, ifStateAddWorker);
+ }
+
+ private class InterfaceStateAddWorker implements Callable {
+ private final NodeConnectorId nodeConnectorId;
+ private final FlowCapableNodeConnector fcNodeConnectorNew;
+ private final String portName;
+
+ public InterfaceStateAddWorker(NodeConnectorId nodeConnectorId,
+ FlowCapableNodeConnector fcNodeConnectorNew,
+ String portName) {
+ this.nodeConnectorId = nodeConnectorId;
+ this.fcNodeConnectorNew = fcNodeConnectorNew;
+ this.portName = portName;
+ }
+
+ @Override
+ public Object call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceStateAddHelper.addState(dataBroker, nodeConnectorId,
+ portName, fcNodeConnectorNew);
+ }
+
+ @Override
+ public String toString() {
+ return "InterfaceStateAddWorker{" +
+ "nodeConnectorId=" + nodeConnectorId +
+ ", fcNodeConnectorNew=" + fcNodeConnectorNew +
+ ", portName='" + portName + '\'' +
+ '}';
+ }
+ }
+
+ private class InterfaceStateUpdateWorker implements Callable {
+ private InstanceIdentifier<FlowCapableNodeConnector> key;
+ private final FlowCapableNodeConnector fcNodeConnectorOld;
+ private final FlowCapableNodeConnector fcNodeConnectorNew;
+ private String portName;
+
+
+ public InterfaceStateUpdateWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
+ FlowCapableNodeConnector fcNodeConnectorOld,
+ FlowCapableNodeConnector fcNodeConnectorNew,
+ String portName) {
+ this.key = key;
+ this.fcNodeConnectorOld = fcNodeConnectorOld;
+ this.fcNodeConnectorNew = fcNodeConnectorNew;
+ this.portName = portName;
+ }
+
+ @Override
+ public Object call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceStateUpdateHelper.updateState(key, dataBroker, portName,
+ fcNodeConnectorNew, fcNodeConnectorOld);
+ }
+
+ @Override
+ public String toString() {
+ return "InterfaceStateUpdateWorker{" +
+ "key=" + key +
+ ", fcNodeConnectorOld=" + fcNodeConnectorOld +
+ ", fcNodeConnectorNew=" + fcNodeConnectorNew +
+ ", portName='" + portName + '\'' +
+ '}';
+ }
+ }
+
+ private class InterfaceStateRemoveWorker implements Callable {
+ InstanceIdentifier<FlowCapableNodeConnector> key;
+ FlowCapableNodeConnector fcNodeConnectorOld;
+ private final String portName;
+
+ public InterfaceStateRemoveWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
+ FlowCapableNodeConnector fcNodeConnectorOld,
+ String portName) {
+ this.key = key;
+ this.fcNodeConnectorOld = fcNodeConnectorOld;
+ this.portName = portName;
+ }
+
+ @Override
+ public Object call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceStateRemoveHelper.removeState(key, dataBroker, portName, fcNodeConnectorOld);
+ }
+
+ @Override
+ public String toString() {
+ return "InterfaceStateRemoveWorker{" +
+ "key=" + key +
+ ", fcNodeConnectorOld=" + fcNodeConnectorOld +
+ ", portName='" + portName + '\'' +
+ '}';
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class InterfaceTopologyStateListener extends AsyncDataChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class);
+ private DataBroker dataBroker;
+
+ public InterfaceTopologyStateListener(DataBroker dataBroker) {
+ super(OvsdbBridgeAugmentation.class, InterfaceTopologyStateListener.class);
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ protected InstanceIdentifier<OvsdbBridgeAugmentation> getWildCardPath() {
+ return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class)
+ .child(Node.class).augmentation(OvsdbBridgeAugmentation.class).build();
+ }
+
+ @Override
+ protected DataChangeListener getDataChangeListener() {
+ return InterfaceTopologyStateListener.this;
+ }
+
+ @Override
+ protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
+ return AsyncDataBroker.DataChangeScope.BASE;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld) {
+ LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
+ identifier, bridgeOld);
+ DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(identifier, bridgeOld);
+ jobCoordinator.enqueueJob(bridgeOld.getBridgeName().getValue() + bridgeOld.getDatapathId(), rendererStateRemoveWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld,
+ OvsdbBridgeAugmentation bridgeNew) {
+ LOG.info("Received Update DataChange Notification for identifier: {}, ovsdbBridgeAugmentation old: {}, new: {}." +
+ "No Action Performed.", identifier, bridgeOld, bridgeNew);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeNew) {
+ LOG.debug("Received Add DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
+ identifier, bridgeNew);
+ DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
+ jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue() + bridgeNew.getDatapathId(), rendererStateAddWorker);
+ }
+
+ private class RendererStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
+ OvsdbBridgeAugmentation bridgeNew;
+
+
+ public RendererStateAddWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
+ OvsdbBridgeAugmentation bridgeNew) {
+ this.instanceIdentifier = instanceIdentifier;
+ this.bridgeNew = bridgeNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceTopologyStateAddHelper.addPortToBridge(instanceIdentifier,
+ bridgeNew, dataBroker);
+ }
+ }
+
+ private class RendererStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
+ OvsdbBridgeAugmentation bridgeNew;
+
+
+ public RendererStateRemoveWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
+ OvsdbBridgeAugmentation bridgeNew) {
+ this.instanceIdentifier = instanceIdentifier;
+ this.bridgeNew = bridgeNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsInterfaceTopologyStateRemoveHelper.removePortFromBridge(instanceIdentifier,
+ bridgeNew, dataBroker);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase<Interface, VlanMemberConfigListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class);
+ private DataBroker dataBroker;
+ private IdManager idManager;
+
+ public VlanMemberConfigListener(final DataBroker dataBroker, final IdManager idManager) {
+ super(Interface.class, VlanMemberConfigListener.class);
+ this.dataBroker = dataBroker;
+ this.idManager = idManager;
+ }
+
+ @Override
+ protected InstanceIdentifier<Interface> getWildCardPath() {
+ return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
+ IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null) {
+ return;
+ }
+
+ if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+ return;
+ }
+
+ ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class);
+ if (parentRefs == null) {
+ LOG.error("Attempt to remove Vlan Trunk-Member {} without a parent interface", interfaceOld);
+ return;
+ }
+
+ String lowerLayerIf = parentRefs.getParentInterface();
+ if (lowerLayerIf.equals(interfaceOld.getName())) {
+ LOG.error("Attempt to remove Vlan Trunk-Member {} with same parent interface name.", interfaceOld);
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigRemoveWorker removeWorker = new RendererConfigRemoveWorker(key, interfaceOld, parentRefs, ifL2vlan);
+ coordinator.enqueueJob(lowerLayerIf, removeWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
+ IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class);
+ if (ifL2vlanNew == null) {
+ return;
+ }
+ if (ifL2vlanNew.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+ LOG.error("Configuration Error. Attempt to modify Vlan Mode of interface: {} " +
+ "to interface: {}", interfaceOld, interfaceNew);
+ return;
+ }
+
+ ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class);
+ if (parentRefsNew == null) {
+ LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} without a " +
+ "parent interface", interfaceNew);
+ return;
+ }
+
+ String lowerLayerIf = parentRefsNew.getParentInterface();
+ if (lowerLayerIf.equals(interfaceNew.getName())) {
+ LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} with same parent " +
+ "interface name.", interfaceNew);
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigUpdateWorker updateWorker = new RendererConfigUpdateWorker(key, interfaceNew, interfaceOld,
+ parentRefsNew, ifL2vlanNew);
+ coordinator.enqueueJob(lowerLayerIf, updateWorker);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
+ IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null) {
+ return;
+ }
+
+ if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+ return;
+ }
+
+ ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+ if (parentRefs == null) {
+ LOG.error("Attempt to add Vlan Trunk-Member {} without a parent interface", interfaceNew);
+ return;
+ }
+
+ String lowerLayerIf = parentRefs.getParentInterface();
+ if (lowerLayerIf.equals(interfaceNew.getName())) {
+ LOG.error("Attempt to add Vlan Trunk-Member {} with same parent interface name.", interfaceNew);
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifL2vlan);
+ coordinator.enqueueJob(lowerLayerIf, configWorker);
+ }
+
+ @Override
+ protected VlanMemberConfigListener getDataTreeChangeListener() {
+ return VlanMemberConfigListener.this;
+ }
+
+ private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceNew;
+ IfL2vlan ifL2vlan;
+ ParentRefs parentRefs;
+
+ public RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+ ParentRefs parentRefs, IfL2vlan ifL2vlan) {
+ this.key = key;
+ this.interfaceNew = interfaceNew;
+ this.ifL2vlan = ifL2vlan;
+ this.parentRefs = parentRefs;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew,
+ ifL2vlan, idManager);
+ }
+ }
+
+ private class RendererConfigUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceNew;
+ Interface interfaceOld;
+ IfL2vlan ifL2vlanNew;
+ ParentRefs parentRefsNew;
+
+ public RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+ Interface interfaceOld, ParentRefs parentRefsNew, IfL2vlan ifL2vlanNew) {
+ this.key = key;
+ this.interfaceNew = interfaceNew;
+ this.interfaceOld = interfaceOld;
+ this.ifL2vlanNew = ifL2vlanNew;
+ this.parentRefsNew = parentRefsNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, parentRefsNew, interfaceOld,
+ ifL2vlanNew, interfaceNew, idManager);
+ }
+ }
+
+ private class RendererConfigRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<Interface> key;
+ Interface interfaceOld;
+ IfL2vlan ifL2vlan;
+ ParentRefs parentRefs;
+
+ public RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld,
+ ParentRefs parentRefs, IfL2vlan ifL2vlan) {
+ this.key = key;
+ this.interfaceOld = interfaceOld;
+ this.ifL2vlan = ifL2vlan;
+ this.parentRefs = parentRefs;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefs, interfaceOld,
+ ifL2vlan, idManager);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigAddHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigAddHelper.class);
+
+ public static List<ListenableFuture<Void>> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+ Interface interfaceNew, IdManager idManager) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ IfTunnel ifTunnel = interfaceNew.getAugmentation(IfTunnel.class);
+ if (ifTunnel != null) {
+ addTunnelConfiguration(dataBroker, parentRefs, interfaceNew, idManager, t);
+ futures.add(t.submit());
+ return futures;
+ }
+
+ addVlanConfiguration(interfaceNew, t, dataBroker);
+ futures.add(t.submit());
+ return futures;
+ }
+
+ private static void addVlanConfiguration(Interface interfaceNew, WriteTransaction t, DataBroker dataBroker) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker);
+ if (ifState == null) {
+ return;
+ }
+ updateStateEntry(interfaceNew, t, ifState);
+
+ IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+ return;
+ }
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(interfaceNew.getName());
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ return;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ return;
+ }
+
+ OperStatus operStatus = ifState.getOperStatus();
+ PhysAddress physAddress = ifState.getPhysAddress();
+ AdminStatus adminStatus = ifState.getAdminStatus();
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
+
+ //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker);
+
+ if (!ifaceChild.isEnabled()) {
+ operStatus = OperStatus.Down;
+ }
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(ifaceChild.getName());
+ List<String> childLowerLayerIfList = new ArrayList<>();
+ childLowerLayerIfList.add(0, nodeConnectorId.getValue());
+ childLowerLayerIfList.add(1, interfaceNew.getName());
+ InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
+ .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
+ childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName()));
+ t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true);
+ }
+ }
+
+ private static void addTunnelConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+ Interface interfaceNew, IdManager idManager,
+ WriteTransaction t) {
+ if (parentRefs == null) {
+ LOG.warn("ParentRefs for interface: {} Not Found. " +
+ "Creation of Tunnel OF-Port not supported when dpid not provided.", interfaceNew.getName());
+ return;
+ }
+
+ BigInteger dpId = parentRefs.getDatapathNodeIdentifier();
+ if (dpId == null) {
+ LOG.warn("dpid for interface: {} Not Found. No DPID provided. " +
+ "Creation of OF-Port not supported.", interfaceNew.getName());
+ return;
+ }
+
+ createBridgeEntryIfNotPresent(dpId, dataBroker, t);
+
+ BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+ BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+ BridgeInterfaceEntryKey bridgeInterfaceEntryKey = new BridgeInterfaceEntryKey(interfaceNew.getName());
+ if (bridgeRefEntry == null) {
+ InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey,
+ interfaceNew.getName(), t);
+ return;
+ }
+
+ InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+ (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+ Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+ if (bridgeNodeOptional.isPresent()) {
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+ String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+ SouthboundUtils.addPortToBridge(bridgeIid, interfaceNew,
+ ovsdbBridgeAugmentation, bridgeName, interfaceNew.getName(), dataBroker, t);
+ }
+
+ InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceNew.getName());
+ InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey,
+ interfaceNew.getName(), tpIid, t);
+ }
+
+ private static void updateStateEntry(Interface interfaceNew, WriteTransaction t,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+ OperStatus operStatus;
+ if (!interfaceNew.isEnabled() && ifState.getOperStatus() != OperStatus.Down) {
+ operStatus = OperStatus.Down;
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+ ifaceBuilder.setOperStatus(operStatus);
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+ }
+ }
+
+ private static void createBridgeEntryIfNotPresent(BigInteger dpId,
+ DataBroker dataBroker, WriteTransaction t) {
+ BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+ InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+ InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+ BridgeEntry bridgeEntry =
+ InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+ dataBroker);
+ if (bridgeEntry == null) {
+ BridgeEntryBuilder bridgeEntryBuilder = new BridgeEntryBuilder().setKey(bridgeEntryKey)
+ .setDpid(dpId);
+ t.put(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, bridgeEntryBuilder.build(), true);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigRemoveHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigRemoveHelper.class);
+
+ public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, Interface interfaceOld,
+ IdManager idManager, ParentRefs parentRefs) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ IfTunnel ifTunnel = interfaceOld.getAugmentation(IfTunnel.class);
+ if (ifTunnel != null) {
+ removeTunnelConfiguration(parentRefs, dataBroker, interfaceOld, idManager, t);
+ futures.add(t.submit());
+ return futures;
+ }
+
+ removeVlanConfiguration(dataBroker, interfaceOld, t);
+
+ /* FIXME: Deallocate ID from Idmanager. */
+
+ futures.add(t.submit());
+ return futures;
+ }
+
+ private static void removeVlanConfiguration(DataBroker dataBroker, Interface interfaceOld, WriteTransaction t) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceOld.getName(), dataBroker);
+ if (ifState == null) {
+ return;
+ }
+
+ String ncStr = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
+ NodeConnector nodeConnector =
+ InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
+ FlowCapableNodeConnector flowCapableNodeConnector =
+ nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ //State state = flowCapableNodeConnector.getState();
+ OperStatus operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up;
+
+ if (ifState.getOperStatus() != operStatus) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceOld.getName());
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+ ifaceBuilder.setOperStatus(operStatus);
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceOld.getName()));
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+ }
+
+ IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+ return;
+ }
+
+ // For Vlan-Trunk Interface, remove the trunk-member operstates as well...
+ InterfaceKey interfaceKey = new InterfaceKey(interfaceOld.getName());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (iface == null) {
+ return;
+ }
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ return;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ return;
+ }
+
+ //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+ t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
+ }
+ }
+
+ private static void removeTunnelConfiguration(ParentRefs parentRefs, DataBroker dataBroker, Interface interfaceOld,
+ IdManager idManager, WriteTransaction t) {
+
+ BigInteger dpId = null;
+ if (parentRefs != null) {
+ dpId = parentRefs.getDatapathNodeIdentifier();
+ }
+
+ if (dpId == null) {
+ return;
+ }
+
+ BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(bridgeRefEntryIid, dataBroker);
+
+ if (bridgeRefEntry != null) {
+ InstanceIdentifier<?> bridgeIid = bridgeRefEntry.getBridgeReference().getValue();
+ InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName());
+ t.delete(LogicalDatastoreType.CONFIGURATION, tpIid);
+ }
+
+ BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+ InstanceIdentifier<BridgeEntry> bridgeEntryIid = InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+ BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryIid, dataBroker);
+ if (bridgeEntry == null) {
+ return;
+ }
+
+ List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
+ if (bridgeInterfaceEntries == null) {
+ return;
+ }
+
+ if (bridgeInterfaceEntries.size() <= 1) {
+ t.delete(LogicalDatastoreType.CONFIGURATION, bridgeEntryIid);
+ } else {
+ BridgeInterfaceEntryKey bridgeInterfaceEntryKey =
+ new BridgeInterfaceEntryKey(interfaceOld.getName());
+ InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+ InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey,
+ bridgeInterfaceEntryKey);
+ t.delete(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigUpdateHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigUpdateHelper.class);
+
+ public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker, IdManager idManager,
+ Interface interfaceNew, Interface interfaceOld) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+
+ if(portAttributesModified(interfaceOld, interfaceNew)) {
+ futures.addAll(OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager,
+ interfaceOld.getAugmentation(ParentRefs.class)));
+ futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+ interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+ return futures;
+ }
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker);
+ if (ifState == null) {
+ futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+ interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+ return futures;
+ }
+
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ if (interfaceNew.isEnabled() != interfaceOld.isEnabled()) {
+ OperStatus operStatus;
+ if (!interfaceNew.isEnabled()) {
+ operStatus = OperStatus.Down;
+ } else {
+ String ncStr = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
+ NodeConnector nodeConnector =
+ InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
+ FlowCapableNodeConnector flowCapableNodeConnector =
+ nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ //State state = flowCapableNodeConnector.getState();
+ operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up;
+ }
+
+ String ifName = interfaceNew.getName();
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+ ifaceBuilder.setOperStatus(operStatus);
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+
+ IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InterfaceKey interfaceKey = new InterfaceKey(ifName);
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (iface == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+ InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
+ ifaceBuilderChild.setOperStatus(operStatus);
+ ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceChildEntry.getChildInterface()));
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilderChild.build());
+ }
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+
+ private static boolean portAttributesModified(Interface interfaceOld, Interface interfaceNew) {
+ ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class);
+ ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class);
+ if (checkAugmentations(parentRefsOld, parentRefsNew)) {
+ return true;
+ }
+
+ IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class);
+ IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class);
+ if (checkAugmentations(ifL2vlanOld, ifL2vlanNew)) {
+ return true;
+ }
+
+ IfTunnel ifTunnelOld = interfaceOld.getAugmentation(IfTunnel.class);
+ IfTunnel ifTunnelNew = interfaceNew.getAugmentation(IfTunnel.class);
+ if (checkAugmentations(ifTunnelOld, ifTunnelNew)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static<T> boolean checkAugmentations(T oldAug, T newAug) {
+ if ((oldAug != null && newAug == null) ||
+ (oldAug == null && newAug != null)) {
+ return true;
+ }
+
+ if (newAug != null && oldAug != null && !newAug.equals(oldAug)) {
+ return true;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigAddHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigAddHelper.class);
+ public static List<ListenableFuture<Void>> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+ Interface interfaceNew, IfL2vlan ifL2vlan,
+ IdManager idManager) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface());
+ createInterfaceParentEntryIfNotPresent(dataBroker, t, interfaceParentEntryKey, parentRefs.getParentInterface());
+ createInterfaceChildEntry(dataBroker, idManager, t, interfaceParentEntryKey, interfaceNew.getName());
+
+ InterfaceKey interfaceKey = new InterfaceKey(parentRefs.getParentInterface());
+ Interface ifaceParent = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (ifaceParent == null) {
+ LOG.info("Parent Interface: {} not found when adding child interface: {}",
+ parentRefs.getParentInterface(), interfaceNew.getName());
+ futures.add(t.submit());
+ return futures;
+ }
+
+ IfL2vlan parentIfL2Vlan = ifaceParent.getAugmentation(IfL2vlan.class);
+ if (parentIfL2Vlan == null || parentIfL2Vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+ LOG.error("Parent Interface: {} not of trunk Type when adding trunk-member: {}", ifaceParent, interfaceNew);
+ futures.add(t.submit());
+ return futures;
+ }
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker);
+ if (ifState != null) {
+ OperStatus operStatus = ifState.getOperStatus();
+ AdminStatus adminStatus = ifState.getAdminStatus();
+ PhysAddress physAddress = ifState.getPhysAddress();
+
+ if (!interfaceNew.isEnabled()) {
+ operStatus = OperStatus.Down;
+ }
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+ List<String> lowerLayerIfList = new ArrayList<>();
+ lowerLayerIfList.add(parentRefs.getParentInterface());
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
+ .setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList);
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+ t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
+
+ // FIXME: Maybe, add the new interface to the higher-layer if of the parent interface-state.
+ // That may not serve any purpose though for interface manager.... Unless some external parties are interested in it.
+
+ /* FIXME -- Below code is needed to add vlan-trunks to the of-port. Is this really needed.
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+ BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+ if (bridgeRefEntry != null) {
+ InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+ (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+ Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+ if (bridgeNodeOptional.isPresent()) {
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+ String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+ VlanTrunkSouthboundUtils.addVlanPortToBridge(bridgeIid, ifL2vlan,
+ ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t);
+ }
+ } */
+ // FIXME: Need to add the Group here with actions: Push-Vlan, output_port. May not be needed here...
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+
+ private static void createInterfaceParentEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t,
+ InterfaceParentEntryKey interfaceParentEntryKey,
+ String parentInterface){
+ InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier =
+ InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
+
+ if(interfaceParentEntry != null){
+ LOG.info("Not Found entry for Parent Interface: {} in Vlan Trunk-Member Interface Renderer ConfigDS. " +
+ "Creating...", parentInterface);
+ InterfaceParentEntryBuilder interfaceParentEntryBuilder = new InterfaceParentEntryBuilder()
+ .setKey(interfaceParentEntryKey).setParentInterface(parentInterface);
+ t.put(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier,
+ interfaceParentEntryBuilder.build(), true);
+ }
+ }
+
+ private static long createInterfaceChildEntry(DataBroker dataBroker, IdManager idManager, WriteTransaction t,
+ InterfaceParentEntryKey interfaceParentEntryKey, String childInterface){
+ long lportTag = InterfaceManagerCommonUtils.getUniqueId(idManager, childInterface);
+ InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
+ InstanceIdentifier<InterfaceChildEntry> intfId =
+ InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+ InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
+ .setChildInterface(childInterface);
+ t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true);
+ return lportTag;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigRemoveHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigRemoveHelper.class);
+ public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+ Interface interfaceOld, IfL2vlan ifL2vlan,
+ IdManager idManager) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface());
+ InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIid =
+ InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIid, dataBroker);
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries.size() <= 1) {
+ t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIid);
+ } else {
+ InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName());
+ InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryIid =
+ InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+ t.delete(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryIid);
+ }
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker);
+ if (ifState != null) {
+ /* FIXME -- The below code is needed if vlan-trunks should be updated in the of-port
+
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+ BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+ if (bridgeRefEntry != null) {
+ InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+ (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+ Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+ if (bridgeNodeOptional.isPresent()) {
+ OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+ String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+ VlanTrunkSouthboundUtils.updateVlanMemberInTrunk(bridgeIid, ifL2vlan,
+ ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t);
+ }
+ } */
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceOld.getName());
+ t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigUpdateHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigUpdateHelper.class);
+ public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker, ParentRefs parentRefsNew,
+ Interface interfaceOld, IfL2vlan ifL2vlanNew,
+ Interface interfaceNew, IdManager idManager) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class);
+
+ InterfaceParentEntryKey interfaceParentEntryKey =
+ new InterfaceParentEntryKey(parentRefsOld.getParentInterface());
+ InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName());
+ InterfaceChildEntry interfaceChildEntry =
+ InterfaceMetaUtils.getInterfaceChildEntryFromConfigDS(interfaceParentEntryKey, interfaceChildEntryKey,
+ dataBroker);
+
+ if (interfaceChildEntry == null) {
+ futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+ interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+ return futures;
+ }
+
+ IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class);
+ if (ifL2vlanOld == null || (ifL2vlanNew.getL2vlanMode() != ifL2vlanOld.getL2vlanMode())) {
+ LOG.error("Configuration Error. Vlan Mode Change of Vlan Trunk Member {} as new trunk member: {} is " +
+ "not allowed.", interfaceOld, interfaceNew);
+ return futures;
+ }
+
+ if (ifL2vlanOld.getVlanId() != ifL2vlanNew.getVlanId() ||
+ !parentRefsOld.getParentInterface().equals(parentRefsNew.getParentInterface())) {
+ futures.addAll(OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefsOld, interfaceOld,
+ ifL2vlanOld, idManager));
+ futures.addAll(OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefsNew, interfaceNew,
+ ifL2vlanNew, idManager));
+ return futures;
+ }
+
+ if (interfaceNew.isEnabled() == interfaceOld.isEnabled()) {
+ return futures;
+ }
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface pifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefsNew.getParentInterface(), dataBroker);
+ if (pifState != null) {
+ OperStatus operStatus = OperStatus.Down;
+ if (interfaceNew.isEnabled()) {
+ operStatus = pifState.getOperStatus();
+ }
+
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+ IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+ ifaceBuilder.setOperStatus(operStatus);
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+ futures.add(t.submit());
+ }
+
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This worker is responsible for adding the openflow-interfaces/of-port-info container
+ * in odl-interface-openflow yang.
+ * Where applicable:
+ * Create the entries in Interface-State OperDS.
+ * Create the entries in Inventory OperDS.
+ */
+
+public class OvsInterfaceStateAddHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateAddHelper.class);
+
+ public static List<ListenableFuture<Void>> addState(DataBroker dataBroker, NodeConnectorId nodeConnectorId,
+ String portName, FlowCapableNodeConnector fcNodeConnectorNew) {
+ LOG.debug("Adding Interface State to Oper DS for port: {}", portName);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ //Retrieve PbyAddress & OperState from the DataObject
+ PhysAddress physAddress = new PhysAddress(fcNodeConnectorNew.getHardwareAddress().getValue());
+ /*FIXME
+ State state = fcNodeConnectorNew.getState();
+ Interface.OperStatus operStatus =
+ fcNodeConnectorNew == null ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+ Interface.AdminStatus adminStatus = state.isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+ */
+ Interface.OperStatus operStatus = Interface.OperStatus.Up;
+ Interface.AdminStatus adminStatus = Interface.AdminStatus.Up;
+ InterfaceKey interfaceKey = new InterfaceKey(portName);
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+ if (iface != null && !iface.isEnabled()) {
+ operStatus = Interface.OperStatus.Down;
+ }
+
+ List<String> lowerLayerIfList = new ArrayList<>();
+ lowerLayerIfList.add(nodeConnectorId.getValue());
+
+ InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus)
+ .setAdminStatus(adminStatus).setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList)
+ .setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
+ t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
+
+ if (iface == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ // If this interface maps to a Vlan trunk entity, operational states of all the vlan-trunk-members
+ // should also be created here.
+ IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+ //List<Trunks> trunks = new ArrayList<>();
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker);
+
+ // IfL2vlan ifL2vlanChild = iface.getAugmentation(IfL2vlan.class);
+ // trunks.add(new TrunksBuilder().setTrunk(ifL2vlanChild.getVlanId()).build());
+
+ if (!ifaceChild.isEnabled()) {
+ operStatus = Interface.OperStatus.Down;
+ }
+
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(ifaceChild.getName());
+ List<String> childLowerLayerIfList = new ArrayList<>();
+ childLowerLayerIfList.add(0, nodeConnectorId.getValue());
+ childLowerLayerIfList.add(1, iface.getName());
+ InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
+ .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
+ childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName()));
+ t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true);
+ }
+
+ /** Below code will be needed if we want to update the vlan-trunks on the of-port
+ if (trunks.isEmpty()) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+ BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+ if (bridgeRefEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+ (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+ VlanTrunkSouthboundUtils.addTerminationPointWithTrunks(bridgeIid, trunks, iface.getName(), t);
+ */
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceStateRemoveHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateRemoveHelper.class);
+
+ public static List<ListenableFuture<Void>> removeState(InstanceIdentifier<FlowCapableNodeConnector> key,
+ DataBroker dataBroker, String portName, FlowCapableNodeConnector fcNodeConnectorOld) {
+ LOG.debug("Removing interface-state for port: {}", portName);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+ t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
+
+ // For Vlan-Trunk Interface, remove the trunk-member operstates as well...
+ InterfaceKey interfaceKey = new InterfaceKey(portName);
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (iface == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+ t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
+ }
+
+ /* Below code will be needed if we want to update the vlan-trunk in the of-port.
+ NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+ BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry =
+ InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+ if (bridgeRefEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ InstanceIdentifier<?> bridgeIid = bridgeRefEntry.getBridgeReference().getValue();
+ InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName());
+ t.delete(LogicalDatastoreType.CONFIGURATION, tpIid); */
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceStateUpdateHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
+
+ public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
+ DataBroker dataBroker, String portName,
+ FlowCapableNodeConnector flowCapableNodeConnectorNew,
+ FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+ LOG.debug("Update of Interface State for port: {}", portName);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ Interface.OperStatus operStatusNew =
+ flowCapableNodeConnectorNew.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+ Interface.AdminStatus adminStatusNew =
+ flowCapableNodeConnectorNew.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+ MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
+
+ Interface.OperStatus operStatusOld =
+ flowCapableNodeConnectorOld.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+ Interface.AdminStatus adminStatusOld =
+ flowCapableNodeConnectorOld.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+ MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
+
+ boolean opstateModified = false;
+ boolean adminStateModified = false;
+ boolean hardwareAddressModified = false;
+ if (!operStatusNew.equals(operStatusOld)) {
+ opstateModified = true;
+ }
+ if (!adminStatusNew.equals(adminStatusOld)) {
+ adminStateModified = true;
+ }
+ if (!macAddressNew.equals(macAddressOld)) {
+ hardwareAddressModified = true;
+ }
+
+ if (!opstateModified && !adminStateModified && !hardwareAddressModified) {
+ LOG.debug("If State entry for port: {} Not Modified.", portName);
+ return futures;
+ }
+
+ InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+ InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+
+ boolean modified = false;
+ if (opstateModified) {
+ LOG.debug("Opstate Modified for Port: {}", portName);
+ InterfaceKey interfaceKey = new InterfaceKey(portName);
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+ // If interface config admin state is disabled, set operstate of the Interface State entity to Down.
+ if (iface != null && !iface.isEnabled()) {
+ operStatusNew = Interface.OperStatus.Down;
+ }
+
+ ifaceBuilder.setOperStatus(operStatusNew);
+ modified = true;
+ }
+
+ if (adminStateModified) {
+ LOG.debug("Admin state Modified for Port: {}", portName);
+ ifaceBuilder.setAdminStatus(adminStatusNew);
+ modified = true;
+ }
+
+ if (hardwareAddressModified) {
+ LOG.debug("Hw-Address Modified for Port: {}", portName);
+ PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
+ ifaceBuilder.setPhysAddress(physAddress);
+ modified = true;
+ }
+
+ /* FIXME: Is there chance that lower layer node-connector info is updated.
+ Not Considering for now.
+ */
+
+ if (modified) {
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+
+ InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(portName);
+ InterfaceParentEntry interfaceParentEntry =
+ InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+ if (interfaceParentEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+ if (interfaceChildEntries == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ LOG.debug("Updating if-state entries for Vlan-Trunk Members for port: {}", portName);
+ //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+ for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+ InstanceIdentifier<Interface> ifChildStateId =
+ IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+ t.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilder.build());
+ }
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceTopologyStateAddHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateAddHelper.class);
+ public static List<ListenableFuture<Void>> addPortToBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
+ OvsdbBridgeAugmentation bridgeNew, DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ if (bridgeNew.getDatapathId() == null) {
+ LOG.warn("DataPathId found as null for Bridge Augmentation: {}... retrying...", bridgeNew);
+ Optional<OvsdbBridgeAugmentation> bridgeNodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+ if (bridgeNodeOptional.isPresent()) {
+ bridgeNew = bridgeNodeOptional.get();
+ }
+ if (bridgeNew.getDatapathId() == null) {
+ LOG.warn("DataPathId found as null again for Bridge Augmentation: {}. Bailing out.", bridgeNew);
+ return futures;
+ }
+ }
+
+ String dpId = bridgeNew.getDatapathId().getValue();
+ String bridgeName = bridgeNew.getBridgeName().getValue();
+
+ if (dpId == null) {
+ LOG.error("Optained null dpid for bridge: {}", bridgeNew);
+ return futures;
+ }
+
+ dpId = dpId.replaceAll("[^\\d.]", "");
+ BigInteger ovsdbDpId = new BigInteger(dpId, 16);
+ BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId);
+ InstanceIdentifier<BridgeRefEntry> bridgeEntryId =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+ BridgeRefEntryBuilder tunnelDpnBridgeEntryBuilder =
+ new BridgeRefEntryBuilder().setKey(bridgeRefEntryKey).setDpid(ovsdbDpId)
+ .setBridgeReference(new OvsdbBridgeRef(bridgeIid));
+ t.put(LogicalDatastoreType.OPERATIONAL, bridgeEntryId, tunnelDpnBridgeEntryBuilder.build(), true);
+
+ BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(ovsdbDpId);
+ InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+ InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+ BridgeEntry bridgeEntry =
+ InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+ dataBroker);
+ if (bridgeEntry == null) {
+ futures.add(t.submit());
+ return futures;
+ }
+
+ List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
+ for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
+ String portName = bridgeInterfaceEntry.getInterfaceName();
+ InterfaceKey interfaceKey = new InterfaceKey(portName);
+ Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (iface.getAugmentation(IfTunnel.class) != null) {
+ SouthboundUtils.addPortToBridge(bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, t);
+ InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
+ InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey,
+ new BridgeInterfaceEntryKey(portName), portName, tpIid, t);
+ }
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceTopologyStateRemoveHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateRemoveHelper.class);
+
+ public static List<ListenableFuture<Void>> removePortFromBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
+ OvsdbBridgeAugmentation bridgeOld, DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();;
+
+ String dpId = bridgeOld.getDatapathId().getValue().replaceAll("[^\\d.]", "");
+ if (dpId == null) {
+ LOG.warn("Got Null DPID for Bridge: {}", bridgeOld);
+ return futures;
+ }
+
+ dpId = dpId.replaceAll("[^\\d.]", "");
+ BigInteger ovsdbDpId = new BigInteger(dpId,16);
+ BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId);
+ InstanceIdentifier<BridgeRefEntry> bridgeEntryId =
+ InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+ t.delete(LogicalDatastoreType.OPERATIONAL, bridgeEntryId);
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities;
+
+import com.google.common.collect.Maps;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class SouthboundUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
+ public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
+
+ public static void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface,
+ OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+ String portName, DataBroker dataBroker, WriteTransaction t) {
+ IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+ if (ifTunnel != null) {
+ addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, t);
+ return;
+ }
+
+ IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan != null) {
+ addVlanPortToBridge(bridgeIid, ifL2vlan, bridgeAugmentation, bridgeName, portName, dataBroker, t);
+ }
+ }
+
+ private static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+ OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+ String portName, DataBroker dataBroker, WriteTransaction t) {
+ int vlanId = ifL2vlan.getVlanId().getValue();
+ addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, null, null, dataBroker, t);
+ }
+
+ private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
+ OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+ String portName, DataBroker dataBroker, WriteTransaction t) {
+ Class type = null;
+ if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class)) {
+ type = InterfaceTypeGre.class;
+ } else if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
+ type = InterfaceTypeVxlan.class;
+ }
+
+ if (type == null) {
+ LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
+ return;
+ }
+
+ int vlanId = 0;
+ IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+ if (ifL2vlan != null) {
+ vlanId = ifL2vlan.getVlanId().getValue();
+ }
+
+ Map<String, String> options = Maps.newHashMap();
+ options.put("key", "flow");
+
+ IpAddress localIp = ifTunnel.getTunnelSource();
+ options.put("local_ip", localIp.getIpv4Address().getValue());
+
+ IpAddress remoteIp = ifTunnel.getTunnelDestination();
+ options.put("remote_ip", remoteIp.getIpv4Address().getValue());
+
+ addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, dataBroker, t);
+ }
+
+ private static void addTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+ String bridgeName, String portName, int vlanId, Class type,
+ Map<String, String> options, DataBroker dataBroker, WriteTransaction t) {
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+ tpAugmentationBuilder.setName(portName);
+
+ if (type != null) {
+ tpAugmentationBuilder.setInterfaceType(type);
+ }
+
+ if (options != null) {
+ List<Options> optionsList = new ArrayList<Options>();
+ for (Map.Entry<String, String> entry : options.entrySet()) {
+ OptionsBuilder optionsBuilder = new OptionsBuilder();
+ optionsBuilder.setKey(new OptionsKey(entry.getKey()));
+ optionsBuilder.setOption(entry.getKey());
+ optionsBuilder.setValue(entry.getValue());
+ optionsList.add(optionsBuilder.build());
+ }
+ tpAugmentationBuilder.setOptions(optionsList);
+ }
+
+ if (vlanId != 0) {
+ tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
+ tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
+ }
+
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+ t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+ }
+
+ private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node,
+ String portName){
+ InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+ .child(Node.class,node.getKey())
+ .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+ LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
+ return terminationPointPath;
+ }
+
+ public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
+ String portName){
+ InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+ .child(Node.class,nodekey)
+ .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+ LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
+ return terminationPointPath;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VlanTrunkSouthboundUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(VlanTrunkSouthboundUtils.class);
+ public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
+
+ public static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+ OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+ String parentInterface, DataBroker dataBroker, WriteTransaction t) {
+ LOG.info("Vlan Interface creation not supported yet. please visit later.");
+ int vlanId = ifL2vlan.getVlanId().getValue();
+ addTrunkTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t);
+ }
+
+ public static void updateVlanMemberInTrunk(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+ OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+ String parentInterface, DataBroker dataBroker, WriteTransaction t) {
+ LOG.info("Vlan Interface creation not supported yet. please visit later.");
+ int vlanId = ifL2vlan.getVlanId().getValue();
+ updateTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t);
+ }
+
+ private static void addTrunkTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+ String bridgeName, String parentInterface, int vlanId,
+ DataBroker dataBroker, WriteTransaction t) {
+ if (vlanId == 0) {
+ LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface);
+ return;
+ }
+
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+ tpAugmentationBuilder.setName(parentInterface);
+ tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+ OvsdbTerminationPointAugmentation terminationPointAugmentation = null;
+ Optional<TerminationPoint> terminationPointOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker);
+ if (terminationPointOptional.isPresent()) {
+ TerminationPoint terminationPoint = terminationPointOptional.get();
+ terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+ if (terminationPointAugmentation != null) {
+ List<Trunks> trunks = terminationPointAugmentation.getTrunks();
+ if (trunks == null) {
+ trunks = new ArrayList<>();
+ }
+
+ trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+ tpAugmentationBuilder.setTrunks(trunks);
+ }
+ } else {
+ List<Trunks> trunks = new ArrayList<>();
+ trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+ tpAugmentationBuilder.setTrunks(trunks);
+ }
+
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+ t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+ }
+
+ public static void addTerminationPointWithTrunks(InstanceIdentifier<?> bridgeIid, List<Trunks> trunks,
+ String parentInterface, WriteTransaction t) {
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+ tpAugmentationBuilder.setName(parentInterface);
+ tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+ tpAugmentationBuilder.setTrunks(trunks);
+
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+ t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+ }
+
+ private static void updateTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+ String bridgeName, String parentInterface, int vlanId,
+ DataBroker dataBroker, WriteTransaction t) {
+ if (vlanId == 0) {
+ LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface);
+ return;
+ }
+
+ InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+ tpAugmentationBuilder.setName(parentInterface);
+ tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+ OvsdbTerminationPointAugmentation terminationPointAugmentation = null;
+ Optional<TerminationPoint> terminationPointOptional =
+ IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker);
+ if (terminationPointOptional.isPresent()) {
+ TerminationPoint terminationPoint = terminationPointOptional.get();
+ terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+ if (terminationPointAugmentation != null) {
+ List<Trunks> trunks = terminationPointAugmentation.getTrunks();
+ if (trunks != null) {
+ trunks.remove(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+ }
+
+ tpAugmentationBuilder.setTrunks(trunks);
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+ t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+ }
+ }
+ }
+
+ private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
+ String portName){
+ InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+ .child(Node.class,nodekey)
+ .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+ LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
+ return terminationPointPath;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.rpcservice;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class InterfaceManagerRpcService implements OdlInterfaceRpcService {
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerRpcService.class);
+ DataBroker dataBroker;
+ public InterfaceManagerRpcService(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ public Future<RpcResult<GetDpidFromInterfaceOutput>> getDpidFromInterface(GetDpidFromInterfaceInput input) {
+ String interfaceName = input.getIntfName();
+ RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder;
+ try {
+ BigInteger dpId = null;
+ InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+ Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (Tunnel.class.equals(interfaceInfo.getType())) {
+ ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class);
+ dpId = parentRefs.getDatapathNodeIdentifier();
+ } else {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ }
+ GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid(
+ (dpId));
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ } catch (Exception e) {
+ LOG.error("Retrieval of datapath id for the key {} failed due to {}", interfaceName, e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
+ @Override
+ public Future<RpcResult<GetEndpointIpForDpnOutput>> getEndpointIpForDpn(GetEndpointIpForDpnInput input) {
+ RpcResultBuilder<GetEndpointIpForDpnOutput> rpcResultBuilder;
+ try {
+ BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid());
+ InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+ InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+ BridgeEntry bridgeEntry =
+ InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+ dataBroker);
+ // local ip of any of the bridge interface entry will be the dpn end point ip
+ BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().get(0);
+ InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName());
+ Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ IfTunnel tunnel = interfaceInfo.getAugmentation(IfTunnel.class);
+ GetEndpointIpForDpnOutputBuilder endpointIpForDpnOutput = new GetEndpointIpForDpnOutputBuilder().setLocalIps(Arrays.asList(tunnel.getTunnelSource()));
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(endpointIpForDpnOutput.build());
+ }catch(Exception e){
+ LOG.error("Retrieval of endpoint of for dpn {} failed due to {}" ,input.getDpid(), e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
+ @Override
+ public Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> getEgressInstructionsForInterface(GetEgressInstructionsForInterfaceInput input) {
+ RpcResultBuilder<GetEgressInstructionsForInterfaceOutput> rpcResultBuilder;
+ try {
+ List<InstructionInfo> instructionInfo = new ArrayList<InstructionInfo>();
+ List<ActionInfo> actionInfo = getEgressActionInfosForInterface(input.getIntfName());
+ instructionInfo.add(new InstructionInfo(InstructionType.write_actions, actionInfo));
+ GetEgressInstructionsForInterfaceOutputBuilder output = new GetEgressInstructionsForInterfaceOutputBuilder().
+ setInstruction(buildInstructions(instructionInfo));
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ }catch(Exception e){
+ LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
+ @Override
+ public Future<RpcResult<GetEgressActionsForInterfaceOutput>> getEgressActionsForInterface(GetEgressActionsForInterfaceInput input) {
+ RpcResultBuilder<GetEgressActionsForInterfaceOutput> rpcResultBuilder;
+ try {
+ List<Action> actionsList = getEgressActionsForInterface(input.getIntfName());
+ GetEgressActionsForInterfaceOutputBuilder output = new GetEgressActionsForInterfaceOutputBuilder().
+ setAction(actionsList);
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ }catch(Exception e){
+ LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
+ public static InstanceIdentifier<InterfaceChildEntry> getInterfaceChildEntryIdentifier(InterfaceParentEntryKey parentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<InterfaceChildEntry> interfaceChildEntryInstanceIdentifierBuilder =
+ InstanceIdentifier.builder(InterfaceChildInfo.class).child(InterfaceParentEntry.class, parentEntryKey).child(InterfaceChildEntry.class, interfaceChildEntryKey);
+ return interfaceChildEntryInstanceIdentifierBuilder.build();
+ }
+
+ public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(String interfaceName,
+ DataBroker dataBroker) {
+ InterfaceParentEntryKey parentEntryKey = new InterfaceParentEntryKey(interfaceName);
+ InterfaceChildEntryKey childEntryKey = new InterfaceChildEntryKey(interfaceName);
+ InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryInstanceIdentifier = getInterfaceChildEntryIdentifier(parentEntryKey, childEntryKey);
+ Optional<InterfaceChildEntry> interfaceChildEntryOptional =
+ IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryInstanceIdentifier, dataBroker);
+ if (!interfaceChildEntryOptional.isPresent()) {
+ return null;
+ }
+ return interfaceChildEntryOptional.get();
+ }
+
+ @Override
+ public Future<RpcResult<GetPortFromInterfaceOutput>> getPortFromInterface(GetPortFromInterfaceInput input) {
+ RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder;
+ String interfaceName = input.getIntfName();
+ try {
+ BigInteger dpId = null;
+ long portNo = 0;
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+ // FIXME Assuming portName and interfaceName are same
+ GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId).
+ setPortname(interfaceName).setPortno(Long.valueOf(portNo));
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ }catch(Exception e){
+ LOG.error("Retrieval of lport tag for the key {} failed due to {}" ,input.getIntfName(), e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
+
+ @Override
+ public Future<RpcResult<GetInterfaceFromPortOutput>> getInterfaceFromPort(GetInterfaceFromPortInput input) {
+ /*RpcResultBuilder<GetInterfaceFromPortOutput> rpcResultBuilder;
+ try {
+ Interface interfaceInfo = null;
+ NodeId nodeId = IfmUtil.buildDpnNodeId(input.getDpid());
+ Node node = getNodeFromInventoryOperDS(nodeId, dataBroker);
+ ChildInterfaceNames childInterfaceNames = node.getAugmentation(ChildInterfaceNames.class);
+ for(OfInterfaceRefInfo ofInterfaceRefInfo : childInterfaceNames.getOfInterfaceRefInfo()){
+ interfaceInfo = getInterfaceFromTunnelKey(ofInterfaceRefInfo.getOfIntfName(), input.getInterfaceId(),
+ input.getInterfaceType());
+ }
+ GetInterfaceFromPortOutputBuilder output = new GetInterfaceFromPortOutputBuilder().
+ setInterfaceName(interfaceInfo == null ? null : interfaceInfo.getName());
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ }catch(Exception e){
+ LOG.error("Retrieval of interface for the key {} failed due to {}" ,input.getPortno(), e);
+ rpcResultBuilder = RpcResultBuilder.failed();
+ }
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ */
+ return null;
+ }
+
+ public List<ActionInfo> getEgressActionInfosForInterface(String interfaceName) {
+ Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
+ dataBroker);
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ String portNo = IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId);
+ Class<? extends InterfaceType> ifType = interfaceInfo.getType();
+ if(L2vlan.class.equals(ifType)){
+ IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
+ LOG.trace("L2Vlan: {}",vlanIface);
+ long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue();
+ if (vlanVid != 0) {
+ listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+ listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+ new String[] { Long.toString(vlanVid) }));
+ }
+ listActionInfo.add(new ActionInfo(ActionType.output, new String[] {portNo}));
+ }else if(Tunnel.class.equals(ifType)){
+ listActionInfo.add(new ActionInfo(ActionType.output, new String[] { portNo}));
+ }
+ return listActionInfo;
+ }
+
+ public List<Action> getEgressActionsForInterface(String interfaceName) {
+ List<ActionInfo> listActionInfo = getEgressActionInfosForInterface(interfaceName);
+ List<Action> actionsList = new ArrayList<>();
+ for (ActionInfo actionInfo : listActionInfo) {
+ actionsList.add(actionInfo.buildAction());
+ }
+ return actionsList;
+ }
+
+ protected static List<Instruction> buildInstructions(List<InstructionInfo> listInstructionInfo) {
+ if (listInstructionInfo != null) {
+ List<Instruction> instructions = new ArrayList<Instruction>();
+ int instructionKey = 0;
+
+ for (InstructionInfo instructionInfo : listInstructionInfo) {
+ instructions.add(instructionInfo.buildInstruction(instructionKey));
+ instructionKey++;
+ }
+ return instructions;
+ }
+
+ return null;
+ }
+
+ public static Node getNodeFromInventoryOperDS(NodeId nodeId, DataBroker dataBroker) {
+ InstanceIdentifier<Node> nodeIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId)).build();
+
+ Optional<Node> nodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
+ nodeIdentifier, dataBroker);
+ if (!nodeOptional.isPresent()) {
+ return null;
+ }
+ return nodeOptional.get();
+ }
+
+ public Interface getInterfaceFromTunnelKey(String interfaceName, BigInteger tunnelKey,
+ Class<? extends TunnelTypeBase> ifType){
+
+ /*Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+
+ if(ifType.isAssignableFrom(IfL2vlan.class)){
+ IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
+ LOG.trace("L2Vlan: {}",vlanIface);
+ long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId();
+ if(tunnelKey.intValue() == vlanVid){
+ return interfaceInfo;
+ }
+ }else if(ifType.isAssignableFrom(TunnelTypeBase.class)){
+ IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class);
+ TunnelResources tunnelResources = ifTunnel.getTunnelResources();
+ if(ifType.isAssignableFrom(TunnelTypeGre.class)) {
+ IfGre ifGre = tunnelResources.getAugmentation(IfGre.class);
+ if (ifGre.getGreKey() == tunnelKey) {
+ return interfaceInfo;
+ }
+ }else if(ifType.isAssignableFrom(TunnelTypeVxlan.class)){
+ IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+ if(ifVxlan.getVni() == tunnelKey){
+ return interfaceInfo;
+ }
+ }
+ }
+ return null;*/
+ return null;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FlowBasedServicesConfigBindHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigBindHelper.class);
+
+ public static List<ListenableFuture<Void>> bindService(InstanceIdentifier<BoundServices> instanceIdentifier,
+ BoundServices boundServiceNew, DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = null;
+ String interfaceName =
+ InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+ if (ifState == null || ifState.getOperStatus() == OperStatus.Down) {
+ LOG.info("Not Binding Service since for Interface: {}", interfaceName);
+ return futures;
+ }
+
+ // Get the Parent ServiceInfo
+ ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker);
+ if (servicesInfo == null) {
+ LOG.error("Reached Impossible part 1 in the code during bind service for: {}", boundServiceNew);
+ return futures;
+ }
+
+ InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+ Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+ List<BoundServices> allServices = servicesInfo.getBoundServices();
+ if (allServices.isEmpty()) {
+ LOG.error("Reached Impossible part 2 in the code during bind service for: {}", boundServiceNew);
+ return futures;
+ }
+
+ NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+ long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+ Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+ if (allServices.size() == 1) {
+ // If only one service present, install instructions in table 0.
+ int vlanId = 0;
+ List<MatchInfo> matches = null;
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+ matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+ } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+ matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+ }
+
+ if (matches != null) {
+ FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew,
+ dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+ }
+
+ if (t != null) {
+ futures.add(t.submit());
+ }
+ return futures;
+ }
+
+ boolean isCurrentServiceHighestPriority = true;
+ Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
+ short highestPriority = 0xFF;
+ for (BoundServices boundService : allServices) {
+ if (boundService.getServicePriority() < boundServiceNew.getServicePriority()) {
+ isCurrentServiceHighestPriority = false;
+ break;
+ }
+ if (!boundService.equals(boundServiceNew)) {
+ tmpServicesMap.put(boundService.getServicePriority(), boundService);
+ if (boundService.getServicePriority() < highestPriority) {
+ highestPriority = boundService.getServicePriority();
+ }
+ }
+ LOG.error("Reached unexpected part 1 of the code when handling bind service for interface: {}, when binding" +
+ "service: {}", iface, boundServiceNew);
+ }
+
+ if (!isCurrentServiceHighestPriority) {
+ FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundServiceNew, iface, dataBroker, t,
+ lportTag.intValue());
+ } else {
+ BoundServices serviceToReplace = tmpServicesMap.get(highestPriority);
+ FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, serviceToReplace, iface, dataBroker, t,
+ lportTag.intValue());
+ int vlanId = 0;
+ List<MatchInfo> matches = null;
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+ matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+ } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+ matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+ }
+
+ if (matches != null) {
+ FlowBasedServicesUtils.removeIngressFlow(iface, serviceToReplace, dpId, dataBroker, t);
+ FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew, dataBroker, t,
+ matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+ }
+ }
+
+ if (t != null) {
+ futures.add(t.submit());
+ }
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FlowBasedServicesConfigUnbindHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigUnbindHelper.class);
+
+ public static List<ListenableFuture<Void>> unbindService(InstanceIdentifier<BoundServices> instanceIdentifier,
+ BoundServices boundServiceOld, DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = null;
+
+ String interfaceName =
+ InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+ if (ifState == null || ifState.getOperStatus() == OperStatus.Down) {
+ LOG.info("Not unbinding Service since operstatus is {} for Interface: {}",
+ ifState.getOperStatus(), interfaceName);
+ return futures;
+ }
+
+ // Get the Parent ServiceInfo
+ ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker);
+ if (servicesInfo == null) {
+ LOG.error("Reached Impossible part in the code for bound service: {}", boundServiceOld);
+ return futures;
+ }
+
+ InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+ Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+ long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+ int vlanId = 0;
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+ }
+ List<BoundServices> boundServices = servicesInfo.getBoundServices();
+ if (boundServices.isEmpty()) {
+ // Remove entry from Ingress Table.
+ FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t);
+ if (t != null) {
+ futures.add(t.submit());
+ }
+ return futures;
+ }
+
+ Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
+ short highestPriority = 0xFF;
+ for (BoundServices boundService : boundServices) {
+ tmpServicesMap.put(boundService.getServicePriority(), boundService);
+ if (boundService.getServicePriority() < highestPriority) {
+ highestPriority = boundService.getServicePriority();
+ }
+ }
+
+ if (highestPriority < boundServiceOld.getServicePriority()) {
+ FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundServiceOld, dataBroker, t);
+ if (t != null) {
+ futures.add(t.submit());
+ }
+ return futures;
+ }
+
+ List<MatchInfo> matches = null;
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+ } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+ matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+ }
+
+ BoundServices toBeMoved = tmpServicesMap.get(highestPriority);
+ FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t);
+ FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, toBeMoved, dataBroker, t,
+ matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+ FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, toBeMoved, dataBroker, t);
+
+ if (t != null) {
+ futures.add(t.submit());
+ }
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigBindHelper;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigUnbindHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListenerBase<BoundServices, FlowBasedServicesConfigListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigListener.class);
+ private DataBroker dataBroker;
+
+ public FlowBasedServicesConfigListener(final DataBroker dataBroker) {
+ super(BoundServices.class, FlowBasedServicesConfigListener.class);
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ protected InstanceIdentifier<BoundServices> getWildCardPath() {
+ return InstanceIdentifier.create(ServiceBindings.class).child(ServicesInfo.class)
+ .child(BoundServices.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<BoundServices> key, BoundServices boundServiceOld) {
+ String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+ LOG.info("Service Binding Entry removed for Interface: {}, Data: {}",
+ interfaceName, boundServiceOld);
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, boundServiceOld);
+ coordinator.enqueueJob(interfaceName, configWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<BoundServices> key, BoundServices boundServiceOld,
+ BoundServices boundServiceNew) {
+ LOG.error("Service Binding entry update not allowed for: {}, Data: {}",
+ InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(), boundServiceNew);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<BoundServices> key, BoundServices boundServicesNew) {
+ String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+ LOG.info("Service Binding Entry created for Interface: {}, Data: {}",
+ interfaceName, boundServicesNew);
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, boundServicesNew);
+ coordinator.enqueueJob(interfaceName, configWorker);
+ }
+
+ @Override
+ protected FlowBasedServicesConfigListener getDataTreeChangeListener() {
+ return FlowBasedServicesConfigListener.this;
+ }
+
+ private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<BoundServices> instanceIdentifier;
+ BoundServices boundServicesNew;
+
+ public RendererConfigAddWorker(InstanceIdentifier<BoundServices> instanceIdentifier,
+ BoundServices boundServicesNew) {
+ this.instanceIdentifier = instanceIdentifier;
+ this.boundServicesNew = boundServicesNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ return FlowBasedServicesConfigBindHelper.bindService(instanceIdentifier,
+ boundServicesNew, dataBroker);
+ }
+ }
+
+ private class RendererConfigRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<BoundServices> instanceIdentifier;
+ BoundServices boundServicesNew;
+
+ public RendererConfigRemoveWorker(InstanceIdentifier<BoundServices> instanceIdentifier,
+ BoundServices boundServicesNew) {
+ this.instanceIdentifier = instanceIdentifier;
+ this.boundServicesNew = boundServicesNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ return FlowBasedServicesConfigUnbindHelper.unbindService(instanceIdentifier,
+ boundServicesNew, dataBroker);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateBindHelper;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateUnbindHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChangeListenerBase<Interface, FlowBasedServicesInterfaceStateListener> {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesInterfaceStateListener.class);
+ private DataBroker dataBroker;
+
+ public FlowBasedServicesInterfaceStateListener(final DataBroker dataBroker) {
+ super(Interface.class, FlowBasedServicesInterfaceStateListener.class);
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ protected InstanceIdentifier<Interface> getWildCardPath() {
+ return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<Interface> key, Interface interfaceStateOld) {
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererStateInterfaceUnbindWorker stateUnbindWorker =
+ new RendererStateInterfaceUnbindWorker(interfaceStateOld);
+ coordinator.enqueueJob(interfaceStateOld.getName(), stateUnbindWorker);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<Interface> key, Interface interfaceStateOld, Interface interfaceStateNew) {
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) {
+ RendererStateInterfaceUnbindWorker stateUnbindWorker =
+ new RendererStateInterfaceUnbindWorker(interfaceStateNew);
+ coordinator.enqueueJob(interfaceStateNew.getName(), stateUnbindWorker);
+ return;
+ }
+
+ RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew);
+ coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<Interface> key, Interface interfaceStateNew) {
+ if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) {
+ LOG.info("Interface: {} operstate is down when adding. Not Binding services", interfaceStateNew.getName());
+ return;
+ }
+
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew);
+ coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker);
+ }
+
+ @Override
+ protected FlowBasedServicesInterfaceStateListener getDataTreeChangeListener() {
+ return FlowBasedServicesInterfaceStateListener.this;
+ }
+
+ private class RendererStateInterfaceBindWorker implements Callable<List<ListenableFuture<Void>>> {
+ Interface iface;
+
+ public RendererStateInterfaceBindWorker(Interface iface) {
+ this.iface = iface;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ return FlowBasedServicesStateBindHelper.bindServicesOnInterface(iface, dataBroker);
+ }
+ }
+
+ private class RendererStateInterfaceUnbindWorker implements Callable<List<ListenableFuture<Void>>> {
+ Interface iface;
+
+ public RendererStateInterfaceUnbindWorker(Interface iface) {
+ this.iface = iface;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ return FlowBasedServicesStateUnbindHelper.unbindServicesFromInterface(iface, dataBroker);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesStateBindHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateBindHelper.class);
+
+ public static List<ListenableFuture<Void>> bindServicesOnInterface(Interface ifaceState,
+ DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker);
+ if (servicesInfo == null) {
+ return futures;
+ }
+
+ List<BoundServices> allServices = servicesInfo.getBoundServices();
+ if (allServices == null || allServices.isEmpty()) {
+ return futures;
+ }
+
+ BoundServices highestPriorityBoundService = null;
+ short highestPriority = 0xFF;
+ for (BoundServices boundService : allServices) {
+ if (boundService.getServicePriority() < highestPriority) {
+ highestPriorityBoundService = boundService;
+ highestPriority = boundService.getServicePriority();
+ }
+ }
+
+ InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+ NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+ long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+ int vlanId = 0;
+ List<MatchInfo> matches = null;
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+ matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+ } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+ matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+ }
+
+ if (matches != null) {
+ FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, highestPriorityBoundService,
+ dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+ }
+
+ for (BoundServices boundService : allServices) {
+ if (!boundService.equals(highestPriorityBoundService)) {
+ FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundService, iface,
+ dataBroker, t, lportTag.intValue());
+ }
+ }
+
+ futures.add(t.submit());
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesStateUnbindHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateUnbindHelper.class);
+
+ public static List<ListenableFuture<Void>> unbindServicesFromInterface(Interface ifaceState,
+ DataBroker dataBroker) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker);
+ if (servicesInfo == null) {
+ return futures;
+ }
+
+ List<BoundServices> allServices = servicesInfo.getBoundServices();
+ if (allServices == null || allServices.isEmpty()) {
+ return futures;
+ }
+
+ BoundServices highestPriorityBoundService = null;
+ short highestPriority = 0xFF;
+ for (BoundServices boundService : allServices) {
+ if (boundService.getServicePriority() < highestPriority) {
+ highestPriorityBoundService = boundService;
+ highestPriority = boundService.getServicePriority();
+ }
+ }
+
+ InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+ NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+ BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+
+ FlowBasedServicesUtils.removeIngressFlow(iface, highestPriorityBoundService, dpId,
+ dataBroker, t);
+
+ for (BoundServices boundService : allServices) {
+ if (!boundService.equals(highestPriorityBoundService)) {
+ FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundService, dataBroker, t);
+ }
+ }
+
+ return futures;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.StypeOpenflow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesUtils.class);
+
+ public static ServicesInfo getServicesInfoForInterface(String interfaceName, DataBroker dataBroker) {
+ ServicesInfoKey servicesInfoKey = new ServicesInfoKey(interfaceName);
+ InstanceIdentifier.InstanceIdentifierBuilder<ServicesInfo> servicesInfoIdentifierBuilder =
+ InstanceIdentifier.builder(ServiceBindings.class).child(ServicesInfo.class, servicesInfoKey);
+ Optional<ServicesInfo> servicesInfoOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION,
+ servicesInfoIdentifierBuilder.build(), dataBroker);
+
+ if (servicesInfoOptional.isPresent()) {
+ return servicesInfoOptional.get();
+ }
+
+ return null;
+ }
+
+ public static NodeConnectorId getNodeConnectorIdFromInterface(Interface iface, DataBroker dataBroker) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+ InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(iface.getName(), dataBroker);
+ List<String> ofportIds = ifState.getLowerLayerIf();
+ return new NodeConnectorId(ofportIds.get(0));
+ }
+
+ public static List<MatchInfo> getMatchInfoForVlanPortAtIngressTable(BigInteger dpId, long portNo, long vlanId) {
+ List<MatchInfo> matches = new ArrayList<>();
+ matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {dpId, BigInteger.valueOf(portNo)}));
+ if (vlanId > 0) {
+ LOG.error("VlanId matching support is not fully available in Be.");
+ matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[]{vlanId}));
+ }
+ return matches;
+ }
+
+ public static List<MatchInfo> getMatchInfoForTunnelPortAtIngressTable(BigInteger dpId, long portNo, Interface iface) {
+ List<MatchInfo> matches = new ArrayList<MatchInfo>();
+ matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[]{dpId, BigInteger.valueOf(portNo)}));
+ /*IfTunnel tunnel = iface.getAugmentation(IfTunnel.class);
+ TunnelResources tunnelResources = tunnel.getTunnelResources();
+ if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) {
+ IfGre ifgre = tunnelResources.getAugmentation(IfGre.class);
+ BigInteger grekey = ifgre.getGreKey();
+ // FIXME: Add tunnel-id match information
+
+ } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) {
+ IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+ BigInteger vni = ifVxlan.getVni();
+ // FIXME: Add tunnel-id match information
+ }*/
+
+ return matches;
+ }
+
+ public static List<MatchInfo> getMatchInfoForDispatcherTable(BigInteger dpId, Interface iface,
+ int interfaceTag, short servicePriority) {
+ List<MatchInfo> matches = new ArrayList<MatchInfo>();
+ matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+ MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, servicePriority),
+ MetaDataUtil.getMetaDataMaskForLPortDispatcher() }));
+ /*if (iface.getType().isAssignableFrom(Tunnel.class)) {
+ IfTunnel tunnel = iface.getAugmentation(IfTunnel.class);
+ TunnelResources tunnelResources = tunnel.getTunnelResources();
+ if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) {
+ IfGre ifgre = tunnelResources.getAugmentation(IfGre.class);
+ BigInteger grekey = ifgre.getGreKey();
+ // FIXME: Add tunnel-id match information
+
+ } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) {
+ IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+ BigInteger vni = ifVxlan.getVni();
+ // FIXME: Add tunnel-id match information
+ }
+ }*/
+ return matches;
+ }
+
+ public static Long getLPortTag(Interface iface, DataBroker dataBroker) {
+ /*ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
+ String portName = parentRefs.getParentInterface();
+ BigInteger dpIdFromInterface = parentRefs.getDatapathNodeIdentifier();
+ String portKey = FlowBasedServicesUtils.getInterfaceRefInfo(dpIdFromInterface.toString(), portName);
+ if (iface.getType().isAssignableFrom(L2vlan.class)) {
+ InterfacesMetaKey interfacesMetaKey = new InterfacesMetaKey(portKey);
+ InterfacesInfoKey interfacesInfoKey = new InterfacesInfoKey(iface.getName());
+ InterfacesInfo interfacesInfo = VlanInterfaceUtilities.getInterfacesInfoFromConfigDS(interfacesMetaKey,
+ interfacesInfoKey, dataBroker);
+ return interfacesInfo.getLporttag();
+ } else if (iface.getType().isAssignableFrom(Tunnel.class)) {
+ TunnelInterfaceRefInfoKey tunnelInterfaceRefInfoKey = new TunnelInterfaceRefInfoKey(portKey);
+ TunnelInterfaceEntries tunnelInterfaceEntries =
+ TunnelInterfaceUtilities.getTunnelInterfaceRefEntriesFromConfigDs(
+ tunnelInterfaceRefInfoKey, iface.getName(), dataBroker);
+ return tunnelInterfaceEntries.getLportTag();
+ } */
+ return 0L;
+ }
+
+ public static void installInterfaceIngressFlow(BigInteger dpId, int vlanId,
+ BoundServices boundServiceNew,
+ DataBroker dataBroker, WriteTransaction t,
+ List<MatchInfo> matches, int lportTag, short tableId) {
+ List<Instruction> instructions = boundServiceNew.getAugmentation(StypeOpenflow.class).getInstruction();
+
+ int serviceInstructionsSize = instructions.size();
+ List<Instruction> instructionSet = new ArrayList<Instruction>();
+ if (vlanId != 0) {
+ // incrementing instructionSize and using it as actionKey. Because it won't clash with any other instructions
+ int actionKey = ++serviceInstructionsSize;
+ instructionSet.add(MDSALUtil.buildAndGetPopVlanActionInstruction(actionKey, ++serviceInstructionsSize));
+ }
+
+ if (lportTag != 0L) {
+ BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(instructions);
+ short sIndex = boundServiceNew.getServicePriority();
+ BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lportTag,
+ ++sIndex, metadataValues[0]);
+ BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(
+ MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
+ MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]);
+ instructionSet.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask,
+ ++serviceInstructionsSize));
+ }
+
+ if (instructions != null && !instructions.isEmpty()) {
+ for (Instruction info : instructions) {
+ // Skip meta data write as that is handled already
+ if (info.getInstruction() instanceof WriteMetadataCase) {
+ continue;
+ }
+ instructionSet.add(info);
+ }
+ }
+
+ String serviceRef = boundServiceNew.getServiceName();
+ StypeOpenflow stypeOpenflow = boundServiceNew.getAugmentation(StypeOpenflow.class);
+ Flow ingressFlow = MDSALUtil.buildFlowNew(tableId, serviceRef,
+ stypeOpenflow.getFlowPriority(), serviceRef, 0, 0,
+ stypeOpenflow.getFlowCookie(), matches, instructionSet);
+ installFlow(dpId, ingressFlow, dataBroker, t);
+ }
+
+ private static void installFlow(BigInteger dpId, Flow flow, DataBroker dataBroker, WriteTransaction t) {
+ FlowKey flowKey = new FlowKey(new FlowId(flow.getId()));
+ Node nodeDpn = buildInventoryDpnNode(dpId);
+ InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build();
+
+ t.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
+ }
+
+ private static Node buildInventoryDpnNode(BigInteger dpnId) {
+ NodeId nodeId = new NodeId("openflow:" + dpnId);
+ Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build();
+
+ return nodeDpn;
+ }
+
+ public static void installLPortDispatcherFlow(BigInteger dpId, BoundServices boundService, Interface iface,
+ DataBroker dataBroker, WriteTransaction t, int interfaceTag) {
+ LOG.debug("Installing LPort Dispatcher Flows {}, {}", dpId, iface);
+ short serviceIndex = boundService.getServicePriority();
+ String serviceRef = boundService.getServiceName();
+ List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForDispatcherTable(dpId, iface,
+ interfaceTag, serviceIndex);
+
+ // Get the metadata and mask from the service's write metadata instruction
+ StypeOpenflow stypeOpenFlow = boundService.getAugmentation(StypeOpenflow.class);
+ List<Instruction> serviceInstructions = stypeOpenFlow.getInstruction();
+ int instructionSize = serviceInstructions.size();
+ BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(serviceInstructions);
+ BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, ++serviceIndex, metadataValues[0]);
+ BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
+ MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]);
+
+ // build the final instruction for LPort Dispatcher table flow entry
+ List<Instruction> instructions = new ArrayList<Instruction>();
+ instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask, ++instructionSize));
+ if (serviceInstructions != null && !serviceInstructions.isEmpty()) {
+ for (Instruction info : serviceInstructions) {
+ // Skip meta data write as that is handled already
+ if (info.getInstruction() instanceof WriteMetadataCase) {
+ continue;
+ }
+ instructions.add(info);
+ }
+ }
+
+ // build the flow and install it
+ Flow ingressFlow = MDSALUtil.buildFlowNew(stypeOpenFlow.getDispatcherTableId(), serviceRef,
+ boundService.getServicePriority(), serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, instructions);
+ installFlow(dpId, ingressFlow, dataBroker, t);
+ }
+
+ public static void removeIngressFlow(Interface iface, BoundServices serviceOld, BigInteger dpId,
+ DataBroker dataBroker, WriteTransaction t) {
+ LOG.debug("Removing Ingress Flows");
+ String flowKeyStr = iface.getName() + serviceOld.getServicePriority() +
+ serviceOld.getServiceName() + IfmConstants.VLAN_INTERFACE_INGRESS_TABLE;
+ FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr));
+ Node nodeDpn = buildInventoryDpnNode(dpId);
+ InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(IfmConstants.VLAN_INTERFACE_INGRESS_TABLE)).child(Flow.class, flowKey).build();
+
+ t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
+ }
+
+ public static void removeLPortDispatcherFlow(BigInteger dpId, Interface iface, BoundServices boundServicesOld,
+ DataBroker dataBroker, WriteTransaction t) {
+ LOG.debug("Removing LPort Dispatcher Flows {}, {}", dpId, iface);
+ Long interfaceTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+
+ StypeOpenflow stypeOpenFlow = boundServicesOld.getAugmentation(StypeOpenflow.class);
+ String flowKeyStr = iface.getName() + boundServicesOld.getServicePriority() +
+ boundServicesOld.getServiceName() + stypeOpenFlow.getDispatcherTableId();
+ FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr));
+ Node nodeDpn = buildInventoryDpnNode(dpId);
+ InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(stypeOpenFlow.getDispatcherTableId())).child(Flow.class, flowKey).build();
+
+ t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
+ }
+
+ public static String getInterfaceRefInfo(String dpId, String portName) {
+ String portRefInfo = "";
+ if (!"".equals(dpId)) {
+ portRefInfo = dpId.toString() + ":";
+ }
+ portRefInfo = portRefInfo + portName;
+ return portRefInfo;
+ }
+}
\ No newline at end of file
@Override
public java.lang.AutoCloseable createInstance() {
InterfacemgrProvider provider = new InterfacemgrProvider();
+ provider.setRpcProviderRegistry(getRpcRegistryDependency());
+
getBrokerDependency().registerProvider(provider);
return provider;
}
}
}
}
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-rpc-registry;
+ }
+ }
+ }
}
}
-}
\ No newline at end of file
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.*;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public abstract class AsyncDataChangeListenerBase<T extends DataObject, K extends DataChangeListener> implements DataChangeListener, AutoCloseable {
+ private static final Logger LOG = LoggerFactory.getLogger(AsyncDataChangeListenerBase.class);
+
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1;
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1;
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300;
+ private static final int STARTUP_LOOP_TICK = 500;
+ private static final int STARTUP_LOOP_MAX_RETRIES = 8;
+
+ private static ThreadPoolExecutor dataChangeHandlerExecutor = new ThreadPoolExecutor(
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE,
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE,
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>());
+
+ private ListenerRegistration<K> listenerRegistration;
+ protected final Class<T> clazz;
+ private final Class<K> eventClazz;
+
+ /**
+ * @param clazz - for which the data change event is received
+ */
+ public AsyncDataChangeListenerBase(Class<T> clazz, Class<K> eventClazz) {
+ this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+ this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!");
+ }
+
+ public void registerListener(final LogicalDatastoreType dsType, final DataBroker db) {
+ try {
+ TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+ listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
+ @Override
+ public ListenerRegistration call() throws Exception {
+ return db.registerDataChangeListener(dsType, getWildCardPath(), getDataChangeListener(), getDataChangeScope());
+ }
+ });
+ } catch (final Exception e) {
+ LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
+ LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
+ throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e);
+ }
+ }
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ if (changeEvent == null) {
+ return;
+ }
+
+ DataChangeHandler dataChangeHandler = new DataChangeHandler(changeEvent);
+ dataChangeHandlerExecutor.execute(dataChangeHandler);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
+ final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null
+ ? createdData.keySet() : Collections.<InstanceIdentifier<?>>emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(createdData.get(key));
+ if (value.isPresent()) {
+ this.add(createKeyIdent, (T)value.get());
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,
+ final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null
+ ? updateData.keySet() : Collections.<InstanceIdentifier<?>>emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(updateData.get(key));
+ final Optional<DataObject> original = Optional.of(originalData.get(key));
+ if (value.isPresent() && original.isPresent()) {
+ this.update(updateKeyIdent, (T) original.get(), (T) value.get());
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void removeData(final Set<InstanceIdentifier<?>> removeData,
+ final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ for (InstanceIdentifier<?> key : removeData) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
+ final DataObject removeValue = originalData.get(key);
+ this.remove(ident, (T)removeValue);
+ }
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error when cleaning up DataChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ LOG.info("Interface Manager Closed");
+ }
+
+ protected abstract void remove(InstanceIdentifier<T> identifier, T del);
+
+ protected abstract void update(InstanceIdentifier<T> identifier, T original, T update);
+
+ protected abstract void add(InstanceIdentifier<T> identifier, T add);
+
+ protected abstract InstanceIdentifier<T> getWildCardPath();
+
+ protected abstract DataChangeListener getDataChangeListener();
+
+ protected abstract AsyncDataBroker.DataChangeScope getDataChangeScope();
+
+ public class DataChangeHandler implements Runnable {
+ final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent;
+
+ public DataChangeHandler(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ this.changeEvent = changeEvent;
+ }
+
+ @Override
+ public void run() {
+ Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+
+ /* All DataObjects for create */
+ final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
+ ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+ /* All DataObjects for remove */
+ final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+ ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>>emptySet();
+ /* All DataObjects for updates */
+ final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
+ ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+ /* All Original DataObjects */
+ final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
+ ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+
+ createData(createdData);
+ updateData(updateData, originalData);
+ removeData(removeData, originalData);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.*;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public abstract class AsyncDataTreeChangeListenerBase<T extends DataObject, K extends DataTreeChangeListener> implements DataTreeChangeListener<T>, AutoCloseable {
+ private static final Logger LOG = LoggerFactory.getLogger(AsyncDataTreeChangeListenerBase.class);
+
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1;
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1;
+ private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300;
+ private static final int STARTUP_LOOP_TICK = 500;
+ private static final int STARTUP_LOOP_MAX_RETRIES = 8;
+
+ private ListenerRegistration<K> listenerRegistration;
+
+ private static ThreadPoolExecutor dataTreeChangeHandlerExecutor = new ThreadPoolExecutor(
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE,
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE,
+ DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>());
+
+ protected final Class<T> clazz;
+ private final Class<K> eventClazz;
+
+ public AsyncDataTreeChangeListenerBase(Class<T> clazz, Class<K> eventClazz) {
+ this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+ this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!");
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
+ if (changes == null || changes.isEmpty()) {
+ return;
+ }
+
+ DataTreeChangeHandler dataTreeChangeHandler = new DataTreeChangeHandler(changes);
+ dataTreeChangeHandlerExecutor.execute(dataTreeChangeHandler);
+ }
+
+ public void registerListener(LogicalDatastoreType dsType, final DataBroker db) {
+ final DataTreeIdentifier<T> treeId = new DataTreeIdentifier<>(dsType, getWildCardPath());
+ try {
+ TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+ listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
+ @Override
+ public ListenerRegistration<K> call() throws Exception {
+ return db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener());
+ }
+ });
+ } catch (final Exception e) {
+ LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
+ LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
+ throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error when cleaning up DataTreeChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ protected abstract InstanceIdentifier<T> getWildCardPath();
+ protected abstract void remove(InstanceIdentifier<T> key, T dataObjectModification);
+ protected abstract void update(InstanceIdentifier<T> key, T dataObjectModificationBefore, T dataObjectModificationAfter);
+ protected abstract void add(InstanceIdentifier<T> key, T dataObjectModification);
+ protected abstract K getDataTreeChangeListener();
+
+ public class DataTreeChangeHandler implements Runnable {
+ Collection<DataTreeModification<T>> changes;
+
+ public DataTreeChangeHandler(Collection<DataTreeModification<T>> changes) {
+ this.changes = changes;
+ }
+
+
+
+ @Override
+ public void run() {
+ for (DataTreeModification<T> change : changes) {
+ final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<T> mod = change.getRootNode();
+
+ switch (mod.getModificationType()) {
+ case DELETE:
+ remove(key, mod.getDataBefore());
+ break;
+ case SUBTREE_MODIFIED:
+ update(key, mod.getDataBefore(), mod.getDataAfter());
+ break;
+ case WRITE:
+ if (mod.getDataBefore() == null) {
+ add(key, mod.getDataAfter());
+ } else {
+ update(key, mod.getDataBefore(), mod.getDataAfter());
+ }
+ break;
+ default:
+ // FIXME: May be not a good idea to throw.
+ throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+
+public class DataStoreJobCoordinator {
+ private static final Logger LOG = LoggerFactory.getLogger(DataStoreJobCoordinator.class);
+
+ private static final int THREADPOOL_SIZE = Runtime.getRuntime().availableProcessors();
+
+ private ForkJoinPool fjPool;
+ private Map<Integer,Map<String, JobQueue>> jobQueueMap = new ConcurrentHashMap<>();
+
+ private static DataStoreJobCoordinator instance;
+
+ static {
+ instance = new DataStoreJobCoordinator();
+ }
+
+ public static DataStoreJobCoordinator getInstance() {
+ return instance;
+ }
+
+ /**
+ *
+ */
+ private DataStoreJobCoordinator() {
+ fjPool = new ForkJoinPool();
+
+ for (int i = 0; i < THREADPOOL_SIZE; i++) {
+ Map<String, JobQueue> jobEntriesMap = new ConcurrentHashMap<String, JobQueue>();
+ jobQueueMap.put(i, jobEntriesMap);
+ }
+
+ new Thread(new JobQueueHandler()).start();
+ }
+
+ public void enqueueJob(String key,
+ Callable<List<ListenableFuture<Void>>> mainWorker) {
+ enqueueJob(key, mainWorker, null, 0);
+ }
+
+ public void enqueueJob(String key,
+ Callable<List<ListenableFuture<Void>>> mainWorker,
+ RollbackCallable rollbackWorker) {
+ enqueueJob(key, mainWorker, rollbackWorker, 0);
+ }
+
+ public void enqueueJob(String key,
+ Callable<List<ListenableFuture<Void>>> mainWorker,
+ int maxRetries) {
+ enqueueJob(key, mainWorker, null, maxRetries);
+ }
+
+ /**
+ *
+ * @param key
+ * @param mainWorker
+ * @param rollbackWorker
+ * @param maxRetries
+ *
+ * This is used by the external applications to enqueue a Job with an appropriate key.
+ * A JobEntry is created and queued appropriately.
+ */
+
+ public void enqueueJob(String key,
+ Callable<List<ListenableFuture<Void>>> mainWorker,
+ RollbackCallable rollbackWorker,
+ int maxRetries) {
+ JobEntry jobEntry = new JobEntry(key, mainWorker, rollbackWorker, maxRetries);
+ Integer hashKey = getHashKey(key);
+ LOG.debug("Obtained Hashkey: {}, for jobkey: {}", hashKey, key);
+
+ Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(hashKey);
+ synchronized (jobEntriesMap) {
+ JobQueue jobQueue = jobEntriesMap.get(key);
+ if (jobQueue == null) {
+ jobQueue = new JobQueue();
+ }
+ jobQueue.addEntry(jobEntry);
+ jobEntriesMap.put(key, jobQueue);
+ }
+
+ jobQueueMap.put(hashKey, jobEntriesMap); // Is this really needed ?
+ }
+
+ /**
+ * clearJob is used to cleanup the submitted job from the jobqueue.
+ **/
+ private void clearJob(JobEntry jobEntry) {
+ Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(getHashKey(jobEntry.getKey()));
+ synchronized (jobEntriesMap) {
+ JobQueue jobQueue = jobEntriesMap.get(jobEntry.getKey());
+ jobQueue.setExecutingEntry(null);
+ if (jobQueue.getWaitingEntries().isEmpty()) {
+ jobEntriesMap.remove(jobEntry.getKey());
+ }
+ }
+ }
+
+ /**
+ *
+ * @param key
+ * @return generated hashkey
+ *
+ * Used to generate the hashkey in to the jobQueueMap.
+ */
+ private Integer getHashKey(String key) {
+ int code = key.hashCode();
+ return (code % THREADPOOL_SIZE + THREADPOOL_SIZE) % THREADPOOL_SIZE;
+ }
+
+ /**
+ * JobCallback class is used as a future callback for
+ * main and rollback workers to handle success and failure.
+ */
+ private class JobCallback implements FutureCallback<List<Void>> {
+ private JobEntry jobEntry;
+
+ public JobCallback(JobEntry jobEntry) {
+ this.jobEntry = jobEntry;
+ }
+
+ /**
+ * @param voids
+ * This implies that all the future instances have returned success. -- TODO: Confirm this
+ */
+ @Override
+ public void onSuccess(List<Void> voids) {
+ clearJob(jobEntry);
+ }
+
+ /**
+ *
+ * @param throwable
+ * This method is used to handle failure callbacks.
+ * If more retry needed, the retrycount is decremented and mainworker is executed again.
+ * After retries completed, rollbackworker is executed.
+ * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
+ */
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ LOG.warn("Job: {} failed with exception: {}", jobEntry, throwable.getStackTrace());
+ if (jobEntry.getMainWorker() == null) {
+ LOG.error("Job: {} failed with Double-Fault. Bailing Out.", jobEntry);
+ clearJob(jobEntry);
+ return;
+ }
+
+ if (jobEntry.decrementRetryCountAndGet() > 0) {
+ MainTask worker = new MainTask(jobEntry);
+ fjPool.execute(worker);
+ return;
+ }
+
+ if (jobEntry.getRollbackWorker() != null) {
+ jobEntry.setMainWorker(null);
+ RollbackTask rollbackTask = new RollbackTask(jobEntry);
+ fjPool.execute(rollbackTask);
+ return;
+ }
+
+ clearJob(jobEntry);
+ }
+ }
+
+ /**
+ * RollbackTask is used to execute the RollbackCallable provided by the application
+ * in the eventuality of a failure.
+ */
+
+ private class RollbackTask implements Runnable {
+ private JobEntry jobEntry;
+
+ public RollbackTask(JobEntry jobEntry) {
+ this.jobEntry = jobEntry;
+ }
+
+ @Override
+ public void run() {
+ RollbackCallable callable = jobEntry.getRollbackWorker();
+ callable.setFutures(jobEntry.getFutures());
+ List<ListenableFuture<Void>> futures = null;
+
+ try {
+ futures = callable.call();
+ } catch (Exception e){
+ LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace());
+ e.printStackTrace();
+ }
+
+ if (futures == null || futures.isEmpty()) {
+ clearJob(jobEntry);
+ return;
+ }
+
+ ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ Futures.addCallback(listenableFuture, new JobCallback(jobEntry));
+ jobEntry.setFutures(futures);
+ }
+ }
+
+ /**
+ * MainTask is used to execute the MainWorker callable.
+ */
+
+ private class MainTask implements Runnable {
+ private JobEntry jobEntry;
+
+ public MainTask(JobEntry jobEntry) {
+ this.jobEntry = jobEntry;
+ }
+
+ @Override
+ public void run() {
+ List<ListenableFuture<Void>> futures = null;
+ try {
+ futures = jobEntry.getMainWorker().call();
+ } catch (Exception e){
+ LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace());
+ e.printStackTrace();
+ }
+
+ if (futures == null || futures.isEmpty()) {
+ clearJob(jobEntry);
+ return;
+ }
+
+ ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ Futures.addCallback(listenableFuture, new JobCallback(jobEntry));
+ jobEntry.setFutures(futures);
+ }
+ }
+
+ private class JobQueueHandler implements Runnable {
+ @Override
+ public void run() {
+ LOG.debug("Starting JobQueue Handler Thread.");
+ while (true) {
+ try {
+ boolean jobAddedToPool = false;
+ for (int i = 0; i < THREADPOOL_SIZE; i++) {
+ Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(i);
+ if (jobEntriesMap.isEmpty()) {
+ continue;
+ }
+
+ synchronized (jobEntriesMap) {
+ Iterator it = jobEntriesMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, JobQueue> entry = (Map.Entry)it.next();
+ if (entry.getValue().getExecutingEntry() != null) {
+ continue;
+ }
+ JobEntry jobEntry = entry.getValue().getWaitingEntries().poll();
+ if (jobEntry != null) {
+ entry.getValue().setExecutingEntry(jobEntry);
+ MainTask worker = new MainTask(jobEntry);
+ fjPool.execute(worker);
+ jobAddedToPool = true;
+ } else {
+ it.remove();
+ }
+ }
+ }
+ }
+
+ if (!jobAddedToPool) {
+ TimeUnit.SECONDS.sleep(1);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * JobEntry is the entity built per job submitted by the application and
+ * enqueued to the book-keeping data structure.
+ */
+public class JobEntry {
+ final private String key;
+ private Callable<List<ListenableFuture<Void>>> mainWorker;
+ final private RollbackCallable rollbackWorker;
+ private AtomicInteger retryCount;
+ private List<ListenableFuture<Void>> futures;
+
+ public JobEntry(String key,
+ Callable<List<ListenableFuture<Void>>> mainWorker,
+ RollbackCallable rollbackWorker,
+ int maxRetries) {
+ this.key = key;
+ this.mainWorker = mainWorker;
+ this.rollbackWorker = rollbackWorker;
+ retryCount = new AtomicInteger(maxRetries);
+ }
+
+ /**
+ *
+ * @return
+ *
+ * The key provided by the application that segregates the
+ * callables that can be run parallely.
+ * NOTE: Currently, this is a string. Can be converted to Object where
+ * Object implementation should provide the hashcode and equals methods.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ public Callable<List<ListenableFuture<Void>>> getMainWorker() {
+ return mainWorker;
+ }
+
+ public void setMainWorker(Callable<List<ListenableFuture<Void>>> mainWorker) {
+ this.mainWorker = mainWorker;
+ }
+
+ public RollbackCallable getRollbackWorker() {
+ return rollbackWorker;
+ }
+
+ public int decrementRetryCountAndGet() {
+ return retryCount.decrementAndGet();
+ }
+
+ public List<ListenableFuture<Void>> getFutures() {
+ return futures;
+ }
+
+ public void setFutures(List<ListenableFuture<Void>> futures) {
+ this.futures = futures;
+ }
+
+ @Override
+ public String toString() {
+ return "JobEntry{" +
+ "key='" + key + '\'' +
+ ", mainWorker=" + mainWorker +
+ ", rollbackWorker=" + rollbackWorker +
+ ", retryCount=" + retryCount +
+ ", futures=" + futures +
+ '}';
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class JobQueue {
+ private ConcurrentLinkedQueue<JobEntry> waitingEntries;
+ private JobEntry executingEntry;
+
+ public JobQueue() {
+ waitingEntries = new ConcurrentLinkedQueue<JobEntry>();
+ }
+
+ public void addEntry(JobEntry entry) {
+ waitingEntries.add(entry); // FIXME - Try/Catch.
+ }
+
+ public ConcurrentLinkedQueue<JobEntry> getWaitingEntries() {
+ return waitingEntries;
+ }
+
+ public JobEntry getExecutingEntry() {
+ return executingEntry;
+ }
+
+ public void setExecutingEntry(JobEntry executingEntry) {
+ this.executingEntry = executingEntry;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public abstract class RollbackCallable implements Callable<List<ListenableFuture<Void>>> {
+
+ private List<ListenableFuture<Void>> futures;
+
+ public RollbackCallable() {
+ }
+
+ public List<ListenableFuture<Void>> getFutures() {
+ return futures;
+ }
+
+ public void setFutures(List<ListenableFuture<Void>> futures) {
+ this.futures = futures;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.Callable;
+
+public class TaskRetryLooper {
+ private static final Logger LOG = LoggerFactory.getLogger(TaskRetryLooper.class);
+
+ private final long tick;
+ private final int maxRetries;
+
+ /**
+ * @param tick sleep between steps in miliseconds
+ * @param maxRetries retries limit
+ */
+ public TaskRetryLooper(long tick, int maxRetries) {
+ this.tick = tick;
+ this.maxRetries = maxRetries;
+ }
+
+ public <T> T loopUntilNoException(Callable<T> task) throws Exception {
+ T output = null;
+
+ Exception taskException = null;
+ for (int i = 0; i < maxRetries; i++) {
+ taskException = null;
+ try {
+ output = task.call();
+ break;
+ } catch (Exception exception) {
+ LOG.debug("looper step failed: {}", exception.getMessage());
+ taskException = exception;
+ }
+
+ try {
+ Thread.sleep(tick);
+ } catch (InterruptedException e) {
+ LOG.debug("interrupted: {}", e.getMessage(), e);
+ }
+ }
+
+ if (taskException != null) {
+ throw taskException;
+ }
+
+ LOG.debug("looper step succeeded: {}", output);
+ return output;
+ }
+}
\ No newline at end of file
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
.setCookie(new FlowCookie(cookie)).build();
}
+ public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+ int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
+ return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
+ listMatchInfo, listInstructionInfo, true);
+ }
+
+ private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+ int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
+ List<Instruction> listInstructionInfo, boolean isStrict) {
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
+ .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build())
+ .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
+ .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
+ .setCookie(new FlowCookie(cookie)).build();
+ }
+
public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
List<BucketInfo> listBucketInfo) {
// TODO Auto-generated method stub
return null;
}
+
+ public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) {
+ Action popVlanAction = new ActionBuilder().setAction(
+ new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
+ .setKey(new ActionKey(actionKey)).build();
+ List<Action> listAction = new ArrayList<Action> ();
+ listAction.add(popVlanAction);
+ ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
+ ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
+ InstructionBuilder instructionBuilder = new InstructionBuilder();
+
+ instructionBuilder.setInstruction(applyActionsCase);
+ instructionBuilder.setKey(new InstructionKey(instructionKey));
+ return instructionBuilder.build();
+ }
+
+ public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata,
+ BigInteger mask, int instructionKey) {
+ return new InstructionBuilder()
+ .setInstruction(
+ new WriteMetadataCaseBuilder().setWriteMetadata(
+ new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build())
+ .build()).setKey(new InstructionKey(instructionKey)).build();
+ }
}
public class MetaDataUtil {
public static final BigInteger METADATA_MASK_VRFID = new BigInteger("00000000FFFFFFFF", 16);
+ public static final BigInteger METADATA_MASK_LPORT_TAG = new BigInteger("1FFFFF0000000000", 16);
+ public static final BigInteger METADATA_MASK_SERVICE = new BigInteger("000000FFFF000000", 16);
+ public static final BigInteger METADATA_MASK_SERVICE_INDEX = new BigInteger("E000000000000000", 16);
+ public static final BigInteger METADATA_MASK_LPORT_WRITE = new BigInteger("00FFFF0000000000", 16);
+ public static final BigInteger METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID = new BigInteger("08000000FFFFFF00", 16);
+ public static final BigInteger METADATA_MASK_LABEL_ITM = new BigInteger("40FFFFFF000000FF", 16);
+
+ public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex) {
+ return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag));
+ }
+
+ public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex,
+ BigInteger serviceMetaData) {
+ return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag)).or(serviceMetaData);
+ }
+
+ public static BigInteger getServiceIndexMetaData(int serviceIndex) {
+ return new BigInteger("7", 16).and(BigInteger.valueOf(serviceIndex)).shiftLeft(61);
+ }
+
+ public static BigInteger getLportTagMetaData(int lportTag) {
+ return new BigInteger("1FFFFF", 16).and(BigInteger.valueOf(lportTag)).shiftLeft(40);
+ }
+
+ public static BigInteger getMetaDataMaskForLPortDispatcher() {
+ return METADATA_MASK_SERVICE_INDEX.or(METADATA_MASK_LPORT_TAG);
+ }
+
+ public static BigInteger getMetadataLPort(int lPortTag) {
+ return (new BigInteger("FFFF", 16).and(BigInteger.valueOf(lPortTag))).shiftLeft(40);
+ }
+
+ public static BigInteger getLportFromMetadata(BigInteger metadata) {
+ return (metadata.and(METADATA_MASK_LPORT_TAG)).shiftRight(40);
+ }
+
+ public static int getElanTagFromMetadata(BigInteger metadata) {
+ return (((metadata.and(MetaDataUtil.METADATA_MASK_SERVICE)).
+ shiftRight(24))).intValue();
+ }
+
+ public static BigInteger getMetaDataMaskForLPortDispatcher(BigInteger metadataMaskForServiceIndex,
+ BigInteger metadataMaskForLPortTag, BigInteger metadataMaskForService) {
+ return metadataMaskForServiceIndex.or(metadataMaskForLPortTag).or(metadataMaskForService);
+ }
+
+ /**
+ * For the tunnel id with VNI and valid-vni-flag set, the most significant byte
+ * should have 08. So, shifting 08 to 7 bytes (56 bits) and the result is OR-ed with
+ * VNI being shifted to 1 byte.
+ */
+ public static BigInteger getTunnelIdWithValidVniBitAndVniSet(int vni) {
+ return BigInteger.valueOf(0X08).shiftLeft(56).or(BigInteger.valueOf(vni).shiftLeft(8));
+ }
}
import java.math.BigInteger;
import java.util.List;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
public interface IMdsalApiManager {
public void installFlow(FlowEntity flowEntity);
+ public CheckedFuture<Void,TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flowEntity);
+
+ public CheckedFuture<Void,TransactionCommitFailedException> removeFlow(BigInteger dpId, FlowEntity flowEntity);
+
public void removeFlow(FlowEntity flowEntity);
public void installGroup(GroupEntity groupEntity);
}
}
+ public CheckedFuture<Void,TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flow) {
+ FlowKey flowKey = new FlowKey( new FlowId(flow.getId()) );
+ Node nodeDpn = buildDpnNode(dpId);
+ InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build();
+
+ WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
+ modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
+ return modification.submit();
+ }
+
public void installGroup(GroupEntity groupEntity) {
try {
Group group = groupEntity.getGroupBuilder().build();
WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
- modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
+ modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId);
CheckedFuture<Void,TransactionCommitFailedException> submitFuture = modification.submit();
}
}
+ public CheckedFuture<Void,TransactionCommitFailedException> removeFlowNew(FlowEntity flowEntity) {
+ s_logger.debug("Remove flow {}",flowEntity);
+ Node nodeDpn = buildDpnNode(flowEntity.getDpnId());
+ FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getFlowId()));
+ InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class, flowKey).build();
+ WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
+ modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
+ return modification.submit();
+ }
+
public void removeGroup(GroupEntity groupEntity) {
try {
Node nodeDpn = buildDpnNode(groupEntity.getDpnId());
import java.math.BigInteger;
import java.util.List;
+
+import com.google.common.util.concurrent.CheckedFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
mdSalMgr.installFlow(flowEntity);
}
+ @Override
+ public CheckedFuture<Void, TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flowEntity) {
+ return mdSalMgr.installFlow(dpId, flowEntity);
+ }
+
+ @Override
+ public CheckedFuture<Void, TransactionCommitFailedException> removeFlow(BigInteger dpId, FlowEntity flowEntity) {
+ return mdSalMgr.removeFlowNew(flowEntity);
+ }
+
@Override
public void removeFlow(FlowEntity flowEntity) {
mdSalMgr.removeFlow(flowEntity);
}
}
- public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) {
+ public void createRemoteNextHop(String ifName, String ipAddress) {
String nhKey = new String("nexthop." + ifName + ipAddress);
int groupId = createNextHopPointer(nhKey);
- BigInteger dpnId = getDpnId(ofPortId);
+ BigInteger dpnId = interfaceManager.getDpnForInterface(ifName);
TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
if (nexthop == null) {
List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
}
- private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path) {
ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
import java.math.BigInteger;
+
+import com.google.common.base.Optional;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
private void registerListener(final DataBroker db) {
try {
- listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
getWildCardPath(), OdlInterfaceChangeListener.this, DataChangeScope.SUBTREE);
} catch (final Exception e) {
LOG.error("Nexthop Manager Interfaces DataChange listener registration fail!", e);
}
@Override
- protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
- LOG.trace("Adding Interface : key: " + identifier + ", value=" + intrf );
-
- if (intrf.getType().equals(L3tunnel.class)) {
- IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
- IpAddress gatewayIp = intfData.getGatewayIp();
- IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp;
- NodeConnectorId ofPort = intrf.getAugmentation(BaseIds.class).getOfPortId();
- nexthopManager.createRemoteNextHop(intrf.getName(), ofPort.toString(), remoteIp.getIpv4Address().getValue());
+ protected void add(InstanceIdentifier<Interface> identifier, Interface interfaceInfo) {
+ LOG.trace("Adding Interface : key: " + identifier + ", value=" + interfaceInfo );
+ // READ interface config information
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf =
+ getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName()));
+
+ if(intrf != null && intrf.getType().equals(Tunnel.class)){
+ IfTunnel intfData = intrf.getAugmentation(IfTunnel.class);
+ IpAddress gatewayIp = intfData.getTunnelGateway();
+ IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp;
+ nexthopManager.createRemoteNextHop(intrf.getName(), remoteIp.getIpv4Address().getValue());
}
}
-
private InstanceIdentifier<Interface> getWildCardPath() {
- return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+ return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
}
@Override
protected void remove(InstanceIdentifier<Interface> identifier,
- Interface intrf) {
- LOG.trace("Removing interface : key: " + identifier + ", value=" + intrf );
- if (intrf.getType().equals(L3tunnel.class)) {
+ Interface interfaceInfo) {
+ LOG.trace("Removing interface : key: " + identifier + ", value=" + interfaceInfo );
+ // READ interface config information
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf =
+ getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName()));
+
+ if (intrf != null && intrf.getType().equals(Tunnel.class)) {
BigInteger dpnId = interfaceManager.getDpnForInterface(intrf);
- IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
- IpAddress gatewayIp = intfData.getGatewayIp();
- IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp;
+ IfTunnel intfData = intrf.getAugmentation(IfTunnel.class);
+ IpAddress gatewayIp = intfData.getTunnelGateway();
+ IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp;
nexthopManager.removeRemoteNextHop(dpnId, intrf.getName(), remoteIp.getIpv4Address().getValue());
}
}
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(NexthopManager nexthopManager, InterfaceKey interfaceKey) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceId =
+ getInterfaceIdentifier(interfaceKey);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceOptional =
+ nexthopManager.read(LogicalDatastoreType.CONFIGURATION, interfaceId);
+ if (!interfaceOptional.isPresent()) {
+ return null;
+ }
+
+ return interfaceOptional.get();
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceInstanceIdentifierBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, interfaceKey);
+ return interfaceInstanceIdentifierBuilder.build();
+ }
+
@Override
protected void update(InstanceIdentifier<Interface> identifier,
Interface original, Interface update) {
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.vpnservice;
-import java.math.BigInteger;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
import org.opendaylight.vpnservice.mdsalutil.NwConstants;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigInteger;
+
public class InterfaceChangeListener extends AbstractDataChangeListener<Interface> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeListener.class);
@Override
protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
LOG.trace("Remove interface event - key: {}, value: {}", identifier, intrf );
- if (intrf.getType().equals(L3tunnel.class)) {
+ if (intrf.getType().equals(Tunnel.class)) {
BigInteger dpnId = interfaceManager.getDpnForInterface(intrf);
String ifName = intrf.getName();
LOG.debug("Removing tunnel interface associated with Interface {}", intrf.getName());
*/
package org.opendaylight.vpnservice;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
import java.math.BigInteger;
import java.util.Collection;
int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
short gotoTableId = VpnConstants.FIB_TABLE;
- if(intf.getType().equals(L3tunnel.class)){
+ if(intf.getType().equals(Tunnel.class)){
gotoTableId = VpnConstants.LFIB_TABLE;
}
LOG.trace("Operation Interface update event - Old: {}, New: {}", original, update);
String interfaceName = update.getName();
Interface intf = getInterface(interfaceName);
- if (intf != null && intf.getType().equals(L3tunnel.class)) {
+ if (intf != null && intf.getType().equals(Tunnel.class)) {
BigInteger dpnId = interfaceManager.getDpnForInterface(interfaceName);
if(update.getOperStatus().equals(OperStatus.Up)) {
//Create ingress to LFIB
LOG.trace("Operational Interface add event - {}", add);
String interfaceName = add.getName();
Interface intf = getInterface(interfaceName);
- if (intf != null && intf.getType().equals(L3tunnel.class)) {
+ if (intf != null && intf.getType().equals(Tunnel.class)) {
BigInteger dpnId = interfaceManager.getDpnForInterface(interfaceName);
if(add.getOperStatus().equals(OperStatus.Up)) {
//Create ingress to LFIB