From d881f3df8fcf72d3a46d31947d4cca4ccbc6d275 Mon Sep 17 00:00:00 2001 From: Faseela K Date: Thu, 17 Dec 2015 22:59:35 +0530 Subject: [PATCH] support for create/remove terminatingserviceActions Change-Id: I11ad9df3fef64cfeb2fc1687e77f4134deea9b00 Signed-off-by: Faseela K --- .../src/main/yang/odl-interface-rpc.yang | 31 ++++ .../src/main/config/default-config.xml | 5 + .../vpnservice/interfacemgr/IfmConstants.java | 7 +- .../interfacemgr/InterfacemgrProvider.java | 9 +- .../InterfaceManagerRpcService.java | 134 ++++++++++++++++-- .../rev150325/InterfacemgrImplModule.java | 2 +- .../src/main/yang/interfacemgr-impl.yang | 9 ++ .../vpnservice/mdsalutil/MatchFieldType.java | 6 +- 8 files changed, 183 insertions(+), 20 deletions(-) diff --git a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang index ef1cad59..a0399466 100644 --- a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang +++ b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang @@ -142,4 +142,35 @@ module odl-interface-rpc { } } } + + rpc create-terminating-service-actions { + description "create the ingress terminating service table entries"; + input { + leaf dpid { + type uint64; + } + leaf tunnel-key { + type uint64; + } + leaf interface-name { + type string; + } + uses offlow:instruction-list; + } + } + + rpc remove-terminating-service-actions { + description "remove the ingress terminating service table entries"; + input { + leaf dpid { + type uint64; + } + leaf interface-name { + type string; + } + leaf tunnel-key { + type uint64; + } + } + } } \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml b/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml index a0e92ffb..a7b9952a 100644 --- a/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml +++ b/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml @@ -11,6 +11,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&revision=2015-03-31 urn:opendaylight:params:xml:ns:yang:interfacemgr:impl?module=interfacemgr-impl&revision=2015-03-25 + urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&revision=2015-04-10 urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28 @@ -24,6 +25,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html binding:binding-broker-osgi-registry binding-osgi-broker + + mdsalutil:odl-mdsalutil + mdsalutil-service + binding:binding-rpc-registry binding-rpc-broker diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java index 351a37a5..79076578 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java @@ -8,6 +8,8 @@ package org.opendaylight.vpnservice.interfacemgr; +import java.math.BigInteger; + public class IfmConstants { public static final String IFM_IDPOOL_NAME = "interfaces"; public static final long IFM_ID_POOL_START = 1L; @@ -18,5 +20,8 @@ public class IfmConstants { 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; - + public static final short INTERNAL_TUNNEL_TABLE = 22; + public static final short EXTERNAL_TUNNEL_TABLE = 23; + public static final String TUNNEL_TABLE_FLOWID_PREFIX = "TUNNEL."; + public static final BigInteger TUNNEL_TABLE_COOKIE = new BigInteger("9000000", 16); } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java index f519acf3..5865e7b0 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java @@ -23,6 +23,7 @@ import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listen import org.opendaylight.vpnservice.interfacemgr.listeners.VlanMemberConfigListener; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; 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.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; @@ -44,7 +45,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable private RpcProviderRegistry rpcProviderRegistry; private IdManagerService idManager; - + private IMdsalApiManager mdsalManager; private InterfaceConfigListener interfaceConfigListener; private InterfaceTopologyStateListener topologyStateListener; private InterfaceInventoryStateListener interfaceInventoryStateListener; @@ -59,6 +60,10 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable this.rpcProviderRegistry = rpcProviderRegistry; } + public void setMdsalManager(IMdsalApiManager mdsalManager) { + this.mdsalManager = mdsalManager; + } + @Override public void onSessionInitiated(ProviderContext session) { LOG.info("InterfacemgrProvider Session Initiated"); @@ -67,7 +72,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable idManager = rpcProviderRegistry.getRpcService(IdManagerService.class); createIdPool(); - interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker); + interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker, mdsalManager); rpcRegistration = getRpcProviderRegistry().addRpcImplementation( OdlInterfaceRpcService.class, interfaceManagerRpcService); diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java index ef70eb84..95d81df6 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java @@ -9,45 +9,41 @@ package org.opendaylight.vpnservice.interfacemgr.rpcservice; import com.google.common.base.Optional; +import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; 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.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.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils; +import org.opendaylight.vpnservice.mdsalutil.*; +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.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.inventory.rev130819.tables.table.Flow; 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.IfIndexesInterfaceMap; -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._if.indexes._interface.map.IfIndexInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterfaceKey; -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.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; @@ -62,8 +58,10 @@ 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) { + IMdsalApiManager mdsalMgr; + public InterfaceManagerRpcService(DataBroker dataBroker, IMdsalApiManager mdsalMgr) { this.dataBroker = dataBroker; + this.mdsalMgr = mdsalMgr; } @Override @@ -95,6 +93,108 @@ public class InterfaceManagerRpcService implements OdlInterfaceRpcService { return Futures.immediateFuture(rpcResultBuilder.build()); } + @Override + public Future> createTerminatingServiceActions(CreateTerminatingServiceActionsInput input) { + final SettableFuture> result = SettableFuture.create(); + try{ + List mkMatches = new ArrayList(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + LOG.info("create terminatingServiceAction on DpnId = {} for tunnel-key {}", input.getDpid() , input.getTunnelKey()); + + // Matching metadata + mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {input.getTunnelKey()})); + List instructions = input.getInstruction(); + Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(input.getInterfaceName()),dataBroker); + IfTunnel tunnelInfo = interfaceInfo.getAugmentation(IfTunnel.class); + if(tunnelInfo != null) { + short tableId = tunnelInfo.isInternal() ? IfmConstants.INTERNAL_TUNNEL_TABLE : + IfmConstants.EXTERNAL_TUNNEL_TABLE; + List instructionSet = new ArrayList(); + if (instructions != null && !instructions.isEmpty()) { + for (Instruction info : instructions) { + instructionSet.add(info); + } + } + final String flowRef = getFlowRef(input.getDpid(),tableId, input.getTunnelKey()); + Flow terminatingSerFlow = MDSALUtil.buildFlowNew(tableId, flowRef, + 5, "TST Flow Entry", 0, 0, + IfmConstants.TUNNEL_TABLE_COOKIE.add(input.getTunnelKey()), mkMatches, instructionSet); + + ListenableFuture installFlowResult = mdsalMgr.installFlow(input.getDpid(), terminatingSerFlow); + Futures.addCallback(installFlowResult, new FutureCallback(){ + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to install terminating service flow %s", flowRef); + LOG.error("create terminating service actions failed. {}. {}", msg, error); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + result.set(RpcResultBuilder.success().build()); + } else { + String msg = String.format("Terminating Service Actions cannot be created for a non-tunnel interface %s",input.getInterfaceName()); + LOG.error(msg); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg).build()); + } + }catch(Exception e){ + String msg = String.format("create Terminating Service Actions for %s failed",input.getInterfaceName()); + LOG.error("create Terminating Service Actions for {} failed due to {}" ,input.getDpid(), e); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, e.getMessage()).build()); + } + return result; + } + + @Override + public Future> removeTerminatingServiceActions(RemoveTerminatingServiceActionsInput input) { + final SettableFuture> result = SettableFuture.create(); + try{ + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + LOG.info("remove terminatingServiceAction on DpnId = {} for tunnel-key {}", input.getDpid() , input.getTunnelKey()); + + Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(input.getInterfaceName()),dataBroker); + IfTunnel tunnelInfo = interfaceInfo.getAugmentation(IfTunnel.class); + if(tunnelInfo != null) { + short tableId = tunnelInfo.isInternal() ? IfmConstants.INTERNAL_TUNNEL_TABLE : + IfmConstants.EXTERNAL_TUNNEL_TABLE; + final String flowRef = getFlowRef(input.getDpid(),tableId, input.getTunnelKey()); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(input.getDpid(), tableId, flowRef, + 0, flowRef, 0, 0, + null, null, null); + ListenableFuture removeFlowResult = mdsalMgr.removeFlow(input.getDpid(), flowEntity); + Futures.addCallback(removeFlowResult, new FutureCallback(){ + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to install terminating service flow %s", flowRef); + LOG.error("create terminating service actions failed. {}. {}", msg, error); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + result.set(RpcResultBuilder.success().build()); + } else { + String msg = String.format("Terminating Service Actions cannot be removed for a non-tunnel interface %s", + input.getInterfaceName()); + LOG.error(msg); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg).build()); + } + }catch(Exception e){ + LOG.error("Remove Terminating Service Actions for {} failed due to {}" ,input.getDpid(), e); + String msg = String.format("Remove Terminating Service Actions for %d failed.", input.getDpid()); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, e.getMessage()).build()); + } + return result; + } + @Override public Future> getEndpointIpForDpn(GetEndpointIpForDpnInput input) { RpcResultBuilder rpcResultBuilder; @@ -288,4 +388,8 @@ public class InterfaceManagerRpcService implements OdlInterfaceRpcService { return null; } + private String getFlowRef(BigInteger dpnId, short tableId, BigInteger tunnelKey) { + return new StringBuffer().append(IfmConstants.TUNNEL_TABLE_FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR) + .append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(tunnelKey).toString(); + } } \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java index c5e8e323..14ab2e60 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java @@ -28,7 +28,7 @@ public class InterfacemgrImplModule extends org.opendaylight.yang.gen.v1.urn.ope public java.lang.AutoCloseable createInstance() { InterfacemgrProvider provider = new InterfacemgrProvider(); provider.setRpcProviderRegistry(getRpcRegistryDependency()); - + provider.setMdsalManager(getMdsalutilDependency()); getBrokerDependency().registerProvider(provider); return provider; } diff --git a/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang b/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang index 1c8851d2..47188016 100644 --- a/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang +++ b/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang @@ -6,6 +6,7 @@ module interfacemgr-impl { import config { prefix config; revision-date 2013-04-05; } import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;} import odl-interface {prefix odlif; revision-date 2015-03-31;} + import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;} description "Service definition for interfacemgr project"; @@ -32,6 +33,14 @@ module interfacemgr-impl { } } } + container mdsalutil { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity odl-mdsal:odl-mdsalutil; + } + } + } container rpc-registry { uses config:service-ref { refine type { diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java index b889f1e5..57a7f38d 100644 --- a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java @@ -553,7 +553,11 @@ public enum MatchFieldType { } BigInteger[] tunnelIdValues = matchInfo.getBigMatchValues(); - tunnelBuilder.setTunnelId(tunnelIdValues[0]).setTunnelMask(tunnelIdValues[1]).build(); + tunnelBuilder.setTunnelId(tunnelIdValues[0]); + if(tunnelIdValues.length > 1){ + tunnelBuilder.setTunnelMask(tunnelIdValues[1]); + } + tunnelBuilder.build(); } @Override -- 2.36.6