initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bff2d76
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.iml
diff --git a/apps/fpcagent/BUCK b/apps/fpcagent/BUCK
new file mode 100644
index 0000000..c57ddf9
--- /dev/null
+++ b/apps/fpcagent/BUCK
@@ -0,0 +1,77 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//lib:JACKSON',
+ '//lib:KRYO',
+ '//models/fpcagent:onos-models-fpcagent',
+ '//models/common:onos-models-common',
+ '//apps/config:onos-apps-config',
+ '//lib:onos-yang-model',
+ '//core/api:onos-api',
+ '//lib:javax.ws.rs-api',
+ '//utils/rest:onlab-rest',
+ '//core/store/serializers:onos-core-serializers',
+ ':zeromq',
+ ':json',
+]
+
+TEST_DEPS = [
+ '//lib:TEST_ADAPTERS',
+ '//lib:TEST_REST',
+ '//utils/osgi:onlab-osgi-tests',
+]
+
+BUNDLES = [
+ '//apps/fpcagent:onos-apps-fpcagent',
+]
+
+EXCLUDED_BUNDLES = [
+ ':zeromq',
+ ':json',
+]
+
+APPS = [
+ 'org.onosproject.models.fpcagent',
+ 'org.onosproject.yang',
+ 'org.onosproject.yang-gui',
+ 'org.onosproject.config',
+ 'org.onosproject.restconf',
+ 'org.onosproject.protocols.restconfserver',
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+ test_deps = TEST_DEPS,
+ web_context = '/onos/fpcagent',
+ api_title = 'FPC Agent REST API',
+ api_package = 'org.onosproject.fpcagent.rest',
+ api_version = '1.0',
+ api_description = 'FPC Agent REST API',
+)
+
+onos_app(
+ app_name = 'org.onosproject.fpcagent',
+ title = 'YANG FPC Agent',
+ category = 'Traffic Steering',
+ url = 'http://onosproject.org',
+ description = 'FPC Agent YANG Application',
+ required_apps = APPS,
+ excluded_bundles = EXCLUDED_BUNDLES,
+)
+
+remote_jar (
+ name = 'json',
+ out = 'json-20090211.jar',
+ url = 'mvn:org.json:json:jar:20090211',
+ sha1 = 'c183aa3a2a6250293808bba12262c8920ce5a51c',
+ maven_coords = 'org.json:json:jar:NON-OSGI:20090211',
+ visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+ name = 'zeromq',
+ out = 'jeromq-0.3.5.jar',
+ url = 'mvn:org.zeromq:jeromq:jar:0.3.5',
+ sha1 = '39a79082570d114bb5433762e836e4dd9c38b03d',
+ maven_coords = 'org.zeromq:jeromq:0.3.5',
+ visibility = [ 'PUBLIC' ],
+)
diff --git a/apps/fpcagent/fpcagent.json b/apps/fpcagent/fpcagent.json
new file mode 100644
index 0000000..5b820df
--- /dev/null
+++ b/apps/fpcagent/fpcagent.json
@@ -0,0 +1,30 @@
+{
+ "apps": {
+ "org.onosproject.fpcagent": {
+ "fpcagent": {
+ "monitor-threads": 4,
+ "scheduled-monitors-poolsize": 4,
+ "dpn-listener-uri": "tcp://127.0.0.1:5569",
+ "dpn-listener-id": 1,
+ "dpn-client-uri": "tcp://127.0.0.1:5559",
+ "dpn-client-threads": 5,
+ "metricsupdate-ms": 10000,
+ "mobilityupdate-ms": 30000,
+ "activation-threads": 5,
+ "target-read-limit": 10,
+ "http-notifier-clients": 3,
+ "zmq-nbi-server-poolsize": 1,
+ "zmq-nbi-server-uri": "tcp://127.0.0.1:5570",
+ "zmq-nbi-inproc-uri": "inproc://backend",
+ "zmq-nbi-handler-poolsize": 10,
+ "http-nio2-nb-poolsize": 80,
+ "http-nio2-nb-port": 9292,
+ "node-id": "node0",
+ "network-id": "network1",
+ "zmq-broadcast-all": "1",
+ "zmq-broadcast-controllers": "2",
+ "zmq-broadcast-dpns": "3"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/Configure.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/Configure.java
new file mode 100644
index 0000000..d6b277a
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/Configure.java
@@ -0,0 +1,7 @@
+package org.onosproject.fpcagent;
+
+import org.onosproject.yang.gen.v1.fpc.rev20150105.FpcService;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentService;
+
+public interface Configure extends IetfDmmFpcagentService, FpcService {
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcConfig.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcConfig.java
new file mode 100644
index 0000000..b9cbb9f
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcConfig.java
@@ -0,0 +1,25 @@
+package org.onosproject.fpcagent;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.fpcagent.helpers.ConfigHelper;
+import org.onosproject.net.config.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+public class FpcConfig extends Config<ApplicationId> {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ public Optional<ConfigHelper> getConfig() {
+ try {
+ return Optional.of(mapper.treeToValue(object, ConfigHelper.class));
+ } catch (JsonProcessingException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ return Optional.empty();
+ }
+}
+
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
new file mode 100644
index 0000000..31ca0f0
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
@@ -0,0 +1,566 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.fpcagent;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.felix.scr.annotations.*;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.fpcagent.dto.configure.Context;
+import org.onosproject.fpcagent.dto.dpn.AddDpn;
+import org.onosproject.fpcagent.helpers.ConfigHelper;
+import org.onosproject.fpcagent.helpers.DpnApi;
+import org.onosproject.fpcagent.workers.ZMQSBPublisherManager;
+import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
+import org.onosproject.net.config.*;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.deregisterclient.DeregisterClientInput;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.RegisterClientInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.ConfigureInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.instructions.instructions.instrtype.Instr3GppMob;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opheader.OpTypeEnum;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.CreateOrUpdate;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.DeleteOrQuery;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.mobilityinfo.mobprofileparameters.ThreegppTunnel;
+import org.onosproject.yang.gen.v1.ietfdmmthreegpp.rev20160803.ietfdmmthreegpp.threegppinstr.Bits;
+import org.onosproject.yang.model.RpcInput;
+import org.onosproject.yang.model.RpcOutput;
+import org.onosproject.yang.model.RpcRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Optional;
+
+import static org.onosproject.fpcagent.helpers.Converter.getFpcIdentity;
+
+/**
+ * Fpc Manager.
+ */
+@Component(immediate = true)
+@Service
+public class FpcManager implements Configure, FpcService {
+ static final Logger log = LoggerFactory.getLogger(FpcManager.class);
+
+ private static final String FPC_APP_ID = "org.onosproject.fpcagent";
+ private static final Class<FpcConfig> CONFIG_CLASS = FpcConfig.class;
+ private final InternalNetworkConfigListener configListener =
+ new InternalNetworkConfigListener();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TenantService tenantService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private RpcRegistry rpcRegistry;
+
+ /* Services */
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private NetworkConfigRegistry registry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private NetworkConfigService configService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private CoreService coreService;
+
+// @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+// protected ModelConverter modelConverter;
+//
+// @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+// protected DynamicConfigService dynamicConfigService;
+
+ /* Variables */
+ private ApplicationId appId;
+ private FpcConfig fpcConfig;
+
+ private HashMap<String, ArrayList<Contexts>> sessionContextsMap = Maps.newHashMap();
+ private HashMap<String, ArrayList<Context>> sessionContextsRestMap = Maps.newHashMap();
+ private HashMap<String, String> nodeNetworkMap = Maps.newHashMap();
+
+ /* Config */
+ private ConfigFactory<ApplicationId, FpcConfig> fpcConfigConfigFactory =
+ new ConfigFactory<ApplicationId, FpcConfig>(
+ SubjectFactories.APP_SUBJECT_FACTORY, FpcConfig.class, "fpcagent") {
+ @Override
+ public FpcConfig createConfig() {
+ return new FpcConfig();
+ }
+ };
+
+ @Activate
+ protected void activate() {
+ appId = coreService.registerApplication(FPC_APP_ID);
+ configService.addListener(configListener);
+ registry.registerConfigFactory(fpcConfigConfigFactory);
+
+ rpcRegistry.registerRpcService(this);
+
+ tenantService.addTenant(getFpcIdentity.apply("default"));
+
+ log.info("FPC Agent Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ configService.removeListener(configListener);
+ registry.unregisterConfigFactory(fpcConfigConfigFactory);
+
+ // TODO check if null before closing
+ ZMQSBSubscriberManager.getInstance().close();
+ ZMQSBPublisherManager.getInstance().close();
+
+ rpcRegistry.unregisterRpcService(this);
+
+ log.info("FPC Agent Stopped");
+ }
+
+ public void init() {
+
+ fpcConfig.getConfig().ifPresent(
+ helper -> {
+ ZMQSBSubscriberManager.createInstance(
+ helper.dpnListenerUri(),
+ helper.zmqBroadcastAll(),
+ helper.zmqBroadcastControllers(),
+ helper.zmqBroadcastDpns(),
+ helper.nodeId(),
+ helper.networkId()
+ );
+
+ ZMQSBPublisherManager.createInstance(
+ helper.dpnClientUri(),
+ helper.dpnClientThreads()
+ );
+
+ ZMQSBPublisherManager.getInstance().open();
+ ZMQSBSubscriberManager.getInstance().open();
+ }
+ );
+ }
+
+ @Override
+ public Optional<ConfigHelper> getConfig() {
+ return fpcConfig != null ? fpcConfig.getConfig() : Optional.empty();
+ }
+
+ private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+ switch (event.type()) {
+ case CONFIG_REGISTERED:
+ case CONFIG_UNREGISTERED: {
+ break;
+ }
+ case CONFIG_REMOVED: {
+ if (event.configClass() == CONFIG_CLASS) {
+ fpcConfig = null;
+ }
+ break;
+ }
+ case CONFIG_UPDATED:
+ case CONFIG_ADDED: {
+ if (event.configClass() == CONFIG_CLASS) {
+ event.config().ifPresent(config -> {
+ fpcConfig = (FpcConfig) config;
+ init();
+ });
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ }
+
+ @Override
+ public RpcOutput configureDpn(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput configure(RpcInput rpcInput) {
+ ConfigureInput input = (ConfigureInput) rpcInput;
+ switch (input.opType()) {
+ case CREATE:
+ case UPDATE:
+ if (input.opBody() instanceof CreateOrUpdate) {
+ CreateOrUpdate createOrUpdate = (CreateOrUpdate) input.opBody();
+ createOrUpdate.contexts().forEach(
+ context -> {
+ String key = context.contextId().fpcIdentity().union().string();
+ sessionContextsMap.computeIfAbsent(key, k -> new ArrayList<>())
+ .add(context);
+ context.dpns().forEach(
+ dpn -> {
+ if (input.instructions().instrType() instanceof Instr3GppMob) {
+
+ Instr3GppMob instr3GppMob = (Instr3GppMob) input.instructions().instrType();
+ String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
+
+ Ip4Address ulLocalAddress = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+ dlRemoteAddress = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString()),
+ dlLocalAddress = Ip4Address.valueOf(context.dl().tunnelLocalAddress().toString());
+
+ long s1u_sgw_gtpu_teid, s1u_enb_gtpu_teid,
+ clientId = input.clientId().fpcIdentity().union().int64(),
+ contextId = context.contextId().fpcIdentity().union().int64();
+
+ BigInteger opId = input.opId().uint64(),
+ imsi = context.imsi().uint64();
+
+ short ebi = context.ebi().uint8(),
+ lbi = context.lbi().uint8();
+
+ Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.dpnId().fpcIdentity().union().string()));
+
+ if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ return;
+ }
+ if (context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ return;
+ }
+
+ if (input.opType().equals(OpTypeEnum.CREATE)) {
+ if (commands.contains("session")) {
+ DpnApi.create_session(
+ dpnTopic,
+ imsi,
+ Ip4Prefix.valueOf(context.delegatingIpPrefixes().get(0).toString()).address(),
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid,
+ clientId,
+ opId,
+ contextId
+ );
+
+
+ if (commands.contains("downlink")) {
+ DpnApi.modify_bearer_dl(
+ dpnTopic,
+ s1u_sgw_gtpu_teid,
+ dlRemoteAddress,
+ s1u_enb_gtpu_teid,
+ clientId,
+ opId
+ );
+ }
+ } else if (commands.contains("indirect-forward")) {
+ // TODO - Modify API for Indirect Forwarding to/from another SGW
+ } else if (commands.contains("uplink")) {
+ DpnApi.create_bearer_ul(
+ dpnTopic,
+ imsi,
+ lbi,
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid
+ );
+ }
+ } else {
+ if (commands.contains("downlink")) {
+ if (context.dl().lifetime() >= 0L) {
+ DpnApi.modify_bearer_dl(
+ dpnTopic,
+ dlRemoteAddress,
+ s1u_enb_gtpu_teid,
+ dlLocalAddress,
+ clientId,
+ opId,
+ contextId
+ );
+ } else {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_enb_gtpu_teid
+ );
+ }
+ }
+ if (commands.contains("uplink")) {
+ if (context.ul().lifetime() >= 0L) {
+ DpnApi.modify_bearer_ul(
+ dpnTopic,
+ ulLocalAddress,
+ s1u_enb_gtpu_teid,
+ s1u_sgw_gtpu_teid
+ );
+ } else {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_sgw_gtpu_teid
+ );
+ }
+ }
+ }
+ }
+ }
+ );
+ }
+ );
+ }
+ break;
+ case QUERY:
+ break;
+ case DELETE:
+ if (input.opBody() instanceof DeleteOrQuery) {
+ DeleteOrQuery deleteOrQuery = (DeleteOrQuery) input.opBody();
+
+ deleteOrQuery.targets().forEach(
+ target -> {
+ String targetStr = target.target().union().string();
+ sessionContextsMap.getOrDefault(targetStr, Lists.newArrayList()).parallelStream().forEach(
+ context -> context.dpns().forEach(
+ dpn -> {
+ Long teid;
+ if (context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel) {
+ teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier();
+ } else {
+ return;
+ }
+
+ Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.dpnId().fpcIdentity().union().string()));
+
+ if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ teid
+ );
+ } else {
+ DpnApi.delete_session(
+ dpnTopic,
+ context.lbi().uint8(),
+ teid,
+ input.clientId().fpcIdentity().union().int64(),
+ input.opId().uint64(),
+ context.contextId().fpcIdentity().union().int64()
+ );
+ }
+ }
+ )
+ );
+ }
+ );
+ }
+ break;
+ }
+
+ return null;
+ }
+
+ @Override
+ public RpcOutput configureBundles(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput eventRegister(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput eventDeregister(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput probe(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput registerClient(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public RpcOutput deregisterClient(RpcInput rpcInput) {
+ return null;
+ }
+
+ @Override
+ public void configure(org.onosproject.fpcagent.dto.configure.Configure configure) {
+ org.onosproject.fpcagent.dto.configure.ConfigureInput configureInput = configure.getConfigureInput();
+ if (configureInput.getOp_type().equals("create") || configureInput.getOp_type().equals("update")) {
+
+ configureInput.getContexts().forEach(
+ context -> {
+ String key = String.valueOf(context.getContext_id());
+ sessionContextsRestMap.computeIfAbsent(key, k -> new ArrayList<>()).add(context);
+ context.getDpns().forEach(dpn -> {
+ try {
+ String commands = context.getInstructions().getInstr_3gpp_mob();
+
+ Ip4Address ulLocalAddress = Ip4Address.valueOf(context.getUl().getTunnel_local_address()),
+ dlRemoteAddress = Ip4Address.valueOf(context.getDl().getTunnel_remote_address());
+
+ long s1u_sgw_gtpu_teid, s1u_enb_gtpu_teid,
+ clientId = Long.parseLong(configureInput.getClient_id()),
+ contextId = context.getContext_id();
+
+ BigInteger opId = BigInteger.valueOf(Long.parseLong(configureInput.getOp_id())),
+ imsi = BigInteger.valueOf(Long.parseLong(context.getImsi()));
+
+ short ebi = Short.parseShort(context.getEbi()),
+ lbi = Short.parseShort(context.getLbi());
+
+ Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.getDpn_id()));
+
+
+ s1u_sgw_gtpu_teid = Long.parseLong(context.getUl().getMobility_tunnel_parameters().getTunnel_identifier());
+ s1u_enb_gtpu_teid = Long.parseLong(context.getDl().getMobility_tunnel_parameters().getTunnel_identifier());
+
+ if (configureInput.getOp_type().equals("create")) {
+ if (commands.contains("session")) {
+ DpnApi.create_session(
+ dpnTopic,
+ imsi,
+ Ip4Prefix.valueOf(context.getDelegating_ip_prefixes().get(0)).address(),
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid,
+ clientId,
+ opId,
+ contextId
+ );
+
+
+ if (commands.contains("downlink")) {
+ DpnApi.modify_bearer_dl(
+ dpnTopic,
+ s1u_sgw_gtpu_teid,
+ dlRemoteAddress,
+ s1u_enb_gtpu_teid,
+ clientId,
+ opId
+ );
+ }
+ } else if (commands.contains("indirect-forward")) {
+ // TODO - Modify API for Indirect Forwarding to/from another SGW
+ } else if (commands.contains("uplink")) {
+ DpnApi.create_bearer_ul(
+ dpnTopic,
+ imsi,
+ lbi,
+ ebi,
+ ulLocalAddress,
+ s1u_sgw_gtpu_teid
+ );
+ }
+ } else {
+ if (commands.contains("downlink")) {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_enb_gtpu_teid
+ );
+ }
+ if (commands.contains("uplink")) {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ s1u_sgw_gtpu_teid
+ );
+ }
+ }
+ } catch (Exception e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ );
+ }
+ );
+
+ } else if (configureInput.getOp_type().equals("delete") || configureInput.getOp_type().equals("query")) {
+ configureInput.getTargets().forEach(
+ target -> {
+ String targetStr = target.getTarget();
+ String s = StringUtils.substringBetween(targetStr, "contexts/", "/");
+ if (s == null) {
+ s = StringUtils.substringAfter(targetStr, "contexts/");
+ }
+ sessionContextsRestMap.getOrDefault(s, Lists.newArrayList()).forEach(
+ context -> context.getDpns().forEach(
+ dpn -> {
+ Long teid = Long.valueOf(context.getUl().getMobility_tunnel_parameters().getTunnel_identifier());
+ Short dpnTopic = DpnApi.getTopicFromNode(nodeNetworkMap.get(dpn.getDpn_id()));
+
+ if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
+ DpnApi.delete_bearer(
+ dpnTopic,
+ teid
+ );
+ } else {
+ DpnApi.delete_session(
+ dpnTopic,
+ Short.valueOf(context.getLbi()),
+ teid,
+ Long.valueOf(configureInput.getClient_id()),
+ BigInteger.valueOf(Long.parseLong(configureInput.getOp_id())),
+ Long.valueOf(context.getContext_id())
+ );
+ }
+ }
+ )
+ );
+ }
+ );
+ }
+ }
+
+ @Override
+ public void registerClient(RegisterClientInput input) {
+ tenantService.registerClient(input.clientId(), input.tenantId());
+ }
+
+ @Override
+ public void deregisterClient(DeregisterClientInput input) {
+ tenantService.deregisterClient(input.clientId());
+ }
+
+ @Override
+ public void addDpn(AddDpn addDpn) {
+ addDpn.getDpns().forEach(
+ dpn -> {
+ try {
+ log.info("Addind DPN {}", dpn.getDpn_id());
+ nodeNetworkMap.put(dpn.getDpn_id(), dpn.getNode_id() + "/" + dpn.getNetwork_id());
+ } catch (Exception e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ );
+ }
+
+ @Override
+ public void deleteDpn(String dpn) {
+ log.info("Removing DPN {}", dpn);
+ nodeNetworkMap.remove(dpn);
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcService.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcService.java
new file mode 100644
index 0000000..9ff298a
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcService.java
@@ -0,0 +1,24 @@
+package org.onosproject.fpcagent;
+
+import org.onosproject.fpcagent.dto.configure.Configure;
+import org.onosproject.fpcagent.dto.dpn.AddDpn;
+import org.onosproject.fpcagent.helpers.ConfigHelper;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.deregisterclient.DeregisterClientInput;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.RegisterClientInput;
+
+import java.util.Optional;
+
+public interface FpcService {
+
+ Optional<ConfigHelper> getConfig();
+
+ void configure(Configure configure);
+
+ void registerClient(RegisterClientInput input);
+
+ void deregisterClient(DeregisterClientInput input);
+
+ void addDpn(AddDpn addDpn);
+
+ void deleteDpn(String dpn);
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
new file mode 100644
index 0000000..e51efed
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
@@ -0,0 +1,100 @@
+package org.onosproject.fpcagent;
+
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.payload.Contexts;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.DefaultTenant;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.Tenant;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcMobility;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcPolicy;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.DefaultFpcTopology;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.FpcTopology;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.tenant.fpctopology.Dpns;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnId;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.onosproject.fpcagent.helpers.Converter.getFpcIdentity;
+
+@Component(immediate = true)
+@Service
+public class TenantManager implements TenantService {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private Map<FpcIdentity, Tenant> tenantMap = Maps.newHashMap();
+ private Map<ClientIdentifier, Tenant> clientIdMap = Maps.newHashMap();
+
+ private Map<FpcDpnId, List<FpcDpnId>> vdpnDpnsMap = Maps.newConcurrentMap();
+ private Map<FpcDpnId, Contexts> vdpnContextsMap = Maps.newConcurrentMap();
+
+ @Activate
+ protected void activate() {
+ log.info("Tenant Service Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Tenant Service Stopped");
+ }
+
+ public void addTenant(FpcIdentity tenantId) {
+ Tenant tenant = new DefaultTenant();
+ tenant.tenantId(tenantId);
+ tenant.fpcTopology(new DefaultFpcTopology());
+ tenant.fpcMobility(new DefaultFpcMobility());
+ tenant.fpcPolicy(new DefaultFpcPolicy());
+
+ tenantMap.put(tenantId, tenant);
+ }
+
+ public Optional<Tenant> getTenant(FpcIdentity tenantId) {
+ return Optional.ofNullable(tenantMap.get(tenantId));
+ }
+
+ public Optional<Tenant> getTenant(ClientIdentifier clientId) {
+ return Optional.ofNullable(clientIdMap.get(clientId));
+ }
+
+ public Optional<Tenant> registerClient(ClientIdentifier clientId, FpcIdentity tenantId) {
+ return getTenant(tenantId).map(tenant -> clientIdMap.put(clientId, tenant));
+ }
+
+ public Tenant deregisterClient(ClientIdentifier clientId) {
+ return clientIdMap.remove(clientId);
+ }
+
+ private boolean dpnIdExists(FpcIdentity tenantId, FpcDpnId fpcDpnId) {
+ return getTenant(tenantId).map(
+ tenant -> {
+ FpcTopology fpcTopology = tenant.fpcTopology();
+ return fpcTopology.dpns() != null &&
+ fpcTopology.dpns().stream().anyMatch(dpn -> dpn.dpnId().equals(fpcDpnId));
+ }
+ ).orElse(false);
+ }
+
+ private Optional<FpcDpnId> getDpnId(String nodeId, String networkId) {
+ return getTenant(getFpcIdentity.apply("default")).map(
+ tenant -> {
+ FpcTopology fpcTopology = tenant.fpcTopology();
+ if (fpcTopology.dpns() != null) {
+ return fpcTopology.dpns().stream()
+ .filter(dpn -> dpn.nodeId().equals(nodeId))
+ .filter(dpn -> dpn.networkId().equals(networkId))
+ .findFirst()
+ .map(Dpns::dpnId);
+ }
+ return Optional.<FpcDpnId>empty();
+ }
+ ).orElse(Optional.empty());
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
new file mode 100644
index 0000000..f0f11a5
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
@@ -0,0 +1,19 @@
+package org.onosproject.fpcagent;
+
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.Tenant;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+
+import java.util.Optional;
+
+public interface TenantService {
+ void addTenant(FpcIdentity tenantId);
+
+ Optional<Tenant> getTenant(FpcIdentity tenantId);
+
+ Optional<Tenant> getTenant(ClientIdentifier clientId);
+
+ Optional<Tenant> registerClient(ClientIdentifier clientId, FpcIdentity tenantId);
+
+ Tenant deregisterClient(ClientIdentifier clientId);
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/client/BindClient.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/client/BindClient.java
new file mode 100755
index 0000000..5817772
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/client/BindClient.java
@@ -0,0 +1,128 @@
+
+package org.onosproject.fpcagent.dto.client;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.onosproject.fpcagent.dto.configure.ConfigureInput;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "client-id",
+ "tenant-id",
+ "supported-features",
+ "endpoint-uri"
+})
+public class BindClient {
+
+ @JsonProperty("client-id")
+ private String client_id;
+ @JsonProperty("tenant-id")
+ private String tenant_id;
+ @JsonProperty("supported-features")
+ private List<String> supported_features = null;
+ @JsonProperty("endpoint-uri")
+ private String endpoint_uri;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public BindClient() {
+ }
+
+ /**
+ *
+ * @param endpoint_uri
+ * @param supported_features
+ * @param tenant_id
+ * @param client_id
+ */
+ public BindClient(String client_id, String tenant_id, List<String> supported_features, String endpoint_uri) {
+ super();
+ this.client_id = client_id;
+ this.tenant_id = tenant_id;
+ this.supported_features = supported_features;
+ this.endpoint_uri = endpoint_uri;
+ }
+
+ @JsonProperty("client-id")
+ public String getClient_id() {
+ return client_id;
+ }
+
+ @JsonProperty("client-id")
+ public void setClient_id(String client_id) {
+ this.client_id = client_id;
+ }
+
+ @JsonProperty("tenant-id")
+ public String getTenant_id() {
+ return tenant_id;
+ }
+
+ @JsonProperty("tenant-id")
+ public void setTenant_id(String tenant_id) {
+ this.tenant_id = tenant_id;
+ }
+
+ @JsonProperty("supported-features")
+ public List<String> getSupported_features() {
+ return supported_features;
+ }
+
+ @JsonProperty("supported-features")
+ public void setSupported_features(List<String> supported_features) {
+ this.supported_features = supported_features;
+ }
+
+ @JsonProperty("endpoint-uri")
+ public String getEndpoint_uri() {
+ return endpoint_uri;
+ }
+
+ @JsonProperty("endpoint-uri")
+ public void setEndpoint_uri(String endpoint_uri) {
+ this.endpoint_uri = endpoint_uri;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("client_id", client_id).append("tenant_id", tenant_id).append("supported_features", supported_features).append("endpoint_uri", endpoint_uri).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).append(endpoint_uri).append(supported_features).append(tenant_id).append(client_id).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof ConfigureInput) == false) {
+ return false;
+ }
+ BindClient rhs = ((BindClient) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).append(endpoint_uri, rhs.endpoint_uri).append(supported_features, rhs.supported_features).append(tenant_id, rhs.tenant_id).append(client_id, rhs.client_id).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Configure.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Configure.java
new file mode 100755
index 0000000..b79600f
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Configure.java
@@ -0,0 +1,81 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "input"
+})
+public class Configure {
+
+ @JsonProperty("input")
+ private ConfigureInput configureInput;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Configure() {
+ }
+
+ /**
+ *
+ * @param configureInput
+ */
+ public Configure(ConfigureInput configureInput) {
+ super();
+ this.configureInput = configureInput;
+ }
+
+ @JsonProperty("input")
+ public ConfigureInput getConfigureInput() {
+ return configureInput;
+ }
+
+ @JsonProperty("input")
+ public void setConfigureInput(ConfigureInput configureInput) {
+ this.configureInput = configureInput;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("input", configureInput).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(configureInput).append(additionalProperties).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Configure) == false) {
+ return false;
+ }
+ Configure rhs = ((Configure) other);
+ return new EqualsBuilder().append(configureInput, rhs.configureInput).append(additionalProperties, rhs.additionalProperties).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/ConfigureInput.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/ConfigureInput.java
new file mode 100755
index 0000000..919052d
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/ConfigureInput.java
@@ -0,0 +1,162 @@
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "op-id",
+ "targets",
+ "contexts",
+ "client-id",
+ "session-state",
+ "admin-state",
+ "op-type",
+ "op-ref-scope"
+})
+public class ConfigureInput {
+
+ @JsonProperty("op-id")
+ private String op_id;
+ @JsonProperty("targets")
+ private List<Target> targets = null;
+ @JsonProperty("contexts")
+ private List<Context> contexts = null;
+ @JsonProperty("client-id")
+ private String client_id;
+ @JsonProperty("session-state")
+ private String session_state;
+ @JsonProperty("admin-state")
+ private String admin_state;
+ @JsonProperty("op-type")
+ private String op_type;
+ @JsonProperty("op-ref-scope")
+ private String op_ref_scope;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ */
+ public ConfigureInput() {
+ }
+
+ @JsonProperty("op-id")
+ public String getOp_id() {
+ return op_id;
+ }
+
+ @JsonProperty("op-id")
+ public void setOp_id(String op_id) {
+ this.op_id = op_id;
+ }
+
+ @JsonProperty("targets")
+ public List<Target> getTargets() {
+ return targets;
+ }
+
+ @JsonProperty("targets")
+ public void setTargets(List<Target> targets) {
+ this.targets = targets;
+ }
+
+ @JsonProperty("contexts")
+ public List<Context> getContexts() {
+ return contexts;
+ }
+
+ @JsonProperty("contexts")
+ public void setContexts(List<Context> contexts) {
+ this.contexts = contexts;
+ }
+
+ @JsonProperty("client-id")
+ public String getClient_id() {
+ return client_id;
+ }
+
+ @JsonProperty("client-id")
+ public void setClient_id(String client_id) {
+ this.client_id = client_id;
+ }
+
+ @JsonProperty("session-state")
+ public String getSession_state() {
+ return session_state;
+ }
+
+ @JsonProperty("session-state")
+ public void setSession_state(String session_state) {
+ this.session_state = session_state;
+ }
+
+ @JsonProperty("admin-state")
+ public String getAdmin_state() {
+ return admin_state;
+ }
+
+ @JsonProperty("admin-state")
+ public void setAdmin_state(String admin_state) {
+ this.admin_state = admin_state;
+ }
+
+ @JsonProperty("op-type")
+ public String getOp_type() {
+ return op_type;
+ }
+
+ @JsonProperty("op-type")
+ public void setOp_type(String op_type) {
+ this.op_type = op_type;
+ }
+
+ @JsonProperty("op-ref-scope")
+ public String getOp_ref_scope() {
+ return op_ref_scope;
+ }
+
+ @JsonProperty("op-ref-scope")
+ public void setOp_ref_scope(String op_ref_scope) {
+ this.op_ref_scope = op_ref_scope;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("op_id", op_id).append("targets", targets).append("contexts", contexts).append("client_id", client_id).append("session_state", session_state).append("admin_state", admin_state).append("op_type", op_type).append("op_ref_scope", op_ref_scope).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(session_state).append(op_id).append(additionalProperties).append(admin_state).append(op_type).append(op_ref_scope).append(contexts).append(client_id).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof ConfigureInput) == false) {
+ return false;
+ }
+ ConfigureInput rhs = ((ConfigureInput) other);
+ return new EqualsBuilder().append(session_state, rhs.session_state).append(op_id, rhs.op_id).append(additionalProperties, rhs.additionalProperties).append(admin_state, rhs.admin_state).append(op_type, rhs.op_type).append(op_ref_scope, rhs.op_ref_scope).append(contexts, rhs.contexts).append(client_id, rhs.client_id).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Context.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Context.java
new file mode 100755
index 0000000..2dfaafa
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Context.java
@@ -0,0 +1,217 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "instructions",
+ "context-id",
+ "dpn-group",
+ "delegating-ip-prefixes",
+ "ul",
+ "dl",
+ "dpns",
+ "imsi",
+ "ebi",
+ "lbi"
+})
+public class Context {
+
+ @JsonProperty("instructions")
+ private Instructions instructions;
+ @JsonProperty("context-id")
+ private Integer context_id;
+ @JsonProperty("dpn-group")
+ private String dpn_group;
+ @JsonProperty("delegating-ip-prefixes")
+ private List<String> delegating_ip_prefixes = null;
+ @JsonProperty("ul")
+ private Ul ul;
+ @JsonProperty("dl")
+ private Dl dl;
+ @JsonProperty("dpns")
+ private List<Dpn> dpns = null;
+ @JsonProperty("imsi")
+ private String imsi;
+ @JsonProperty("ebi")
+ private String ebi;
+ @JsonProperty("lbi")
+ private String lbi;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Context() {
+ }
+
+ /**
+ *
+ * @param lbi
+ * @param dpns
+ * @param ul
+ * @param dpn_group
+ * @param context_id
+ * @param instructions
+ * @param dl
+ * @param delegating_ip_prefixes
+ * @param imsi
+ * @param ebi
+ */
+ public Context(Instructions instructions, Integer context_id, String dpn_group, List<String> delegating_ip_prefixes, Ul ul, Dl dl, List<Dpn> dpns, String imsi, String ebi, String lbi) {
+ super();
+ this.instructions = instructions;
+ this.context_id = context_id;
+ this.dpn_group = dpn_group;
+ this.delegating_ip_prefixes = delegating_ip_prefixes;
+ this.ul = ul;
+ this.dl = dl;
+ this.dpns = dpns;
+ this.imsi = imsi;
+ this.ebi = ebi;
+ this.lbi = lbi;
+ }
+
+ @JsonProperty("instructions")
+ public Instructions getInstructions() {
+ return instructions;
+ }
+
+ @JsonProperty("instructions")
+ public void setInstructions(Instructions instructions) {
+ this.instructions = instructions;
+ }
+
+ @JsonProperty("context-id")
+ public Integer getContext_id() {
+ return context_id;
+ }
+
+ @JsonProperty("context-id")
+ public void setContext_id(Integer context_id) {
+ this.context_id = context_id;
+ }
+
+ @JsonProperty("dpn-group")
+ public String getDpn_group() {
+ return dpn_group;
+ }
+
+ @JsonProperty("dpn-group")
+ public void setDpn_group(String dpn_group) {
+ this.dpn_group = dpn_group;
+ }
+
+ @JsonProperty("delegating-ip-prefixes")
+ public List<String> getDelegating_ip_prefixes() {
+ return delegating_ip_prefixes;
+ }
+
+ @JsonProperty("delegating-ip-prefixes")
+ public void setDelegating_ip_prefixes(List<String> delegating_ip_prefixes) {
+ this.delegating_ip_prefixes = delegating_ip_prefixes;
+ }
+
+ @JsonProperty("ul")
+ public Ul getUl() {
+ return ul;
+ }
+
+ @JsonProperty("ul")
+ public void setUl(Ul ul) {
+ this.ul = ul;
+ }
+
+ @JsonProperty("dl")
+ public Dl getDl() {
+ return dl;
+ }
+
+ @JsonProperty("dl")
+ public void setDl(Dl dl) {
+ this.dl = dl;
+ }
+
+ @JsonProperty("dpns")
+ public List<Dpn> getDpns() {
+ return dpns;
+ }
+
+ @JsonProperty("dpns")
+ public void setDpns(List<Dpn> dpns) {
+ this.dpns = dpns;
+ }
+
+ @JsonProperty("imsi")
+ public String getImsi() {
+ return imsi;
+ }
+
+ @JsonProperty("imsi")
+ public void setImsi(String imsi) {
+ this.imsi = imsi;
+ }
+
+ @JsonProperty("ebi")
+ public String getEbi() {
+ return ebi;
+ }
+
+ @JsonProperty("ebi")
+ public void setEbi(String ebi) {
+ this.ebi = ebi;
+ }
+
+ @JsonProperty("lbi")
+ public String getLbi() {
+ return lbi;
+ }
+
+ @JsonProperty("lbi")
+ public void setLbi(String lbi) {
+ this.lbi = lbi;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("instructions", instructions).append("context_id", context_id).append("dpn_group", dpn_group).append("delegating_ip_prefixes", delegating_ip_prefixes).append("ul", ul).append("dl", dl).append("dpns", dpns).append("imsi", imsi).append("ebi", ebi).append("lbi", lbi).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(lbi).append(dpns).append(ul).append(dpn_group).append(context_id).append(instructions).append(additionalProperties).append(dl).append(delegating_ip_prefixes).append(imsi).append(ebi).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Context) == false) {
+ return false;
+ }
+ Context rhs = ((Context) other);
+ return new EqualsBuilder().append(lbi, rhs.lbi).append(dpns, rhs.dpns).append(ul, rhs.ul).append(dpn_group, rhs.dpn_group).append(context_id, rhs.context_id).append(instructions, rhs.instructions).append(additionalProperties, rhs.additionalProperties).append(dl, rhs.dl).append(delegating_ip_prefixes, rhs.delegating_ip_prefixes).append(imsi, rhs.imsi).append(ebi, rhs.ebi).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dl.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dl.java
new file mode 100755
index 0000000..f372a5b
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dl.java
@@ -0,0 +1,130 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "tunnel-local-address",
+ "tunnel-remote-address",
+ "mobility-tunnel-parameters",
+ "dpn-parameters"
+})
+public class Dl {
+
+ @JsonProperty("tunnel-local-address")
+ private String tunnel_local_address;
+ @JsonProperty("tunnel-remote-address")
+ private String tunnel_remote_address;
+ @JsonProperty("mobility-tunnel-parameters")
+ private Mobility_tunnel_parameters_ mobility_tunnel_parameters;
+ @JsonProperty("dpn-parameters")
+ private Dpn_parameters_ dpn_parameters;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Dl() {
+ }
+
+ /**
+ *
+ * @param tunnel_remote_address
+ * @param dpn_parameters
+ * @param tunnel_local_address
+ * @param mobility_tunnel_parameters
+ */
+ public Dl(String tunnel_local_address, String tunnel_remote_address, Mobility_tunnel_parameters_ mobility_tunnel_parameters, Dpn_parameters_ dpn_parameters) {
+ super();
+ this.tunnel_local_address = tunnel_local_address;
+ this.tunnel_remote_address = tunnel_remote_address;
+ this.mobility_tunnel_parameters = mobility_tunnel_parameters;
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonProperty("tunnel-local-address")
+ public String getTunnel_local_address() {
+ return tunnel_local_address;
+ }
+
+ @JsonProperty("tunnel-local-address")
+ public void setTunnel_local_address(String tunnel_local_address) {
+ this.tunnel_local_address = tunnel_local_address;
+ }
+
+ @JsonProperty("tunnel-remote-address")
+ public String getTunnel_remote_address() {
+ return tunnel_remote_address;
+ }
+
+ @JsonProperty("tunnel-remote-address")
+ public void setTunnel_remote_address(String tunnel_remote_address) {
+ this.tunnel_remote_address = tunnel_remote_address;
+ }
+
+ @JsonProperty("mobility-tunnel-parameters")
+ public Mobility_tunnel_parameters_ getMobility_tunnel_parameters() {
+ return mobility_tunnel_parameters;
+ }
+
+ @JsonProperty("mobility-tunnel-parameters")
+ public void setMobility_tunnel_parameters(Mobility_tunnel_parameters_ mobility_tunnel_parameters) {
+ this.mobility_tunnel_parameters = mobility_tunnel_parameters;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public Dpn_parameters_ getDpn_parameters() {
+ return dpn_parameters;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public void setDpn_parameters(Dpn_parameters_ dpn_parameters) {
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("tunnel_local_address", tunnel_local_address).append("tunnel_remote_address", tunnel_remote_address).append("mobility_tunnel_parameters", mobility_tunnel_parameters).append("dpn_parameters", dpn_parameters).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(tunnel_remote_address).append(dpn_parameters).append(additionalProperties).append(tunnel_local_address).append(mobility_tunnel_parameters).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dl) == false) {
+ return false;
+ }
+ Dl rhs = ((Dl) other);
+ return new EqualsBuilder().append(tunnel_remote_address, rhs.tunnel_remote_address).append(dpn_parameters, rhs.dpn_parameters).append(additionalProperties, rhs.additionalProperties).append(tunnel_local_address, rhs.tunnel_local_address).append(mobility_tunnel_parameters, rhs.mobility_tunnel_parameters).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn.java
new file mode 100755
index 0000000..795da24
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn.java
@@ -0,0 +1,111 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "dpn-id",
+ "direction",
+ "dpn-parameters"
+})
+public class Dpn {
+
+ @JsonProperty("dpn-id")
+ private String dpn_id;
+ @JsonProperty("direction")
+ private String direction;
+ @JsonProperty("dpn-parameters")
+ private Dpn_parameters__ dpn_parameters;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Dpn() {
+ }
+
+ /**
+ *
+ * @param dpn_parameters
+ * @param direction
+ * @param dpn_id
+ */
+ public Dpn(String dpn_id, String direction, Dpn_parameters__ dpn_parameters) {
+ super();
+ this.dpn_id = dpn_id;
+ this.direction = direction;
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonProperty("dpn-id")
+ public String getDpn_id() {
+ return dpn_id;
+ }
+
+ @JsonProperty("dpn-id")
+ public void setDpn_id(String dpn_id) {
+ this.dpn_id = dpn_id;
+ }
+
+ @JsonProperty("direction")
+ public String getDirection() {
+ return direction;
+ }
+
+ @JsonProperty("direction")
+ public void setDirection(String direction) {
+ this.direction = direction;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public Dpn_parameters__ getDpn_parameters() {
+ return dpn_parameters;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public void setDpn_parameters(Dpn_parameters__ dpn_parameters) {
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("dpn_id", dpn_id).append("direction", direction).append("dpn_parameters", dpn_parameters).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(dpn_parameters).append(additionalProperties).append(direction).append(dpn_id).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dpn) == false) {
+ return false;
+ }
+ Dpn rhs = ((Dpn) other);
+ return new EqualsBuilder().append(dpn_parameters, rhs.dpn_parameters).append(additionalProperties, rhs.additionalProperties).append(direction, rhs.direction).append(dpn_id, rhs.dpn_id).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters.java
new file mode 100755
index 0000000..e8fea8d
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters.java
@@ -0,0 +1,56 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+
+})
+public class Dpn_parameters {
+
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dpn_parameters) == false) {
+ return false;
+ }
+ Dpn_parameters rhs = ((Dpn_parameters) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters_.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters_.java
new file mode 100755
index 0000000..0e00c6f
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters_.java
@@ -0,0 +1,56 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+
+})
+public class Dpn_parameters_ {
+
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dpn_parameters_) == false) {
+ return false;
+ }
+ Dpn_parameters_ rhs = ((Dpn_parameters_) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters__.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters__.java
new file mode 100755
index 0000000..009e5e8
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Dpn_parameters__.java
@@ -0,0 +1,53 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+
+})
+public class Dpn_parameters__ {
+
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dpn_parameters__) == false) {
+ return false;
+ }
+ Dpn_parameters__ rhs = ((Dpn_parameters__) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Instructions.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Instructions.java
new file mode 100755
index 0000000..043755d
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Instructions.java
@@ -0,0 +1,85 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "instr-3gpp-mob"
+})
+public class Instructions {
+
+ @JsonProperty("instr-3gpp-mob")
+ private String instr_3gpp_mob;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Instructions() {
+ }
+
+ /**
+ *
+ * @param instr_3gpp_mob
+ */
+ public Instructions(String instr_3gpp_mob) {
+ super();
+ this.instr_3gpp_mob = instr_3gpp_mob;
+ }
+
+ @JsonProperty("instr-3gpp-mob")
+ public String getInstr_3gpp_mob() {
+ return instr_3gpp_mob;
+ }
+
+ @JsonProperty("instr-3gpp-mob")
+ public void setInstr_3gpp_mob(String instr_3gpp_mob) {
+ this.instr_3gpp_mob = instr_3gpp_mob;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("instr_3gpp_mob", instr_3gpp_mob).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).append(instr_3gpp_mob).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Instructions) == false) {
+ return false;
+ }
+ Instructions rhs = ((Instructions) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).append(instr_3gpp_mob, rhs.instr_3gpp_mob).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters.java
new file mode 100755
index 0000000..d58f547
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters.java
@@ -0,0 +1,96 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "tunnel-type",
+ "tunnel-identifier"
+})
+public class Mobility_tunnel_parameters {
+
+ @JsonProperty("tunnel-type")
+ private String tunnel_type;
+ @JsonProperty("tunnel-identifier")
+ private String tunnel_identifier;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Mobility_tunnel_parameters() {
+ }
+
+ /**
+ *
+ * @param tunnel_type
+ * @param tunnel_identifier
+ */
+ public Mobility_tunnel_parameters(String tunnel_type, String tunnel_identifier) {
+ super();
+ this.tunnel_type = tunnel_type;
+ this.tunnel_identifier = tunnel_identifier;
+ }
+
+ @JsonProperty("tunnel-type")
+ public String getTunnel_type() {
+ return tunnel_type;
+ }
+
+ @JsonProperty("tunnel-type")
+ public void setTunnel_type(String tunnel_type) {
+ this.tunnel_type = tunnel_type;
+ }
+
+ @JsonProperty("tunnel-identifier")
+ public String getTunnel_identifier() {
+ return tunnel_identifier;
+ }
+
+ @JsonProperty("tunnel-identifier")
+ public void setTunnel_identifier(String tunnel_identifier) {
+ this.tunnel_identifier = tunnel_identifier;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("tunnel_type", tunnel_type).append("tunnel_identifier", tunnel_identifier).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).append(tunnel_type).append(tunnel_identifier).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Mobility_tunnel_parameters) == false) {
+ return false;
+ }
+ Mobility_tunnel_parameters rhs = ((Mobility_tunnel_parameters) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).append(tunnel_type, rhs.tunnel_type).append(tunnel_identifier, rhs.tunnel_identifier).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters_.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters_.java
new file mode 100755
index 0000000..deb615c
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Mobility_tunnel_parameters_.java
@@ -0,0 +1,100 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "tunnel-type",
+ "tunnel-identifier"
+})
+public class Mobility_tunnel_parameters_ {
+
+ @JsonProperty("tunnel-type")
+ private String tunnel_type;
+ @JsonProperty("tunnel-identifier")
+ private String tunnel_identifier;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Mobility_tunnel_parameters_() {
+ }
+
+ /**
+ *
+ * @param tunnel_type
+ * @param tunnel_identifier
+ */
+ public Mobility_tunnel_parameters_(String tunnel_type, String tunnel_identifier) {
+ super();
+ this.tunnel_type = tunnel_type;
+ this.tunnel_identifier = tunnel_identifier;
+ }
+
+ @JsonProperty("tunnel-type")
+ public String getTunnel_type() {
+ return tunnel_type;
+ }
+
+ @JsonProperty("tunnel-type")
+ public void setTunnel_type(String tunnel_type) {
+ this.tunnel_type = tunnel_type;
+ }
+
+ @JsonProperty("tunnel-identifier")
+ public String getTunnel_identifier() {
+ return tunnel_identifier;
+ }
+
+ @JsonProperty("tunnel-identifier")
+ public void setTunnel_identifier(String tunnel_identifier) {
+ this.tunnel_identifier = tunnel_identifier;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("tunnel_type", tunnel_type).append("tunnel_identifier", tunnel_identifier).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).append(tunnel_type).append(tunnel_identifier).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Mobility_tunnel_parameters_) == false) {
+ return false;
+ }
+ Mobility_tunnel_parameters_ rhs = ((Mobility_tunnel_parameters_) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).append(tunnel_type, rhs.tunnel_type).append(tunnel_identifier, rhs.tunnel_identifier).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Target.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Target.java
new file mode 100755
index 0000000..db67e91
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Target.java
@@ -0,0 +1,81 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "target"
+})
+public class Target {
+
+ @JsonProperty("target")
+ private String target;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Target() {
+ }
+
+ /**
+ *
+ * @param target
+ */
+ public Target(String target) {
+ super();
+ this.target = target;
+ }
+
+ @JsonProperty("target")
+ public String getTarget() {
+ return target;
+ }
+
+ @JsonProperty("target")
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("target", target).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(additionalProperties).append(target).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Target) == false) {
+ return false;
+ }
+ Target rhs = ((Target) other);
+ return new EqualsBuilder().append(additionalProperties, rhs.additionalProperties).append(target, rhs.target).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Ul.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Ul.java
new file mode 100755
index 0000000..8f2090e
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/configure/Ul.java
@@ -0,0 +1,130 @@
+
+package org.onosproject.fpcagent.dto.configure;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "tunnel-local-address",
+ "tunnel-remote-address",
+ "mobility-tunnel-parameters",
+ "dpn-parameters"
+})
+public class Ul {
+
+ @JsonProperty("tunnel-local-address")
+ private String tunnel_local_address;
+ @JsonProperty("tunnel-remote-address")
+ private String tunnel_remote_address;
+ @JsonProperty("mobility-tunnel-parameters")
+ private Mobility_tunnel_parameters mobility_tunnel_parameters;
+ @JsonProperty("dpn-parameters")
+ private Dpn_parameters dpn_parameters;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Ul() {
+ }
+
+ /**
+ *
+ * @param tunnel_remote_address
+ * @param dpn_parameters
+ * @param tunnel_local_address
+ * @param mobility_tunnel_parameters
+ */
+ public Ul(String tunnel_local_address, String tunnel_remote_address, Mobility_tunnel_parameters mobility_tunnel_parameters, Dpn_parameters dpn_parameters) {
+ super();
+ this.tunnel_local_address = tunnel_local_address;
+ this.tunnel_remote_address = tunnel_remote_address;
+ this.mobility_tunnel_parameters = mobility_tunnel_parameters;
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonProperty("tunnel-local-address")
+ public String getTunnel_local_address() {
+ return tunnel_local_address;
+ }
+
+ @JsonProperty("tunnel-local-address")
+ public void setTunnel_local_address(String tunnel_local_address) {
+ this.tunnel_local_address = tunnel_local_address;
+ }
+
+ @JsonProperty("tunnel-remote-address")
+ public String getTunnel_remote_address() {
+ return tunnel_remote_address;
+ }
+
+ @JsonProperty("tunnel-remote-address")
+ public void setTunnel_remote_address(String tunnel_remote_address) {
+ this.tunnel_remote_address = tunnel_remote_address;
+ }
+
+ @JsonProperty("mobility-tunnel-parameters")
+ public Mobility_tunnel_parameters getMobility_tunnel_parameters() {
+ return mobility_tunnel_parameters;
+ }
+
+ @JsonProperty("mobility-tunnel-parameters")
+ public void setMobility_tunnel_parameters(Mobility_tunnel_parameters mobility_tunnel_parameters) {
+ this.mobility_tunnel_parameters = mobility_tunnel_parameters;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public Dpn_parameters getDpn_parameters() {
+ return dpn_parameters;
+ }
+
+ @JsonProperty("dpn-parameters")
+ public void setDpn_parameters(Dpn_parameters dpn_parameters) {
+ this.dpn_parameters = dpn_parameters;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("tunnel_local_address", tunnel_local_address).append("tunnel_remote_address", tunnel_remote_address).append("mobility_tunnel_parameters", mobility_tunnel_parameters).append("dpn_parameters", dpn_parameters).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(tunnel_remote_address).append(dpn_parameters).append(additionalProperties).append(tunnel_local_address).append(mobility_tunnel_parameters).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Ul) == false) {
+ return false;
+ }
+ Ul rhs = ((Ul) other);
+ return new EqualsBuilder().append(tunnel_remote_address, rhs.tunnel_remote_address).append(dpn_parameters, rhs.dpn_parameters).append(additionalProperties, rhs.additionalProperties).append(tunnel_local_address, rhs.tunnel_local_address).append(mobility_tunnel_parameters, rhs.mobility_tunnel_parameters).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/AddDpn.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/AddDpn.java
new file mode 100755
index 0000000..3c166ad
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/AddDpn.java
@@ -0,0 +1,82 @@
+
+package org.onosproject.fpcagent.dto.dpn;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "dpns"
+})
+public class AddDpn {
+
+ @JsonProperty("dpns")
+ private List<Dpn> dpns = null;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public AddDpn() {
+ }
+
+ /**
+ *
+ * @param dpns
+ */
+ public AddDpn(List<Dpn> dpns) {
+ super();
+ this.dpns = dpns;
+ }
+
+ @JsonProperty("dpns")
+ public List<Dpn> getDpns() {
+ return dpns;
+ }
+
+ @JsonProperty("dpns")
+ public void setDpns(List<Dpn> dpns) {
+ this.dpns = dpns;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("dpns", dpns).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(dpns).append(additionalProperties).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof AddDpn) == false) {
+ return false;
+ }
+ AddDpn rhs = ((AddDpn) other);
+ return new EqualsBuilder().append(dpns, rhs.dpns).append(additionalProperties, rhs.additionalProperties).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/Dpn.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/Dpn.java
new file mode 100755
index 0000000..f71df67
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/dto/dpn/Dpn.java
@@ -0,0 +1,142 @@
+
+package org.onosproject.fpcagent.dto.dpn;
+
+import com.fasterxml.jackson.annotation.*;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "dpn-id",
+ "dpn-name",
+ "dpn-groups",
+ "node-id",
+ "network-id"
+})
+public class Dpn {
+
+ @JsonProperty("dpn-id")
+ private String dpn_id;
+ @JsonProperty("dpn-name")
+ private String dpn_name;
+ @JsonProperty("dpn-groups")
+ private List<String> dpn_groups = null;
+ @JsonProperty("node-id")
+ private String node_id;
+ @JsonProperty("network-id")
+ private String network_id;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ /**
+ * No args constructor for use in serialization
+ *
+ */
+ public Dpn() {
+ }
+
+ /**
+ *
+ * @param dpn_name
+ * @param network_id
+ * @param dpn_groups
+ * @param dpn_id
+ * @param node_id
+ */
+ public Dpn(String dpn_id, String dpn_name, List<String> dpn_groups, String node_id, String network_id) {
+ super();
+ this.dpn_id = dpn_id;
+ this.dpn_name = dpn_name;
+ this.dpn_groups = dpn_groups;
+ this.node_id = node_id;
+ this.network_id = network_id;
+ }
+
+ @JsonProperty("dpn-id")
+ public String getDpn_id() {
+ return dpn_id;
+ }
+
+ @JsonProperty("dpn-id")
+ public void setDpn_id(String dpn_id) {
+ this.dpn_id = dpn_id;
+ }
+
+ @JsonProperty("dpn-name")
+ public String getDpn_name() {
+ return dpn_name;
+ }
+
+ @JsonProperty("dpn-name")
+ public void setDpn_name(String dpn_name) {
+ this.dpn_name = dpn_name;
+ }
+
+ @JsonProperty("dpn-groups")
+ public List<String> getDpn_groups() {
+ return dpn_groups;
+ }
+
+ @JsonProperty("dpn-groups")
+ public void setDpn_groups(List<String> dpn_groups) {
+ this.dpn_groups = dpn_groups;
+ }
+
+ @JsonProperty("node-id")
+ public String getNode_id() {
+ return node_id;
+ }
+
+ @JsonProperty("node-id")
+ public void setNode_id(String node_id) {
+ this.node_id = node_id;
+ }
+
+ @JsonProperty("network-id")
+ public String getNetwork_id() {
+ return network_id;
+ }
+
+ @JsonProperty("network-id")
+ public void setNetwork_id(String network_id) {
+ this.network_id = network_id;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("dpn_id", dpn_id).append("dpn_name", dpn_name).append("dpn_groups", dpn_groups).append("node_id", node_id).append("network_id", network_id).append("additionalProperties", additionalProperties).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(dpn_name).append(network_id).append(dpn_groups).append(additionalProperties).append(dpn_id).append(node_id).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if ((other instanceof Dpn) == false) {
+ return false;
+ }
+ Dpn rhs = ((Dpn) other);
+ return new EqualsBuilder().append(dpn_name, rhs.dpn_name).append(network_id, rhs.network_id).append(dpn_groups, rhs.dpn_groups).append(additionalProperties, rhs.additionalProperties).append(dpn_id, rhs.dpn_id).append(node_id, rhs.node_id).isEquals();
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/ConfigHelper.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/ConfigHelper.java
new file mode 100644
index 0000000..bee7cce
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/ConfigHelper.java
@@ -0,0 +1,318 @@
+package org.onosproject.fpcagent.helpers;
+
+import com.fasterxml.jackson.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "monitor-threads",
+ "scheduled-monitors-poolsize",
+ "dpn-listener-uri",
+ "dpn-listener-id",
+ "dpn-client-uri",
+ "dpn-client-threads",
+ "metricsupdate-ms",
+ "mobilityupdate-ms",
+ "activation-threads",
+ "target-read-limit",
+ "http-notifier-clients",
+ "zmq-nbi-server-poolsize",
+ "zmq-nbi-server-uri",
+ "zmq-nbi-inproc-uri",
+ "zmq-nbi-handler-poolsize",
+ "http-nio2-nb-poolsize",
+ "http-nio2-nb-port",
+ "node-id",
+ "network-id",
+ "zmq-broadcast-controllers",
+ "zmq-broadcast-dpns",
+ "zmq-broadcast-all"
+})
+public class ConfigHelper {
+
+ @JsonProperty("monitor-threads")
+ private Integer monitorThreads;
+ @JsonProperty("scheduled-monitors-poolsize")
+ private Integer scheduledMonitorsPoolsize;
+ @JsonProperty("dpn-listener-uri")
+ private String dpnListenerUri;
+ @JsonProperty("dpn-listener-id")
+ private Integer dpnListenerId;
+ @JsonProperty("dpn-client-uri")
+ private String dpnClientUri;
+ @JsonProperty("dpn-client-threads")
+ private Integer dpnClientThreads;
+ @JsonProperty("metricsupdate-ms")
+ private Integer metricsupdateMs;
+ @JsonProperty("mobilityupdate-ms")
+ private Integer mobilityupdateMs;
+ @JsonProperty("activation-threads")
+ private Integer activationThreads;
+ @JsonProperty("target-read-limit")
+ private Integer targetReadLimit;
+ @JsonProperty("http-notifier-clients")
+ private Integer httpNotifierClients;
+ @JsonProperty("zmq-nbi-server-poolsize")
+ private Integer zmqNbiServerPoolsize;
+ @JsonProperty("zmq-nbi-server-uri")
+ private String zmqNbiServerUri;
+ @JsonProperty("zmq-nbi-inproc-uri")
+ private String zmqNbiInprocUri;
+ @JsonProperty("zmq-nbi-handler-poolsize")
+ private Integer zmqNbiHandlerPoolsize;
+ @JsonProperty("http-nio2-nb-poolsize")
+ private Integer httpNio2NbPoolsize;
+ @JsonProperty("http-nio2-nb-port")
+ private Integer httpNio2NbPort;
+ @JsonProperty("node-id")
+ private String nodeId;
+ @JsonProperty("network-id")
+ private String networkId;
+ @JsonProperty("zmq-broadcast-controllers")
+ private String zmqBroadcastControllers;
+ @JsonProperty("zmq-broadcast-dpns")
+ private String zmqBroadcastDpns;
+ @JsonProperty("zmq-broadcast-all")
+ private String zmqBroadcastAll;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<>();
+
+ /**
+ * No args constructor for use in serialization
+ */
+ public ConfigHelper() {
+ }
+
+ @JsonProperty("monitor-threads")
+ public Integer monitorThreads() {
+ return monitorThreads;
+ }
+
+ @JsonProperty("monitor-threads")
+ public void setMonitorThreads(Integer monitorThreads) {
+ this.monitorThreads = monitorThreads;
+ }
+
+ @JsonProperty("scheduled-monitors-poolsize")
+ public Integer scheduledMonitorsPoolsize() {
+ return scheduledMonitorsPoolsize;
+ }
+
+ @JsonProperty("scheduled-monitors-poolsize")
+ public void setScheduledMonitorsPoolsize(Integer scheduledMonitorsPoolsize) {
+ this.scheduledMonitorsPoolsize = scheduledMonitorsPoolsize;
+ }
+
+ @JsonProperty("dpn-listener-uri")
+ public String dpnListenerUri() {
+ return dpnListenerUri;
+ }
+
+ @JsonProperty("dpn-listener-uri")
+ public void setDpnListenerUri(String dpnListenerUri) {
+ this.dpnListenerUri = dpnListenerUri;
+ }
+
+ @JsonProperty("dpn-listener-id")
+ public Integer dpnListenerId() {
+ return dpnListenerId;
+ }
+
+ @JsonProperty("dpn-listener-id")
+ public void setDpnListenerId(Integer dpnListenerId) {
+ this.dpnListenerId = dpnListenerId;
+ }
+
+ @JsonProperty("dpn-client-uri")
+ public String dpnClientUri() {
+ return dpnClientUri;
+ }
+
+ @JsonProperty("dpn-client-uri")
+ public void setDpnClientUri(String dpnClientUri) {
+ this.dpnClientUri = dpnClientUri;
+ }
+
+ @JsonProperty("dpn-client-threads")
+ public Integer dpnClientThreads() {
+ return dpnClientThreads;
+ }
+
+ @JsonProperty("dpn-client-threads")
+ public void setDpnClientThreads(Integer dpnClientThreads) {
+ this.dpnClientThreads = dpnClientThreads;
+ }
+
+ @JsonProperty("metricsupdate-ms")
+ public Integer metricUpdateMs() {
+ return metricsupdateMs;
+ }
+
+ @JsonProperty("metricsupdate-ms")
+ public void setMetricsupdateMs(Integer metricsupdateMs) {
+ this.metricsupdateMs = metricsupdateMs;
+ }
+
+ @JsonProperty("mobilityupdate-ms")
+ public Integer mobilityUpdateMs() {
+ return mobilityupdateMs;
+ }
+
+ @JsonProperty("mobilityupdate-ms")
+ public void setMobilityupdateMs(Integer mobilityupdateMs) {
+ this.mobilityupdateMs = mobilityupdateMs;
+ }
+
+ @JsonProperty("activation-threads")
+ public Integer activationThreads() {
+ return activationThreads;
+ }
+
+ @JsonProperty("activation-threads")
+ public void setActivationThreads(Integer activationThreads) {
+ this.activationThreads = activationThreads;
+ }
+
+ @JsonProperty("target-read-limit")
+ public Integer targetReadLimit() {
+ return targetReadLimit;
+ }
+
+ @JsonProperty("target-read-limit")
+ public void setTargetReadLimit(Integer targetReadLimit) {
+ this.targetReadLimit = targetReadLimit;
+ }
+
+ @JsonProperty("http-notifier-clients")
+ public Integer httpNotifierClients() {
+ return httpNotifierClients;
+ }
+
+ @JsonProperty("http-notifier-clients")
+ public void setHttpNotifierClients(Integer httpNotifierClients) {
+ this.httpNotifierClients = httpNotifierClients;
+ }
+
+ @JsonProperty("zmq-nbi-server-poolsize")
+ public Integer zmqServerPoolsize() {
+ return zmqNbiServerPoolsize;
+ }
+
+ @JsonProperty("zmq-nbi-server-poolsize")
+ public void setZmqNbiServerPoolsize(Integer zmqNbiServerPoolsize) {
+ this.zmqNbiServerPoolsize = zmqNbiServerPoolsize;
+ }
+
+ @JsonProperty("zmq-nbi-server-uri")
+ public String zmqServerUri() {
+ return zmqNbiServerUri;
+ }
+
+ @JsonProperty("zmq-nbi-server-uri")
+ public void setZmqNbiServerUri(String zmqNbiServerUri) {
+ this.zmqNbiServerUri = zmqNbiServerUri;
+ }
+
+ @JsonProperty("zmq-nbi-inproc-uri")
+ public String zmqInprocUri() {
+ return zmqNbiInprocUri;
+ }
+
+ @JsonProperty("zmq-nbi-inproc-uri")
+ public void setZmqNbiInprocUri(String zmqNbiInprocUri) {
+ this.zmqNbiInprocUri = zmqNbiInprocUri;
+ }
+
+ @JsonProperty("zmq-nbi-handler-poolsize")
+ public Integer zmqHandlerPoolsize() {
+ return zmqNbiHandlerPoolsize;
+ }
+
+ @JsonProperty("zmq-nbi-handler-poolsize")
+ public void setZmqNbiHandlerPoolsize(Integer zmqNbiHandlerPoolsize) {
+ this.zmqNbiHandlerPoolsize = zmqNbiHandlerPoolsize;
+ }
+
+ @JsonProperty("http-nio2-nb-poolsize")
+ public Integer httpNio2Poolsize() {
+ return httpNio2NbPoolsize;
+ }
+
+ @JsonProperty("http-nio2-nb-poolsize")
+ public void setHttpNio2NbPoolsize(Integer httpNio2NbPoolsize) {
+ this.httpNio2NbPoolsize = httpNio2NbPoolsize;
+ }
+
+ @JsonProperty("http-nio2-nb-port")
+ public Integer httpNio2Port() {
+ return httpNio2NbPort;
+ }
+
+ @JsonProperty("http-nio2-nb-port")
+ public void setHttpNio2NbPort(Integer httpNio2NbPort) {
+ this.httpNio2NbPort = httpNio2NbPort;
+ }
+
+ @JsonProperty("node-id")
+ public String nodeId() {
+ return nodeId;
+ }
+
+ @JsonProperty("node-id")
+ public void setNodeId(String node_id) {
+ this.nodeId = node_id;
+ }
+
+ @JsonProperty("network-id")
+ public String networkId() {
+ return networkId;
+ }
+
+ @JsonProperty("network-id")
+ public void setNetworkId(String network_id) {
+ this.networkId = network_id;
+ }
+
+ @JsonProperty("zmq-broadcast-controllers")
+ public String zmqBroadcastControllers() {
+ return zmqBroadcastControllers;
+ }
+
+ @JsonProperty("zmq-broadcast-controllers")
+ public void setZmqBroadcastControllers(String zmqBroadcastControllers) {
+ this.zmqBroadcastControllers = zmqBroadcastControllers;
+ }
+
+ @JsonProperty("zmq-broadcast-dpns")
+ public String zmqBroadcastDpns() {
+ return zmqBroadcastDpns;
+ }
+
+ @JsonProperty("zmq-broadcast-dpns")
+ public void setZmqBroadcastDpns(String zmqBroadcastDpns) {
+ this.zmqBroadcastDpns = zmqBroadcastDpns;
+ }
+
+ @JsonProperty("zmq-broadcast-all")
+ public String zmqBroadcastAll() {
+ return zmqBroadcastAll;
+ }
+
+ @JsonProperty("zmq-broadcast-all")
+ public void setZmqBroadcastAll(String zmqBroadcastAll) {
+ this.zmqBroadcastAll = zmqBroadcastAll;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java
new file mode 100644
index 0000000..6573ae8
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/Converter.java
@@ -0,0 +1,104 @@
+package org.onosproject.fpcagent.helpers;
+
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpcidentity.FpcIdentityUnion;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.function.Function;
+
+public class Converter {
+ /**
+ * Short to Byte
+ *
+ * @param value - Short
+ * @return byte value
+ */
+ public static byte toUint8(Short value) {
+ return value.byteValue();
+ }
+
+ /**
+ * Short to byte array
+ *
+ * @param value - Short
+ * @return byte array
+ */
+ public static byte[] toUint16(Short value) {
+ return new byte[]{(byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * Lower two bytes of an integer to byte array
+ *
+ * @param value - integer value
+ * @return byte array
+ */
+ public static byte[] toUint16(Integer value) {
+ return new byte[]{(byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * Long to byte array.
+ *
+ * @param value - long
+ * @return byte array
+ */
+ public static byte[] toUint32(long value) {
+ return new byte[]{(byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value & 0xFF)};
+ }
+
+ /**
+ * BigInteger to byte array.
+ *
+ * @param value - BigInteger
+ * @return byte array
+ */
+ public static byte[] toUint64(BigInteger value) {
+ return new byte[]{value.shiftRight(56).byteValue(), value.shiftRight(48).byteValue(), value.shiftRight(40).byteValue(),
+ value.shiftRight(32).byteValue(), value.shiftRight(24).byteValue(), value.shiftRight(16).byteValue(),
+ value.shiftRight(8).byteValue(), value.and(BigInteger.valueOf(0xFF)).byteValue()};
+ }
+
+ /**
+ * Decodes a 32 bit value
+ *
+ * @param source - byte array
+ * @param offset - offset in the array where the 8 bytes begins
+ * @return integer
+ */
+ public static int toInt(byte[] source, int offset) {
+ return new BigInteger(Arrays.copyOfRange(source, offset, offset + 4)).intValue();
+ }
+
+ /**
+ * Converts a byte array to BigInteger
+ *
+ * @param source - byte array
+ * @param offset - offset in the array where the 8 bytes begins
+ * @return BigInteger representing a Uint64
+ */
+ public static BigInteger toBigInt(byte[] source, int offset) {
+ return new BigInteger(Arrays.copyOfRange(source, offset, offset + 8));
+ }
+
+ /**
+ * Converts an integer to a long (used for larger unsigned integers)
+ *
+ * @param source - message buffer (byte array)
+ * @param offset - offset in the array where the 4 bytes begins
+ * @return Long value of the unsigned integer
+ */
+ public static long fromIntToLong(byte[] source, int offset) {
+ long value = 0;
+ for (int i = offset; i < offset + 4; i++) {
+ value = (value << 8) + (source[i] & 0xff);
+ }
+ return value;
+ }
+
+ public static Function<String, FpcIdentity> getFpcIdentity = (v) -> new FpcIdentity(new FpcIdentityUnion(v));
+ public static Function<String, ClientIdentifier> getClientIdentity = (v) -> new ClientIdentifier(getFpcIdentity.apply(v));
+
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java
new file mode 100644
index 0000000..f50a985
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/helpers/DpnApi.java
@@ -0,0 +1,481 @@
+package org.onosproject.fpcagent.helpers;
+
+
+import com.google.common.collect.Maps;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.fpcagent.workers.ZMQSBPublisherManager;
+import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.OpIdentifier;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.yangautoprefixnotify.value.DefaultDownlinkDataNotification;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.yangautoprefixnotify.value.DownlinkDataNotification;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnId;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.fpcidentity.FpcIdentityUnion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map;
+
+import static org.onosproject.fpcagent.helpers.Converter.*;
+
+/**
+ * DPDK DPN API over ZeroMQ.
+ */
+public class DpnApi {
+ protected static final Logger log = LoggerFactory.getLogger(DpnApi.class);
+ /**
+ * Topic for broadcasting
+ */
+ private static byte BROADCAST_TOPIC = 0b0000_0000;
+ private static byte CREATE_SESSION_TYPE = 0b0000_0001;
+ private static byte MODIFY_DL_BEARER_TYPE = 0b0000_0010;
+ private static byte DELETE_SESSION_TYPE = 0b0000_0011;
+ private static byte MODIFY_UL_BEARER_TYPE = 0b0000_0100;
+ private static byte CREATE_UL_BEARER_TYPE = 0b0000_0101;
+ private static byte CREATE_DL_BEARER_TYPE = 0b0000_0110;
+ private static byte DELETE_BEARER_TYPE = 0b0000_0110;
+ private static byte HELLO = 0b0000_1000;
+ private static byte BYE = 0b0000_1001;
+ private static byte SEND_ADC_TYPE = 0b001_0001;
+ private static byte DDN_ACK = 0b0000_0110;
+
+ private static byte DPN_HELLO = 0b0000_0001;
+ private static byte DPN_BYE = 0b0000_0010;
+ private static byte DOWNLINK_DATA_NOTIFICATION = 0b0000_0101;
+ private static byte DPN_STATUS_INDICATION = 0b0000_1100;
+ private static byte DPN_OVERLOAD_INDICATION = 0b0000_0101;
+ private static byte DPN_REPLY = 0b0000_0100;
+ private static String DOWNLINK_DATA_NOTIFICATION_STRING = "Downlink-Data-Notification";
+ private static final Map<String, FpcDpnId> uplinkDpnMap;
+ private static final Map<String, Short> topicToNodeMap;
+
+ static {
+ uplinkDpnMap = Maps.newConcurrentMap();
+ topicToNodeMap = Maps.newConcurrentMap();
+ }
+
+ /**
+ * Creates Mobility Session
+ *
+ * @param dpn - DPN
+ * @param imsi - IMSI
+ * @param ue_ip - Session IP Address
+ * @param default_ebi - Default EBI
+ * @param s1u_sgw_gtpu_ipv4 - SGW GTP-U IPv4 Address
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ * @param clientIdentifier - Client Identifier
+ * @param opIdentifier - Operation Identifier
+ * @param sessionId - Session Id
+ */
+ public static void create_session(
+ Short dpn,
+ BigInteger imsi,
+ Ip4Address ue_ip,
+ Short default_ebi,
+ Ip4Address s1u_sgw_gtpu_ipv4,
+ Long s1u_sgw_gtpu_teid,
+ Long clientIdentifier,
+ BigInteger opIdentifier,
+ Long sessionId
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(41)
+ .put(toUint8(dpn))
+ .put(CREATE_SESSION_TYPE)
+ .put(toUint64(imsi))
+ .put(toUint8(default_ebi))
+ .put(toUint32(ue_ip.toInt()))
+ .put(toUint32(s1u_sgw_gtpu_teid))
+ .put(toUint32(s1u_sgw_gtpu_ipv4.toInt()))
+ .put(toUint64(BigInteger.valueOf(sessionId)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(clientIdentifier))
+ .put(toUint32(opIdentifier.longValue()));
+
+ log.info("create_session: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Modify Downlink Bearer
+ *
+ * @param dpn - DPN
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ * @param s1u_enb_gtpu_ipv4 - ENodeB GTP-U IPv4 Address
+ * @param s1u_enb_gtpu_teid - ENodeB GTP-U TEID
+ * @param clientIdentifier - Client Identifier
+ * @param opIdentifier - Operation Identifier
+ */
+ public static void modify_bearer_dl(
+ Short dpn,
+ Long s1u_sgw_gtpu_teid,
+ Ip4Address s1u_enb_gtpu_ipv4,
+ Long s1u_enb_gtpu_teid,
+ Long clientIdentifier,
+ BigInteger opIdentifier
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(23)
+ .put(toUint8(dpn))
+ .put(MODIFY_DL_BEARER_TYPE)
+ .put(toUint32(s1u_enb_gtpu_ipv4.toInt()))
+ .put(toUint32(s1u_enb_gtpu_teid))
+ .put(toUint32(s1u_sgw_gtpu_teid))
+ .put(toUint32(clientIdentifier))
+ .put(toUint32(opIdentifier.longValue()));
+
+ log.info("modify_bearer_dl: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * DeleteOrQuery Mobility Session.
+ *
+ * @param dpn - DPN
+ * @param del_default_ebi - Default EBI
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ * @param clientIdentifier - Client Identifier
+ * @param opIdentifier - Operation Identifier
+ * @param sessionId - Session Id
+ */
+ public static void delete_session(
+ Short dpn,
+ Short del_default_ebi,
+ Long s1u_sgw_gtpu_teid,
+ Long clientIdentifier,
+ BigInteger opIdentifier,
+ Long sessionId
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(19)
+ .put(toUint8(dpn))
+ .put(DELETE_SESSION_TYPE)
+ .put(toUint64(BigInteger.valueOf(sessionId)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(clientIdentifier))
+ .put(toUint32(opIdentifier.longValue()));
+
+ log.info("delete_session: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Create Uplink Bearer.
+ *
+ * @param dpn - DPN
+ * @param imsi - IMSI
+ * @param default_ebi - Default EBI
+ * @param dedicated_ebi - Dedicated EBI
+ * @param s1u_sgw_gtpu_ipv4 - SGW GTP-U IPv4 Address
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ */
+ public static void create_bearer_ul(
+ Short dpn,
+ BigInteger imsi,
+ Short default_ebi,
+ Short dedicated_ebi,
+ Ip4Address s1u_sgw_gtpu_ipv4,
+ Long s1u_sgw_gtpu_teid
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(21)
+ .put(toUint8(dpn))
+ .put(CREATE_UL_BEARER_TYPE)
+ .put(toUint64(imsi))
+ .put(toUint8(default_ebi))
+ .put(toUint8(dedicated_ebi))
+ .put(toUint32(s1u_sgw_gtpu_ipv4.toInt()))
+ .put(toUint32(s1u_sgw_gtpu_teid));
+
+ log.info("create_bearer_ul: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Create Downlink Bearer.
+ *
+ * @param dpn - DPN
+ * @param dedicated_ebi - Default EBI
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ * @param s1u_enb_gtpu_ipv4 - ENodeB GTP-U IPv4 Address
+ * @param s1u_enb_gtpu_teid - ENodeB GTP-U TEID
+ */
+ public static void create_bearer_dl(
+ Short dpn,
+ Short dedicated_ebi,
+ Long s1u_sgw_gtpu_teid,
+ Ip4Address s1u_enb_gtpu_ipv4,
+ Long s1u_enb_gtpu_teid
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(16)
+ .put(toUint8(dpn))
+ .put(CREATE_DL_BEARER_TYPE)
+ .put(toUint8(dedicated_ebi))
+ .put(toUint32(s1u_sgw_gtpu_teid))
+ .put(toUint32(s1u_enb_gtpu_ipv4.toInt()))
+ .put(toUint32(s1u_enb_gtpu_teid));
+
+ log.info("create_bearer_dl: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Modify Downlink Bearer.
+ *
+ * @param dpn - DPN
+ * @param s1u_sgw_gtpu_ipv4 - SGW GTP-U IPv4 Address
+ * @param s1u_enb_gtpu_teid - ENodeB TEID
+ * @param s1u_enb_gtpu_ipv4 - ENodeB GTP-U IPv4 Address
+ * @param clientIdentifier - Client Identifier
+ * @param opIdentifier - Operation Identifier
+ * @param sessionId - Session Id
+ */
+ public static void modify_bearer_dl(
+ Short dpn,
+ Ip4Address s1u_enb_gtpu_ipv4,
+ Long s1u_enb_gtpu_teid,
+ Ip4Address s1u_sgw_gtpu_ipv4,
+ Long clientIdentifier,
+ BigInteger opIdentifier,
+ Long sessionId
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(32)
+ .put(toUint8(dpn))
+ .put(MODIFY_DL_BEARER_TYPE)
+ .put(toUint32(s1u_sgw_gtpu_ipv4.toInt()))
+ .put(toUint32(s1u_enb_gtpu_teid))
+ .put(toUint32(s1u_enb_gtpu_ipv4.toInt()))
+ .put(toUint64(BigInteger.valueOf(sessionId)))
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(clientIdentifier))
+ .put(toUint32(opIdentifier.longValue()));
+
+ log.info("modify_bearer_dl: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Modify Uplink Bearer.
+ *
+ * @param dpn - DPN
+ * @param s1u_enb_gtpu_ipv4 - ENodeB GTP-U IPv4 Address
+ * @param s1u_enb_gtpu_teid - ENodeB GTP-U TEID
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ */
+ public static void modify_bearer_ul(
+ Short dpn,
+ Ip4Address s1u_enb_gtpu_ipv4,
+ Long s1u_enb_gtpu_teid,
+ Long s1u_sgw_gtpu_teid
+ ) {
+ ByteBuffer bb = ByteBuffer.allocate(15)
+ .put(toUint8(dpn))
+ .put(MODIFY_UL_BEARER_TYPE)
+ .put(toUint32(s1u_enb_gtpu_ipv4.toInt()))
+ .put(toUint32(s1u_enb_gtpu_teid))
+ .put(toUint32(s1u_sgw_gtpu_teid));
+
+ log.info("modify_bearer_ul: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * DeleteOrQuery Bearer.
+ *
+ * @param dpnTopic - DPN
+ * @param s1u_sgw_gtpu_teid - SGW GTP-U TEID
+ */
+ public static void delete_bearer(
+ Short dpnTopic,
+ Long s1u_sgw_gtpu_teid) {
+ ByteBuffer bb = ByteBuffer.allocate(7)
+ .put(toUint8(dpnTopic))
+ .put(DELETE_BEARER_TYPE)
+ .put(toUint32(s1u_sgw_gtpu_teid));
+
+ log.info("delete_bearer: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Creates the byte buffer to send ADC rules over ZMQ
+ *
+ * @param topic - DPN Topic
+ * @param domain_name - domain
+ * @param ip - ipaddress/ipprefix (i.e. 127.0.0.1/32)
+ * @param drop - Drop if 1
+ * @param rating_group - Rating Group
+ * @param service_ID - Service ID
+ * @param sponsor_ID - Sponsor ID
+ */
+ public static void send_ADC_rules(Short topic,
+ String domain_name, String ip,
+ Short drop, Long rating_group,
+ Long service_ID, String sponsor_ID) {
+ Ip4Prefix ip_prefix = null;
+ if (ip != null) {
+ ip_prefix = Ip4Prefix.valueOf(ip);
+ }
+ Short selector_type = (short) (domain_name != null ? 0 : ip_prefix != null ? 2 : ip_prefix.address() != null ? 1 : 255);
+ if (selector_type == 255) {
+ log.warn("Domain/IP not found, failed to send rules");
+ return;
+ }
+ ByteBuffer bb = ByteBuffer.allocate(200);
+ bb.put(toUint8(topic))
+ .put(SEND_ADC_TYPE)
+ .put(toUint8(selector_type));
+ if (selector_type == 0) {
+ bb.put(toUint8((short) domain_name.length()))
+ .put(domain_name.getBytes());
+ }
+ if ((selector_type == 1) || (selector_type == 2)) {
+ int ip_address_long = ip_prefix.address().toInt();
+ bb.put(toUint32(ip_address_long));
+ }
+ if (selector_type == 2) {
+ bb.put(toUint16(ip_prefix.prefixLength()));
+ }
+ if (drop != null)
+ bb.put(toUint8(drop));
+ if (rating_group != null)
+ bb.put(toUint32(rating_group));
+ if (service_ID != null)
+ bb.put(toUint32(service_ID));
+ if (sponsor_ID != null && (short) sponsor_ID.length() > 0) {
+ bb.put(toUint8((short) sponsor_ID.length()))
+ .put(sponsor_ID.getBytes());
+ }
+ bb.put(toUint8(ZMQSBSubscriberManager.getControllerTopic()));
+
+ log.info("send_ADC_rules: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Ensures the session id is an unsigned 64 bit integer
+ *
+ * @param sessionId - session id received from the DPN
+ * @return unsigned session id
+ */
+ private static BigInteger checkSessionId(BigInteger sessionId) {
+ if (sessionId.compareTo(BigInteger.ZERO) < 0) {
+ sessionId = sessionId.add(BigInteger.ONE.shiftLeft(64));
+ }
+ return sessionId;
+ }
+
+ /**
+ * Decodes a DownlinkDataNotification
+ *
+ * @param buf - message buffer
+ * @param key - Concatenation of node id + / + network id
+ * @return DownlinkDataNotification or null if it could not be successfully decoded
+ */
+ private static DownlinkDataNotification processDDN(byte[] buf, String key) {
+ DownlinkDataNotification ddnB = new DefaultDownlinkDataNotification();
+ ddnB.sessionId(checkSessionId(toBigInt(buf, 2)));
+ ddnB.notificationMessageType(DOWNLINK_DATA_NOTIFICATION_STRING);
+ ddnB.clientId(ClientIdentifier.of(FpcIdentity.of(FpcIdentityUnion.of(fromIntToLong(buf, 10)))));
+ ddnB.opId(OpIdentifier.of(BigInteger.valueOf(fromIntToLong(buf, 14))));
+ ddnB.notificationDpnId(uplinkDpnMap.get(key));
+ return ddnB;
+ }
+
+ /**
+ * Decodes a DPN message.
+ *
+ * @param buf - message buffer
+ * @return - A pair with the DPN Id and decoded Object
+ */
+ public static Map.Entry<FpcDpnId, Object> decode(byte[] buf) {
+ if (buf[1] == DPN_REPLY) {
+ return null;
+ } else if (buf[1] == DOWNLINK_DATA_NOTIFICATION) {
+ short nodeIdLen = buf[18];
+ short networkIdLen = buf[19 + nodeIdLen];
+ String key = new String(Arrays.copyOfRange(buf, 19, 19 + nodeIdLen)) + "/" + new String(Arrays.copyOfRange(buf, 20 + nodeIdLen, 20 + nodeIdLen + networkIdLen));
+ return uplinkDpnMap.get(key) == null ? null : new AbstractMap.SimpleEntry<>(uplinkDpnMap.get(key), processDDN(buf, key));
+ } else if (buf[1] == DPN_STATUS_INDICATION) {
+ DPNStatusIndication.Status status = null;
+
+ short nodeIdLen = buf[8];
+ short networkIdLen = buf[9 + nodeIdLen];
+ String key = new String(Arrays.copyOfRange(buf, 9, 9 + nodeIdLen)) + "/" + new String(Arrays.copyOfRange(buf, 10 + nodeIdLen, 10 + nodeIdLen + networkIdLen));
+ if (buf[3] == DPN_OVERLOAD_INDICATION) {
+ status = DPNStatusIndication.Status.OVERLOAD_INDICATION;
+ } else if (buf[3] == DPN_HELLO) {
+ status = DPNStatusIndication.Status.HELLO;
+ topicToNodeMap.put(key, (short) buf[2]);
+ } else if (buf[3] == DPN_BYE) {
+ status = DPNStatusIndication.Status.BYE;
+ topicToNodeMap.remove(key);
+ }
+ return new AbstractMap.SimpleEntry<>(uplinkDpnMap.get(key), new DPNStatusIndication(status, key));
+ }
+ return null;
+ }
+
+ /**
+ * Gets the mapping for node id / network id to ZMQ Topic
+ *
+ * @param Key - Concatenation of node id + / + network id
+ * @return - ZMQ Topic
+ */
+ public static Short getTopicFromNode(String Key) {
+ Short aShort = topicToNodeMap.get(Key);
+ return aShort != null ? aShort : (short) 1;
+ }
+
+ /**
+ * Provides basic status changes,
+ */
+ public static class DPNStatusIndication {
+ private final Status status;
+ private final String key; //nodeId +"/"+ networkId
+ /**
+ * Node Reference of the DPN
+ */
+ public Short nodeRef;
+ /**
+ * Constructor providing the DPN and its associated Status.
+ *
+ * @param status - DPN Status
+ * @param key - Combination of node id and network id
+ */
+ public DPNStatusIndication(Status status,
+ String key) {
+ this.status = status;
+ this.key = key;
+ }
+
+ /**
+ * Provides DPN Status
+ *
+ * @return Status associated to the DPN.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ /**
+ * Provides the DPN key - nodeId +"/"+ networkId
+ *
+ * @return FpcDpnId
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * Basic DPN Status
+ */
+ public enum Status {
+ HELLO,
+ BYE,
+ OVERLOAD_INDICATION
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/package-info.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/package-info.java
new file mode 100644
index 0000000..45fe96c
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * FPC Agent.
+ */
+package org.onosproject.fpcagent;
\ No newline at end of file
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebApplication.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebApplication.java
new file mode 100644
index 0000000..d4e68fc
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebApplication.java
@@ -0,0 +1,15 @@
+package org.onosproject.fpcagent.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * Sample REST API web application.
+ */
+public class AppWebApplication extends AbstractWebApplication {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return getClasses(AppWebResource.class);
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebResource.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebResource.java
new file mode 100644
index 0000000..12de2ed
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/rest/AppWebResource.java
@@ -0,0 +1,81 @@
+package org.onosproject.fpcagent.rest;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.fpcagent.FpcService;
+import org.onosproject.fpcagent.dto.configure.Configure;
+import org.onosproject.fpcagent.dto.dpn.AddDpn;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Path("/")
+public class AppWebResource extends AbstractWebResource {
+ private static final Logger log = LoggerFactory.getLogger(AppWebResource.class);
+
+ protected CoreService coreService = get(CoreService.class);
+ private FpcService fpcService;
+
+ public AppWebResource() {
+ ApplicationId appId = coreService.getAppId("org.onosproject.fpcagent");
+ fpcService = get(FpcService.class);
+ }
+
+ @POST
+ @Path("configure")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response configure(InputStream stream) {
+ try {
+ ObjectNode node = (ObjectNode) mapper().readTree(stream);
+ Configure configure = mapper().readValue(node.toString(), Configure.class);
+ fpcService.configure(configure);
+ } catch (IOException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ return Response.ok().build();
+ }
+
+ @POST
+ @Path("dpns/add_dpn")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response addDpn(InputStream stream) {
+ try {
+ ObjectNode node = (ObjectNode) mapper().readTree(stream);
+ AddDpn dpns = mapper().readValue(node.toString(), AddDpn.class);
+ fpcService.addDpn(dpns);
+ } catch (IOException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ return Response.ok().build();
+ }
+
+ @DELETE
+ @Path("dpns/{dpn}")
+ public Response deleteDpn(@PathParam("dpn") String dpn) {
+ if (dpn != null) {
+ fpcService.deleteDpn(dpn);
+ return Response.ok().build();
+ }
+ return Response.ok().build();
+ }
+
+ @POST
+ @Path("register_client")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response registerClient(InputStream stream) {
+
+ return Response.ok().build();
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java
new file mode 100644
index 0000000..d79cf69
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/NBWorkManager.java
@@ -0,0 +1,80 @@
+package org.onosproject.fpcagent.workers;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.ConfigureInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.ConfigureBundlesInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.eventderegister.EventDeregisterInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.eventregister.EventRegisterInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.probe.ProbeInput;
+import org.onosproject.yang.model.RpcInput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class NBWorkManager implements AutoCloseable {
+ private static final Logger log = LoggerFactory.getLogger(NBWorkManager.class);
+
+ // TODO: add store
+ private static NBWorkManager _instance = null;
+ private final BlockingQueue<Object> blockingQueue;
+ private final int poolSize;
+ private boolean run;
+
+ protected NBWorkManager(int poolSize) {
+ this.blockingQueue = new LinkedBlockingQueue<>();
+ this.poolSize = poolSize;
+ this.run = true;
+ }
+
+ public static NBWorkManager createInstance(int poolSize) {
+ if (_instance == null) {
+ _instance = new NBWorkManager(poolSize);
+ }
+ return _instance;
+ }
+
+ public static NBWorkManager getInstance() {
+ return _instance;
+ }
+
+ public void submit(RpcInput input) {
+ try {
+ blockingQueue.put(input);
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+
+ public void open() {
+ ExecutorService executorService = Executors.newFixedThreadPool(this.poolSize);
+ executorService.submit(() -> {
+ while ((!Thread.currentThread().isInterrupted()) && run) {
+ try {
+ Object o = blockingQueue.take();
+ if (o instanceof ConfigureInput) {
+
+ } else if (o instanceof ConfigureBundlesInput) {
+
+ } else if (o instanceof EventRegisterInput) {
+
+ } else if (o instanceof EventDeregisterInput) {
+
+ } else if (o instanceof ProbeInput) {
+
+ }
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ });
+ }
+
+ @Override
+ public void close() throws Exception {
+ run = false;
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java
new file mode 100644
index 0000000..35701fe
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBPublisherManager.java
@@ -0,0 +1,71 @@
+package org.onosproject.fpcagent.workers;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZContext;
+import org.zeromq.ZMQ;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class ZMQSBPublisherManager implements AutoCloseable {
+ private static final Logger log = LoggerFactory.getLogger(ZMQSBPublisherManager.class);
+ private static ZMQSBPublisherManager _instance = null;
+ private final ZContext ctx;
+ private final String address;
+ private final BlockingQueue<ByteBuffer> blockingQueue;
+ private final int poolSize;
+ private boolean run;
+
+ protected ZMQSBPublisherManager(String address, int poolSize) {
+ this.ctx = new ZContext();
+ this.address = address;
+ this.run = true;
+ this.blockingQueue = new LinkedBlockingQueue<>();
+ this.poolSize = poolSize;
+ }
+
+ public static ZMQSBPublisherManager createInstance(String address, int poolSize) {
+ if (_instance == null) {
+ _instance = new ZMQSBPublisherManager(address, poolSize);
+ }
+ return _instance;
+ }
+
+ public static ZMQSBPublisherManager getInstance() {
+ return _instance;
+ }
+
+ public void send(ByteBuffer buf) {
+ try {
+ blockingQueue.put(buf);
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+
+ public void open() {
+ ExecutorService executorService = Executors.newFixedThreadPool(this.poolSize);
+ executorService.submit(() -> {
+ ZMQ.Socket socket = ctx.createSocket(ZMQ.PUB);
+ socket.connect(address);
+ while ((!Thread.currentThread().isInterrupted()) && run) {
+ try {
+ byte[] array = blockingQueue.take().array();
+ socket.send(array);
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ });
+ }
+
+ @Override
+ public void close() {
+ run = false;
+ }
+}
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java
new file mode 100644
index 0000000..cddd6d4
--- /dev/null
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/workers/ZMQSBSubscriberManager.java
@@ -0,0 +1,314 @@
+package org.onosproject.fpcagent.workers;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.fpcagent.helpers.DpnApi;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.yangautoprefixnotify.value.DownlinkDataNotification;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcDpnId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZContext;
+import org.zeromq.ZMQ;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadLocalRandom;
+
+import static org.onosproject.fpcagent.helpers.Converter.*;
+
+public class ZMQSBSubscriberManager implements AutoCloseable {
+ private static final Logger log = LoggerFactory.getLogger(ZMQSBSubscriberManager.class);
+ private static int MIN_TOPIC_VAL = 4;
+ private static int MAX_TOPIC_VAL = 255;
+ private static byte ASSIGN_ID = 0b0000_1010;
+ private static byte ASSIGN_CONFLICT = 0b0000_1011;
+ private static byte HELLO_REPLY = 0b0000_1101;
+ private static byte CONTROLLER_STATUS_INDICATION = 0b0000_1110;
+ private static byte HELLO = 0b0000_0001;
+ private static byte GOODBYE = 0b0000_0010;
+ private static ZMQSBSubscriberManager _instance = null;
+ private static Long controllerSourceId;
+ private static Short subscriberId;
+ private final String address;
+ private final Short broadcastAllId;
+ private final Short broadcastControllersId;
+ private final Short broadcastDpnsId;
+ private final String nodeId;
+ private final String networkId;
+ private boolean run;
+ private boolean conflictingTopic;
+ private Future<?> broadcastAllWorker;
+ private Future<?> broadcastControllersWorker;
+ private Future<?> broadcastTopicWorker;
+ private Future<?> generalWorker;
+
+ protected ZMQSBSubscriberManager(String address, String broadcastAllId, String broadcastControllersId,
+ String broadcastDpnsId, String nodeId, String networkId) {
+ this.address = address;
+ this.run = true;
+
+ this.nodeId = nodeId;
+ this.networkId = networkId;
+ this.broadcastAllId = Short.parseShort(broadcastAllId);
+ this.broadcastControllersId = Short.parseShort(broadcastControllersId);
+ this.broadcastDpnsId = Short.parseShort(broadcastDpnsId);
+
+ this.conflictingTopic = false;
+ controllerSourceId = (long) ThreadLocalRandom.current().nextInt(0, 65535);
+ }
+
+ public static ZMQSBSubscriberManager createInstance(String address, String broadcastAllId,
+ String broadcastControllersId, String broadcastDpnsId,
+ String nodeId, String networkId) {
+ if (_instance == null) {
+ _instance = new ZMQSBSubscriberManager(address, broadcastAllId, broadcastControllersId,
+ broadcastDpnsId, nodeId, networkId);
+ }
+ return _instance;
+ }
+
+ public static ZMQSBSubscriberManager getInstance() {
+ return _instance;
+ }
+
+ public static Short getControllerTopic() {
+ return subscriberId;
+ }
+
+ public static Long getControllerSourceId() {
+ return controllerSourceId;
+ }
+
+ public void open() {
+ short subscriberId = (short) ThreadLocalRandom.current().nextInt(MIN_TOPIC_VAL, MAX_TOPIC_VAL + 1);
+
+ broadcastAllWorker = Executors.newSingleThreadExecutor().submit(new ZMQSubscriberWorker(broadcastAllId));
+ broadcastControllersWorker = Executors.newSingleThreadExecutor()
+ .submit(new ZMQSubscriberWorker(broadcastControllersId));
+ broadcastTopicWorker = Executors.newSingleThreadExecutor().submit(new BroadcastTopic(subscriberId));
+ }
+
+ @Override
+ public void close() {
+ run = false;
+ }
+
+ /**
+ * Interrupts the BroadcastTopicworker if there is an Assign topic Conflict
+ *
+ * @param conflict - Flag to indicate conflict
+ * @param subId - Topic Id that caused the conflict
+ */
+ protected void BroadcastAllSubIdCallBack(boolean conflict, Short subId) {
+ if (conflict && subscriberId.equals(subId)) {
+ this.conflictingTopic = true;
+ broadcastTopicWorker.cancel(true);
+ }
+ }
+
+ /**
+ * Broadcasts the GOODBYE message to all the DPNs
+ */
+ public void sendGoodbyeToDpns() {
+ ByteBuffer bb = ByteBuffer.allocate(10 + nodeId.length() + networkId.length());
+ bb.put(toUint8(broadcastDpnsId))
+ .put(CONTROLLER_STATUS_INDICATION)
+ .put(toUint8(subscriberId))
+ .put(GOODBYE)
+ .put(toUint32(controllerSourceId))
+ .put(toUint8((short) nodeId.length()))
+ .put(nodeId.getBytes())
+ .put(toUint8((short) networkId.length()))
+ .put(networkId.getBytes());
+
+ log.info("sendGoodbyeToDpns: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Broadcasts an Assign Conflict message
+ *
+ * @param contents - byte array received over the southbound.
+ */
+ protected void SendAssignConflictMessage(byte[] contents) {
+ byte topic = contents[2];
+ short nodeIdLen = contents[7];
+ short networkIdLen = contents[8 + nodeIdLen];
+ String node_id = new String(Arrays.copyOfRange(contents, 8, 8 + nodeIdLen));
+ String network_id = new String(Arrays.copyOfRange(contents, 9 + nodeIdLen, 9 + nodeIdLen + networkIdLen));
+
+ if (toUint8(subscriberId) == topic || nodeId.equals(node_id) || networkId.equals(network_id)) {
+ ByteBuffer bb = ByteBuffer.allocate(9 + nodeId.length() + networkId.length());
+ bb.put(toUint8(broadcastAllId))
+ .put(ASSIGN_CONFLICT)
+ .put(topic)
+ .put(toUint32(controllerSourceId))
+ .put(toUint8((short) nodeId.length()))
+ .put(nodeId.getBytes())
+ .put(toUint8((short) networkId.length()))
+ .put(networkId.getBytes());
+
+ log.info("SendAssignConflictMessage: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+ }
+
+ protected class ZMQSubscriberWorker implements Runnable {
+ private final Short subscriberId;
+ private ZContext ctx;
+
+ ZMQSubscriberWorker(Short subscriberId) {
+ this.subscriberId = subscriberId;
+ this.ctx = new ZContext();
+ }
+
+ /**
+ * Sends a reply to a DPN Hello
+ *
+ * @param dpnStatus - DPN Status Indication message received from the DPN
+ */
+ protected void sendHelloReply(DpnApi.DPNStatusIndication dpnStatus) {
+ if (DpnApi.getTopicFromNode(dpnStatus.getKey()) != null) {
+ ByteBuffer bb = ByteBuffer.allocate(9 + nodeId.length() + networkId.length())
+ .put(toUint8(DpnApi.getTopicFromNode(dpnStatus.getKey())))
+ .put(HELLO_REPLY)
+ .put(toUint8(ZMQSBSubscriberManager.getControllerTopic()))
+ .put(toUint32(ZMQSBSubscriberManager.getControllerSourceId()))
+ .put(toUint8((short) nodeId.length()))
+ .put(nodeId.getBytes())
+ .put(toUint8((short) networkId.length()))
+ .put(networkId.getBytes());
+
+ log.info("sendHelloReply: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+ }
+
+ @Override
+ public void run() {
+ ZMQ.Socket subscriber = this.ctx.createSocket(ZMQ.SUB);
+ subscriber.connect(address);
+ subscriber.subscribe(new byte[]{toUint8(subscriberId)});
+ while ((!Thread.currentThread().isInterrupted()) && run) {
+ byte[] contents = subscriber.recv();
+ byte topic = contents[0];
+ byte messageType = contents[1];
+ switch (topic) {
+ case 1:
+ if (messageType == ASSIGN_CONFLICT && toInt(contents, 3) != controllerSourceId) {
+ BroadcastAllSubIdCallBack(true, (short) contents[2]);
+ } else if (messageType == ASSIGN_ID && toInt(contents, 3) != controllerSourceId) {
+ SendAssignConflictMessage(contents);
+ }
+ break;
+ default:
+ Map.Entry<FpcDpnId, Object> entry = DpnApi.decode(contents);
+ if (entry != null) {
+ if (entry.getValue() instanceof DownlinkDataNotification) {
+// log.info("DownlinkDataNotification");
+ } else if (entry.getValue() instanceof DpnApi.DPNStatusIndication) {
+ DpnApi.DPNStatusIndication dpnStatus = (DpnApi.DPNStatusIndication) entry.getValue();
+// log.info("DPNStatusIndication");
+ if (dpnStatus.getStatus() == DpnApi.DPNStatusIndication.Status.HELLO) {
+ sendHelloReply(dpnStatus);
+ }
+ }
+ }
+ }
+ }
+ subscriber.disconnect(address);
+ subscriber.close();
+ ctx.destroySocket(subscriber);
+ try {
+ Thread.currentThread().join();
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ }
+
+ /**
+ * Class to broadcast a topic for the controller
+ */
+ protected class BroadcastTopic implements Runnable {
+ private Short topic;
+
+ /**
+ * Constructor
+ *
+ * @param topic - Topic to broadcast
+ */
+ public BroadcastTopic(Short topic) {
+ this.topic = topic;
+ }
+
+ /**
+ * Broadcasts the topic
+ */
+ private void broadcastTopic() {
+ ByteBuffer bb = ByteBuffer.allocate(9 + nodeId.length() + networkId.length());
+ bb.put(toUint8(broadcastAllId))
+ .put(ASSIGN_ID)
+ .put(toUint8(this.topic))
+ .put(toUint32(controllerSourceId))
+ .put(toUint8((short) nodeId.length()))
+ .put(nodeId.getBytes())
+ .put(toUint8((short) networkId.length()))
+ .put(networkId.getBytes());
+
+ log.info("broadcastTopic: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ /**
+ * Broadcasts the HELLO message to all the DPNs
+ */
+ private void sendHelloToDpns() {
+ ByteBuffer bb = ByteBuffer.allocate(10 + nodeId.length() + networkId.length());
+ bb.put(toUint8(broadcastDpnsId))
+ .put(CONTROLLER_STATUS_INDICATION)
+ .put(toUint8(subscriberId))
+ .put(HELLO)
+ .put(toUint32(controllerSourceId))
+ .put(toUint8((short) nodeId.length()))
+ .put(nodeId.getBytes())
+ .put(toUint8((short) networkId.length()))
+ .put(networkId.getBytes());
+
+ log.info("sendHelloToDpns: {}", bb.array());
+ ZMQSBPublisherManager.getInstance().send(bb);
+ }
+
+ @Override
+ public void run() {
+ try {
+ this.broadcastTopic();
+ log.info("Thread sleeping: " + Thread.currentThread().getName());
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ if (conflictingTopic) {
+ conflictingTopic = false;
+ this.topic = (short) ThreadLocalRandom.current().nextInt(MIN_TOPIC_VAL, MAX_TOPIC_VAL + 1);
+ subscriberId = this.topic;
+ this.run();
+ return;
+ } else {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ }
+ subscriberId = this.topic;
+ log.info("Topic Id: " + this.topic);
+ generalWorker = Executors.newSingleThreadExecutor().submit(new ZMQSubscriberWorker(this.topic));
+
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ log.error(ExceptionUtils.getFullStackTrace(e));
+ }
+ sendHelloToDpns();
+ }
+
+ }
+}
diff --git a/apps/fpcagent/src/main/webapp/WEB-INF/web.xml b/apps/fpcagent/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..92d9960
--- /dev/null
+++ b/apps/fpcagent/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2016-present Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="ONOS" version="2.5">
+ <display-name>FPC Agent REST API</display-name>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Secured</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>karaf</realm-name>
+ </login-config>
+
+ <servlet>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.onosproject.fpcagent.rest.AppWebApplication</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
diff --git a/models/fpcagent/BUCK b/models/fpcagent/BUCK
new file mode 100644
index 0000000..2615870
--- /dev/null
+++ b/models/fpcagent/BUCK
@@ -0,0 +1,14 @@
+COMPILE_DEPS = [
+ '//models/common:onos-models-common',
+]
+
+APPS = [
+ 'org.onosproject.models.common',
+]
+
+yang_model(
+ app_name = 'org.onosproject.models.fpcagent',
+ title = 'FPC Agent YANG Models',
+ deps = COMPILE_DEPS,
+ required_apps = APPS,
+)
diff --git a/models/fpcagent/src/main/yang/fpc-config.yang b/models/fpcagent/src/main/yang/fpc-config.yang
new file mode 100644
index 0000000..10a656c
--- /dev/null
+++ b/models/fpcagent/src/main/yang/fpc-config.yang
@@ -0,0 +1,106 @@
+module fpc-config {
+ yang-version 1;
+ namespace "urn:opendaylight:fpc:config";
+ prefix fpc-config;
+
+ description
+ "Configuration for ...";
+
+ revision "2016-09-27" {
+ description
+ "Initial revision.";
+ }
+
+ container fpc-config {
+ leaf use-memcached {
+ type boolean;
+ }
+ leaf memcached-uri {
+ type string;
+ }
+ leaf memcached-threads {
+ type uint16;
+ }
+ leaf scheduled-monitors-poolsize {
+ type uint16;
+ }
+ leaf monitor-threads {
+ type uint16;
+ }
+ leaf dpn-listener-uri {
+ type string;
+ }
+ leaf dpn-listener-id {
+ type string;
+ }
+ leaf dpn-client-uri {
+ type string;
+ }
+ leaf dpn-message-processor-threads{
+ type uint16;
+ }
+ leaf dpn-client-threads {
+ type uint16;
+ }
+ leaf metricsupdate-ms {
+ type uint32;
+ }
+ leaf mobilityupdate-ms {
+ type uint32;
+ }
+ leaf node-id {
+ type string;
+ }
+ leaf network-id {
+ type string;
+ }
+ leaf activation-threads {
+ type uint16;
+ }
+ leaf target-read-limit {
+ type uint16;
+ }
+ leaf default-tenant-id {
+ type string;
+ }
+ leaf default-group-id {
+ type string;
+ }
+ leaf prefers-fast-clients {
+ type boolean;
+ }
+ leaf http-notifier-clients {
+ type uint16;
+ }
+ leaf zmq-nbi-server-poolsize {
+ type uint16;
+ }
+ leaf zmq-nbi-server-uri {
+ type string;
+ }
+ leaf zmq-nbi-inproc-uri {
+ type string;
+ }
+ leaf zmq-nbi-handler-poolsize {
+ type uint16;
+ }
+ leaf zmq-broadcast-all {
+ type string;
+ }
+ leaf zmq-broadcast-controllers {
+ type string;
+ }
+ leaf zmq-broadcast-dpns {
+ type string;
+ }
+ leaf http-nio2-nb-poolsize {
+ type uint16;
+ }
+ leaf http-nio2-nb-port {
+ type uint16;
+ }
+ leaf max-trans-rate {
+ type uint16;
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/fpc.yang b/models/fpcagent/src/main/yang/fpc.yang
new file mode 100644
index 0000000..5cd95f4
--- /dev/null
+++ b/models/fpcagent/src/main/yang/fpc.yang
@@ -0,0 +1,169 @@
+module fpc {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:fpc";
+ prefix "fpc";
+
+ import ietf-dmm-fpcagent { prefix fpcagent; }
+ import ietf-dmm-fpcbase { prefix fpcbase; }
+ import ietf-inet-types { prefix inet; }
+ import ietf-dmm-fpc-pmip { prefix fpc-pmip; }
+ import ietf-dmm-threegpp { prefix threegpp; }
+
+ revision "2015-01-05" {
+ description "Initial revision of fpc model";
+ }
+
+ // grouping zmq-dpn-config {
+ // leaf topic {
+ // type string;
+ // }
+ // }
+
+ // augment "/fpcagent:tenants/fpcagent:tenant/fpcagent:fpc-topology/fpcagent:dpns" {
+ // uses zmq-dpn-config;
+ // }
+
+ // New DPN Type
+ identity zmq-dpn-control-protocol {
+ base "fpcbase:fpc-dpn-control-protocol";
+ }
+
+ typedef membership-match-type {
+ type enumeration {
+ enum eq { value 0; }
+ enum super { value 1; }
+ enum psuper { value 2; }
+ enum sub { value 3; }
+ enum psub { value 4; }
+ enum overlap { value 5; }
+ enum nonoverlap { value 6; }
+ }
+ }
+
+ grouping membership-value {
+ leaf policy-membership {
+ type string;
+ }
+ }
+
+ augment "/fpcagent:tenants/fpcagent:tenant/fpcagent:fpc-policy/fpcagent:descriptors/fpcagent:descriptor-value" {
+ case tft-plusplus {
+ uses fpc:membership-value;
+ leaf membership-match-type {
+ type fpc:membership-match-type;
+ }
+ }
+ }
+
+ augment "/fpcagent:tenants/fpcagent:tenant/fpcagent:fpc-mobility/fpcagent:contexts" {
+ uses fpc:membership-value;
+ }
+ augment "/fpcagent:configure/fpcagent:input/fpcagent:op_body/fpcagent:create_or_update/fpcagent:contexts" {
+ uses fpc:membership-value;
+ }
+ augment "/fpcagent:configure-bundles/fpcagent:input/fpcagent:bundles/fpcagent:op_body/fpcagent:create_or_update/fpcagent:contexts" {
+ uses fpc:membership-value;
+ }
+ augment "/fpcagent:configure/fpcagent:output/fpcagent:result-type/fpcagent:common-success/fpcagent:contexts" {
+ uses fpc:membership-value;
+ }
+ augment "/fpcagent:configure-bundles/fpcagent:output/fpcagent:bundles/fpcagent:result-type/fpcagent:common-success/fpcagent:contexts" {
+ uses fpc:membership-value;
+ }
+ // TODO - Add Notification Augments for membership-value
+
+ container tx-stats {
+ config false;
+ leaf last-ts {
+ type string;
+ }
+ leaf total-txs {
+ type uint64;
+ }
+ list states {
+ key state;
+ leaf state {
+ type string;
+ }
+ leaf entries {
+ type uint64;
+ }
+ container total-time {
+ leaf mantissa {
+ type uint64;
+ }
+ leaf exponent {
+ type int32;
+ }
+ }
+ container average-time {
+ leaf mantissa {
+ type uint64;
+ }
+ leaf exponent {
+ type int32;
+ }
+ }
+ }
+ }
+
+ grouping connection-config {
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ leaf tenant-id {
+ type fpcbase:fpc-identity;
+ }
+ leaf-list supported-features {
+ type string;
+ }
+ leaf endpoint-uri {
+ type inet:uri;
+ }
+ leaf supports-oknotify-model {
+ type boolean;
+ }
+ leaf supports-ack-model {
+ type boolean;
+ }
+ }
+
+
+ container connection-info {
+ list connections {
+ config false;
+ key client-id;
+ leaf client-id {
+ type string;
+ }
+ container requested-info {
+ uses fpc:connection-config;
+ }
+ container assigned-info {
+ uses fpc:connection-config;
+ }
+ }
+ }
+
+ rpc register_client {
+ input {
+ uses fpc:connection-config;
+ }
+ output {
+ uses fpc:connection-config;
+ }
+ }
+
+ rpc deregister_client {
+ input {
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ }
+ output {
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-dmm-fpc-pmip.yang b/models/fpcagent/src/main/yang/ietf-dmm-fpc-pmip.yang
new file mode 100644
index 0000000..c44aaab
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-dmm-fpc-pmip.yang
@@ -0,0 +1,71 @@
+module ietf-dmm-fpc-pmip {
+ namespace "urn:ietf:params:xml:ns:yang:ietf-dmm-fpc-pmip";
+ prefix fpc-pmip;
+
+ organization "IETF DMM Working Group";
+ contact "Satoru Matsushima <satoru.matsushima@g.softbank.co.jp>";
+
+ description
+ "This module contains YANG definition for
+ Forwarding Policy Configuration Protocol.(FPCP)";
+
+ revision 2016-01-19 {
+ description "Changes based on -01 version of FPCP draft.";
+ reference "draft-ietf-dmm-fpc-cpdp-01";
+ }
+
+ identity pmip-tunnel-type {
+ description "PMIP Tunnel Type";
+ }
+ identity grev1 {
+ base "fpc-pmip:pmip-tunnel-type";
+ }
+ identity grev2 {
+ base "fpc-pmip:pmip-tunnel-type";
+ }
+ identity ipinip {
+ base "fpc-pmip:pmip-tunnel-type";
+ }
+ grouping pmip-mobility {
+ leaf type {
+ type identityref {
+ base "fpc-pmip:pmip-tunnel-type";
+ }
+ }
+ choice value {
+ case gre {
+ leaf key {
+ type uint32;
+ description "GRE_KEY";
+ }
+ }
+ }
+ }
+
+ typedef pmip-instr {
+ description "Instruction Set for PMIP";
+ type bits {
+ bit assign-ip {
+ position 0;
+ }
+ bit assign-dpn {
+ position 1;
+ }
+ bit session {
+ position 2;
+ }
+ bit uplink {
+ position 3;
+ }
+ bit downlink {
+ position 4;
+ }
+ }
+ }
+
+ grouping pmip-commandset {
+ leaf instr-pmip-mob {
+ type fpc-pmip:pmip-instr;
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-dmm-fpc-policyext.yang b/models/fpcagent/src/main/yang/ietf-dmm-fpc-policyext.yang
new file mode 100644
index 0000000..3845591
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-dmm-fpc-policyext.yang
@@ -0,0 +1,95 @@
+module ietf-dmm-fpc-policyext {
+ namespace "urn:ietf:params:xml:ns:yang:fpcpolicyext";
+ prefix fpcpolicyext;
+
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+
+ organization "IETF DMM Working Group";
+ contact "Satoru Matsushima <satoru.matsushima@g.softbank.co.jp>";
+
+ description
+ "This module contains YANG definition for
+ Forwarding Policy Configuration Protocol (FPCP)
+ common Policy Action and Descriptor extensions";
+
+ revision 2016-08-03 {
+ description "Changes based on -04 version of FPC draft.";
+ reference "draft-ietf-dmm-fpc-cpdp-04";
+ }
+
+ grouping simple-nat {
+ leaf outbound-nat-address {
+ type inet:ip-address;
+ }
+ }
+
+ grouping simple-napt {
+ leaf source-port {
+ type inet:port-number;
+ }
+ leaf outbound-napt-address {
+ type inet:ip-address;
+ }
+ leaf destination-port {
+ type inet:port-number;
+ }
+ }
+
+ grouping prefix-traffic-descriptor {
+ description
+ "Traffic descriptor group collects parameters to
+ identify target traffic flow. It represents
+ source/destination as IP prefixes";
+
+ leaf destination-ip {
+ type inet:ip-prefix;
+ description "Rule of destination IP";
+ }
+ leaf source-ip {
+ type inet:ip-prefix;
+ description "Rule of source IP";
+ }
+ }
+
+ grouping rating-action {
+ description "Rudimentary rating action applied based upon RFC 4006 attributes";
+ leaf service-context-id {
+ type string;
+ description "Per RFC 4006 - Contains a unique identifier of the Diameter credit-control service
+ specific document that applies to the request. The format of the Service-Context-Id is:
+
+ <service-context>@<domain>
+
+ service-context = Token
+
+ The Token is an arbitrary string of characters and digits.
+
+ 'domain' represents the entity that allocated the Service-Context-Id.";
+ }
+ leaf service-identifier {
+ type uint32;
+ description "From RFC 4006 - Contains the identifier of a service. The specific service the
+ request relates to is uniquely identified by the combination of
+ Service-Context-Id and Service-Identifier AVPs.";
+ }
+ leaf rating-group {
+ type uint32;
+ description "From RFC 4006 - Contains the identifier of a rating group. All the services subject
+ to the same rating type are part of the same rating group. The
+ specific rating group the request relates to is uniquely identified
+ by the combination of Service-Context-Id and Rating-Group AVPs.";
+ }
+ }
+
+ grouping domain-descriptor-list {
+ description "Descriptors for list of domains";
+ leaf-list source-domains {
+ type inet:domain-name;
+ description "Source Domain Names";
+ }
+ leaf-list destination-domains {
+ type inet:domain-name;
+ description "Destination Domain Names";
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-dmm-fpcagent.yang b/models/fpcagent/src/main/yang/ietf-dmm-fpcagent.yang
new file mode 100644
index 0000000..1b1ddd6
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-dmm-fpcagent.yang
@@ -0,0 +1,664 @@
+module ietf-dmm-fpcagent {
+ namespace "urn:ietf:params:xml:ns:yang:fpcagent";
+ prefix fpcagent;
+
+ import ietf-dmm-fpcbase { prefix fpcbase; revision-date 2016-08-03; }
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+ import ietf-dmm-fpc-pmip { prefix fpc-pmip; revision-date 2016-01-19; }
+ import ietf-dmm-threegpp { prefix threegpp; }
+
+ organization "IETF DMM Working Group";
+ contact "Satoru Matsushima <satoru.matsushima@g.softbank.co.jp>";
+
+ description
+ "This module contains YANG definition for
+ Forwarding Policy Configuration Protocol.(FPCP)";
+
+ revision 2016-08-03 {
+ description "Changes based on -04 version of FPC draft.";
+ reference "draft-ietf-dmm-fpc-cpdp-04";
+ }
+ feature fpc-cloning {
+ description "An ability to support cloning in the RPC.";
+ }
+ feature fpc-basename-registry {
+ description "Ability to track Base Names already provisioned on the Agent";
+ }
+ feature fpc-bundles {
+ description "Ability for Client to send multiple bundles of actions to
+ an Agent";
+ }
+ feature fpc-client-binding {
+ description "Allows a FPC Client to bind a DPN to an Topology Object";
+ }
+ feature fpc-auto-binding {
+ description "Allows a FPC Agent to advertise Topology Objects that could be DPNs";
+ }
+ feature instruction-bitset {
+ description "Allows the expression of instructions (bit sets) over FPC.";
+ }
+ feature operation-ref-scope {
+ description "Provides the scope of refeneces in an operation. Used to optmize
+ the Agent processing.";
+ }
+
+ typedef agent-identifier {
+ type fpcbase:fpc-identity;
+ }
+
+ typedef client-identifier {
+ type fpcbase:fpc-identity;
+ }
+
+ grouping basename-info {
+ leaf basename {
+ if-feature fpcagent:fpc-basename-registry;
+ description "Rules Basename";
+ type fpcbase:fpc-identity;
+ }
+ leaf base-state {
+ if-feature fpcagent:fpc-basename-registry;
+ type string;
+ }
+ leaf base-checkpoint {
+ if-feature fpcagent:fpc-basename-registry;
+ type string;
+ }
+ }
+
+ // Top Level Structures
+ container tenants {
+ description "";
+
+ list tenant {
+ description "";
+ key "tenant-id";
+ leaf tenant-id {
+ type fpcbase:fpc-identity;
+ }
+
+ container fpc-policy {
+ list policy-groups {
+ key "policy-group-id";
+ uses fpcbase:fpc-policy-group;
+ }
+ list policies {
+ key "policy-id";
+ uses fpcbase:fpc-policy;
+ }
+ list descriptors {
+ key descriptor-id;
+ uses fpcbase:fpc-descriptor;
+ }
+ list actions {
+ key action-id;
+ uses fpcbase:fpc-action;
+ }
+ }
+
+ container fpc-mobility {
+ config false;
+ list contexts {
+ key context-id;
+ uses fpcbase:fpc-context;
+ }
+ list ports {
+ key port-id;
+ uses fpcbase:fpc-port;
+ }
+ list monitors {
+ key monitor-id;
+ uses fpcbase:monitor-config;
+ }
+ }
+ container fpc-topology {
+ // Basic Agent Topology Structures
+ list domains {
+ key domain-id;
+ uses fpcbase:fpc-domain;
+ uses fpcagent:basename-info;
+ }
+
+ list dpn-group-peers {
+ if-feature fpcbase:fpc-basic-agent;
+ key "remote-dpn-group-id";
+ uses fpcbase:fpc-dpn-peer-group;
+ }
+ leaf topology-dpn-id {
+ if-feature fpcbase:fpc-basic-agent;
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf-list control-protocols {
+ if-feature fpcbase:fpc-basic-agent;
+ type identityref {
+ base "fpcbase:fpc-dpn-control-protocol";
+ }
+ }
+
+ list dpn-groups {
+ if-feature fpcbase:fpc-multi-dpn;
+ key dpn-group-id;
+ uses fpcagent:fpc-dpn-group;
+ list domains {
+ key domain-id;
+ uses fpcbase:fpc-domain;
+ uses fpcagent:basename-info;
+ }
+ }
+ list dpns {
+ if-feature fpcbase:fpc-multi-dpn;
+ key dpn-id;
+ uses fpcbase:fpc-dpn;
+ }
+ }
+
+ }
+ }
+
+ container fpc-agent-info {
+ // General Agent Structures
+ leaf-list supported-features {
+ type string;
+ }
+
+ // Common Agent Info
+ list supported-events {
+ key event;
+ leaf event {
+ type identityref {
+ base "fpcbase:event-type";
+ }
+ }
+ leaf event-id {
+ type fpcbase:event-type-id;
+ }
+ }
+
+ list supported-error-types {
+ key error-type;
+ leaf error-type {
+ type identityref {
+ base "fpcagent:error-type";
+ }
+ }
+ leaf error-type-id {
+ type fpcagent:error-type-id;
+ }
+ }
+ }
+
+
+ // Multi-DPN Agent Structures
+ grouping fpc-dpn-group {
+ leaf dpn-group-id {
+ type fpcbase:fpc-dpn-group-id;
+ }
+ leaf data-plane-role {
+ type identityref {
+ base "fpcbase:fpc-forwaridingplane-role";
+ }
+ }
+ leaf access-type {
+ type identityref {
+ base "fpcbase:fpc-access-type";
+ }
+ }
+ leaf mobility-profile {
+ type identityref {
+ base "fpcbase:fpc-mobility-profile-type";
+ }
+ }
+ list dpn-group-peers {
+ key "remote-dpn-group-id";
+ uses fpcbase:fpc-dpn-peer-group;
+ }
+ }
+
+
+ // RPC
+ // RPC Specific Structures
+ //Input Structures
+ typedef admin-status {
+ type enumeration {
+ enum enabled { value 0; }
+ enum disabled { value 1; }
+ enum virtual { value 2; }
+ }
+ }
+
+ typedef session-status {
+ type enumeration {
+ enum complete { value 0; }
+ enum incomplete { value 1; }
+ enum outdated { value 2; }
+ }
+ }
+
+ typedef op-delay {
+ type uint32;
+ }
+
+ typedef op-identifier {
+ type uint64;
+ }
+
+ typedef ref-scope {
+ description "Search scope for references in the operation.
+ op - All references are contained in the operation body (intra-op)
+ bundle - All references in exist in bundle (inter-operation/intra-bundle).
+ NOTE - If this value comes in CONFIG call it is equivalen to 'op'.
+ storage - One or more references exist outside of the operation and bundle.
+ A lookup to a cache / storage is required.
+ unknown - the location of the references are unknown. This is treated as
+ a 'storage' type.";
+ type enumeration {
+ enum none { value 0; }
+ enum op { value 1; }
+ enum bundle { value 2; }
+ enum storage { value 3; }
+ enum unknown { value 4; }
+ }
+ }
+
+ grouping instructions {
+ container instructions {
+ if-feature instruction-bitset;
+ choice instr-type {
+ case pmip-instr {
+ uses fpc-pmip:pmip-commandset;
+ }
+ case instr-3gpp-mob {
+ uses threegpp:threegpp-commandset;
+ }
+ }
+ }
+ }
+
+ grouping op-header {
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ leaf delay {
+ type op-delay;
+ }
+ leaf session-state {
+ type session-status;
+ }
+ leaf admin-state {
+ type admin-status;
+ }
+ leaf op-type {
+ type enumeration {
+ enum create { value 0; }
+ enum update { value 1; }
+ enum query { value 2; }
+ enum delete { value 3; }
+ }
+ }
+ leaf op-ref-scope {
+ if-feature operation-ref-scope;
+ type fpcagent:ref-scope;
+ }
+ uses fpcagent:instructions;
+ }
+
+ grouping clone-ref {
+ leaf entity {
+ type fpcbase:fpc-identity;
+ }
+ leaf source {
+ type fpcbase:fpc-identity;
+ }
+ }
+
+ identity command-set {
+ description "protocol specific commands";
+ }
+
+ grouping context-operation {
+ uses fpcbase:fpc-context;
+ uses fpcagent:instructions;
+ }
+
+ grouping port-operation {
+ uses fpcbase:fpc-port;
+ uses fpcagent:instructions;
+ }
+
+ // Output Structure
+ grouping payload {
+ list ports {
+ uses fpcagent:port-operation;
+ }
+ list contexts {
+ uses fpcagent:context-operation;
+ }
+ }
+
+ grouping op-input {
+ uses fpcagent:op-header;
+ leaf op-id {
+ type op-identifier;
+ }
+ choice op_body {
+ case create_or_update {
+ list clones {
+ if-feature fpc-cloning;
+ key entity;
+ uses fpcagent:clone-ref;
+ }
+ uses fpcagent:payload;
+ }
+ case delete_or_query {
+ uses fpcbase:targets-value;
+ }
+ }
+ }
+
+ typedef result {
+ type enumeration {
+ enum ok { value 0; }
+ enum err { value 1; }
+ enum ok-notify-follows { value 2; }
+ }
+ }
+
+ identity error-type {
+ description "Base Error Type";
+ }
+ identity name-already-exists {
+ description "Notification that an entity of the same name already exists";
+ }
+
+ typedef error-type-id {
+ description "Integer form of the Error Type";
+ type uint32;
+ }
+
+ grouping op-status-value {
+ leaf op-status {
+ type enumeration {
+ enum ok { value 0; }
+ enum err { value 1; }
+ }
+ }
+ }
+
+ grouping result-body {
+ leaf op-id {
+ type op-identifier;
+ }
+ leaf result {
+ type result;
+ }
+ choice result-type {
+ case err {
+ leaf error-type-id {
+ type fpcagent:error-type-id;
+ }
+ leaf error-info {
+ type string {
+ length "1..1024";
+ }
+ }
+ }
+ case common-success {
+ uses fpcagent:payload;
+ }
+ case delete-success {
+ uses fpcbase:targets-value;
+ }
+ case empty-case {
+ }
+ }
+ }
+
+ grouping result-body-dpn {
+ leaf result {
+ type result;
+ }
+ choice result-type {
+ case err {
+ leaf error-type-id {
+ type fpcagent:error-type-id;
+ }
+ leaf error-info {
+ type string {
+ length "1..1024";
+ }
+ }
+ }
+ case common-delete-success {
+ uses fpcbase:fpc-dpn;
+ }
+ case empty-case {
+ }
+ }
+ }
+
+ typedef dpn-operation {
+ type enumeration {
+ enum add { value 0; }
+ enum remove { value 1; }
+ }
+ }
+
+ grouping dpn-input {
+ leaf abstract-dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf input-dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf operation {
+ type fpcagent:dpn-operation;
+ }
+ }
+
+ // Common RPCs
+ rpc configure-dpn {
+ input {
+ uses fpcagent:dpn-input;
+ }
+ output {
+ uses fpcagent:result-body-dpn;
+ }
+ }
+
+ rpc configure {
+ input {
+ uses fpcagent:op-input;
+ }
+ output {
+ uses fpcagent:result-body;
+ }
+ }
+
+ rpc configure-bundles {
+ if-feature fpcagent:fpc-bundles;
+ input {
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ leaf highest-op-ref-scope {
+ if-feature operation-ref-scope;
+ type fpcagent:ref-scope;
+ }
+ list bundles {
+ key op-id;
+ uses fpcagent:op-input;
+ }
+ }
+ output {
+ list bundles {
+ key op-id;
+ uses fpcagent:result-body;
+ }
+ }
+ }
+
+ // Notification Messages & Structures
+ typedef notification-id {
+ type uint32;
+ }
+
+ grouping notification-header {
+ leaf notification-id {
+ type fpcagent:notification-id;
+ }
+ leaf timestamp {
+ type uint64;
+ }
+ }
+
+ grouping cause-values {
+ leaf cause-value {
+ type uint32;
+ }
+ }
+
+ notification config-result-notification {
+ uses fpcagent:notification-header;
+ choice value {
+ case config-result {
+ uses fpcagent:op-status-value;
+ uses fpcagent:cause-values;
+ uses fpcagent:result-body;
+ }
+ case config-bundle-result {
+ list bundles {
+ uses fpcagent:op-status-value;
+ uses fpcagent:cause-values;
+ uses fpcagent:result-body;
+ }
+ }
+ }
+ }
+
+ rpc event_register {
+ description "Used to register monitoring of parameters/events";
+ input {
+ uses fpcbase:monitor-config;
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ }
+ output {
+ leaf monitor-result {
+ type fpcagent:result;
+ }
+ }
+ }
+
+ rpc event_deregister {
+ description "Used to de-register monitoring of parameters/events";
+ input {
+ list monitors {
+ uses fpcbase:monitor-id;
+ }
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ }
+ output {
+ leaf monitor-result {
+ type fpcagent:result;
+ }
+ }
+ }
+
+ rpc probe {
+ description "Probe the status of a registered monitor";
+ input {
+ uses fpcbase:targets-value;
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ }
+ output {
+ leaf monitor-result {
+ type fpcagent:result;
+ }
+ }
+ }
+
+ grouping dpn-status-value {
+ leaf dpn-status {
+ type enumeration {
+ enum available { value 0; }
+ enum unavailable { value 1; }
+ }
+ }
+ }
+
+ notification notify {
+ uses fpcagent:notification-header;
+ choice value {
+ case dpn-candidate-available {
+ if-feature fpcagent:fpc-auto-binding;
+ leaf candidate-node-id {
+ type inet:uri;
+ }
+ leaf-list access-types {
+ type identityref {
+ base "fpcbase:fpc-access-type";
+ }
+ }
+ leaf-list mobility-profiles {
+ type identityref {
+ base "fpcbase:fpc-mobility-profile-type";
+ }
+ }
+ leaf-list forwarding-plane-roles {
+ type identityref {
+ base "fpcbase:fpc-forwaridingplane-role";
+ }
+ }
+ }
+
+ case dpn-availability {
+ leaf availability-message-type {
+ type string;
+ }
+ uses fpcagent:dpn-status-value;
+ leaf load {
+ description "A percentage value (between 0 and 100) of the system load. This is a combined measurement.";
+ type int8;
+ }
+ uses fpcbase:fpc-dpn;
+ }
+
+ case monitor-notification {
+ choice monitor-notification-value {
+ case simple-monitor {
+ uses fpcbase:report;
+ }
+ case bulk-monitors {
+ list reports {
+ uses fpcbase:report;
+ }
+ }
+ }
+ }
+ // Added as part of the augment issue
+ // TODO - Remove once resolved
+ case downlink-data-notification {
+ leaf notification-message-type {
+ type string;
+ }
+ leaf notification-dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf session-id {
+ type uint64;
+ }
+ leaf client-id {
+ type fpcagent:client-identifier;
+ }
+ leaf op-id {
+ type fpcagent:op-identifier;
+ }
+ }
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-dmm-fpcbase.yang b/models/fpcagent/src/main/yang/ietf-dmm-fpcbase.yang
new file mode 100644
index 0000000..8785850
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-dmm-fpcbase.yang
@@ -0,0 +1,706 @@
+module ietf-dmm-fpcbase {
+ namespace "urn:ietf:params:xml:ns:yang:fpcbase";
+ prefix fpcbase;
+
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+ import ietf-dmm-fpc-pmip { prefix fpc-pmip; revision-date 2016-01-19; }
+ import ietf-traffic-selector-types { prefix traffic-selectors; }
+ import ietf-dmm-fpc-policyext { prefix fpcpolicyext; }
+ import ietf-dmm-threegpp { prefix threegpp; }
+ import ietf-pmip-qos { prefix qos-pmip; }
+
+ organization "IETF DMM Working Group";
+ contact "Satoru Matsushima <satoru.matsushima@g.softbank.co.jp>";
+
+ description
+ "This module contains YANG definition for
+ Forwarding Policy Configuration Protocol.(FPCP)";
+
+ revision 2016-08-03 {
+ description "Changes based on -04 version of FPC draft.";
+ reference "draft-ietf-dmm-fpc-cpdp-04";
+ }
+
+ feature fpc-basic-agent {
+ description "This is an agent co-located with a DPN. In this case
+ only DPN Peer Groups, the DPN Id and Control Protocols are exposed
+ along with the core structures.";
+ }
+ feature fpc-multi-dpn {
+ description "The agent supports multiple DPNs.";
+ }
+
+ typedef fpc-identity {
+ type union {
+ type int64;
+ type string;
+ }
+ }
+
+ grouping target-value {
+ leaf target {
+ type fpc-identity;
+ }
+ }
+
+ grouping targets-value {
+ list targets {
+ key "target";
+ leaf target {
+ type fpc-identity;
+ }
+ leaf-list dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ }
+ }
+
+ // Descriptor Structure
+ typedef fpc-descriptor-id-type {
+ type fpcbase:fpc-identity;
+ description "Descriptor-ID";
+ }
+ identity fpc-descriptor-type {
+ description "A traffic descriptor";
+ }
+ grouping fpc-descriptor-id {
+ leaf descriptor-id {
+ type fpcbase:fpc-identity;
+ }
+ }
+
+ identity pmip-selector-descriptor {
+ base "fpcbase:fpc-descriptor-type";
+ }
+ identity prefix-descriptor {
+ base "fpcbase:fpc-descriptor-type";
+ }
+ identity threegpp-tft-decriptor {
+ base "fpcbase:fpc-descriptor-type";
+ }
+ identity domain-descriptor {
+ base "fpcbase:fpc-descriptor-type";
+ }
+
+ grouping fpc-descriptor {
+ uses fpcbase:fpc-descriptor-id;
+ leaf descriptor-type {
+ mandatory true;
+ type identityref {
+ base "fpc-descriptor-type";
+ }
+ description "Descriptor Type";
+ }
+ choice descriptor-value {
+ case all-traffic {
+ leaf all-traffic {
+ type empty;
+ }
+ }
+ case pmip-selector {
+ uses traffic-selectors:traffic-selector;
+ }
+ case prefix-descriptor {
+ uses fpcpolicyext:prefix-traffic-descriptor;
+ }
+ case threegpp-tft {
+ uses threegpp:tft;
+ }
+ case domain-descriptor {
+ uses fpcpolicyext:domain-descriptor-list;
+ }
+ }
+ }
+
+ // Action Structure
+ typedef fpc-action-id-type {
+ type fpcbase:fpc-identity;
+ description "Action-ID";
+ }
+ identity fpc-action-type {
+ description "Action Type";
+ }
+ grouping fpc-action-id {
+ leaf action-id {
+ type fpcbase:fpc-action-id-type;
+ }
+ }
+
+ identity simple-nat-action {
+ base "fpcbase:fpc-action-type";
+ }
+ identity simple-napt-action {
+ base "fpcbase:fpc-action-type";
+ }
+ identity copy-action {
+ base "fpcbase:fpc-action-type";
+ }
+ identity drop-action {
+ base "fpcbase:fpc-action-type";
+ }
+ identity rate-action {
+ base "fpcbase:fpc-action-type";
+ }
+
+ grouping fpc-action {
+ uses fpcbase:fpc-action-id;
+ leaf action-type {
+ mandatory true;
+ type identityref {
+ base "fpc-action-type";
+ }
+ description "Action Type";
+ }
+ choice action-value {
+ case drop {
+ leaf drop {
+ mandatory true;
+ type empty;
+ }
+ container rate-info{
+ leaf sponsor-identity {
+ type threegpp:sponsor-identity-type;
+ }
+ uses fpcpolicyext:rating-action;
+ }
+ }
+ case simple-nat {
+ uses fpcpolicyext:simple-nat;
+ }
+ case simple-napt {
+ uses fpcpolicyext:simple-napt;
+ }
+ case copy-forward {
+ uses fpcbase:copy-forward;
+ }
+ case rate {
+ leaf sponsor-identity {
+ type threegpp:sponsor-identity-type;
+ }
+ uses fpcpolicyext:rating-action;
+ }
+ }
+ }
+
+ // Rule Structure
+ grouping fpc-rule {
+ description
+ "FPC Rule. When no actions are present the action is DROP.
+ When no Descriptors are empty the default is 'all traffic'.";
+ list descriptors {
+ key descriptor-id;
+ uses fpcbase:fpc-descriptor-id;
+ leaf direction {
+ type fpc-direction;
+ }
+ }
+ list actions {
+ key action-id;
+ leaf order {
+ type uint32;
+ }
+ uses fpcbase:fpc-action-id;
+ }
+ }
+
+ // Policy Structures
+ typedef fpc-policy-id {
+ type fpcbase:fpc-identity;
+ }
+ grouping fpc-policy {
+ leaf policy-id {
+ type fpcbase:fpc-policy-id;
+ }
+ list rules {
+ key order;
+ leaf order {
+ type uint32;
+ }
+ uses fpcbase:fpc-rule;
+ }
+ }
+
+ // Policy Group
+ typedef fpc-policy-group-id {
+ type fpcbase:fpc-identity;
+ }
+ grouping fpc-policy-group {
+ leaf policy-group-id {
+ type fpcbase:fpc-policy-group-id;
+ }
+ leaf-list policies {
+ type fpcbase:fpc-policy-id;
+ }
+ }
+
+ // Mobility Structures
+ // Port Group
+ typedef fpc-port-id {
+ type fpcbase:fpc-identity;
+ }
+ grouping fpc-port {
+ leaf port-id {
+ type fpcbase:fpc-port-id;
+ }
+ leaf-list policy-groups {
+ type fpcbase:fpc-policy-group-id;
+ }
+ }
+
+ // Context Group
+ typedef fpc-context-id {
+ type fpcbase:fpc-identity;
+ }
+ grouping fpc-context-profile {
+ description "A profile that applies to a specific direction";
+ leaf tunnel-local-address {
+ type inet:ip-address;
+ description "Uplink endpoint address of the DPN which agent exists.";
+ }
+ leaf tunnel-remote-address {
+ type inet:ip-address;
+ description "Uplink endpoint address of the DPN which agent exists.";
+ }
+ leaf lifetime {
+ type uint32;
+ }
+ leaf tunnel-mtu-size {
+ type uint32;
+ description "Tunnel MTU size";
+ }
+ container mobility-tunnel-parameters {
+ description "Specifies profile specific uplink tunnel parameters to the DPN which the agent exists. The profiles includes GTP/TEID for 3gpp profile, GRE/Key for ietf-pmip profile, or new profile if anyone will define it.";
+ uses fpcbase:mobility-info;
+ }
+ container nexthop {
+ uses fpcbase:fpc-nexthop;
+ }
+ container qos-profile-parameters {
+ uses fpcbase:fpc-qos-profile;
+ }
+ container dpn-parameters {
+ }
+ list vendor-parameters {
+ key "vendor-id vendor-type";
+ uses fpcbase:vendor-attributes;
+ }
+ }
+
+ typedef fpc-direction {
+ type enumeration {
+ enum uplink;
+ enum downlink;
+ }
+ }
+
+ grouping fpc-context {
+ leaf context-id {
+ type fpcbase:fpc-context-id;
+ }
+ leaf dormant {
+ type boolean;
+ }
+ leaf-list ports {
+ type fpcbase:fpc-port-id;
+ }
+ leaf dpn-group {
+ type fpcbase:fpc-dpn-group-id;
+ }
+ leaf-list delegating-ip-prefixes {
+ type inet:ip-prefix;
+ }
+ container ul {
+ if-feature fpcbase:fpc-basic-agent;
+ uses fpcbase:fpc-context-profile;
+ }
+ container dl {
+ if-feature fpcbase:fpc-basic-agent;
+ uses fpcbase:fpc-context-profile;
+ }
+ list dpns {
+ if-feature fpcbase:fpc-multi-dpn;
+ key "dpn-id direction";
+ leaf dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf direction {
+ mandatory true;
+ type fpcbase:fpc-direction;
+ }
+ uses fpcbase:fpc-context-profile;
+ }
+ leaf parent-context {
+ type fpcbase:fpc-context-id;
+ }
+ uses threegpp:threegpp-properties;
+ }
+
+ // Mobility (Tunnel) Information
+ grouping mobility-info {
+ choice mobprofile-parameters {
+ case nothing {
+ leaf none {
+ type empty;
+ }
+ }
+ case pmip-tunnel {
+ uses fpc-pmip:pmip-mobility;
+ choice pmiptunnel-or-ref {
+ case defined-selector {
+ uses traffic-selectors:traffic-selector;
+ }
+ case predefined-selector {
+ leaf selector-reference {
+ type fpcbase:fpc-identity;
+ }
+ }
+ }
+ }
+ case threegpp-tunnel {
+ uses threegpp:threeGPP-tunnel;
+ choice tft-or-ref {
+ case defined-tft {
+ uses threegpp:tft;
+ }
+ case predefined-tft {
+ leaf tft-reference {
+ type fpcbase:fpc-identity;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Next Hop Structures
+ typedef fpcp-service-path-id {
+ type uint32 {
+ range "0..33554431";
+ }
+ description "SERVICE_PATH_ID";
+ }
+
+ identity fpc-nexthop-type {
+ description "Next Hop Type";
+ }
+ identity fpc-nexthop-ip {
+ base "fpcbase:fpc-nexthop-type";
+ }
+ identity fpc-nexthop-servicepath {
+ base "fpcbase:fpc-nexthop-type";
+ }
+ grouping fpc-nexthop {
+ leaf nexthop-type {
+ type identityref {
+ base "fpcbase:fpc-nexthop-type";
+ }
+ }
+ choice nexthop-value {
+ case ip {
+ leaf ip {
+ type inet:ip-address;
+ }
+ }
+ case servicepath {
+ leaf servicepath {
+ type fpcbase:fpcp-service-path-id;
+ }
+ }
+ }
+ }
+
+ // QoS Information
+ identity fpc-qos-type {
+ description "Base identity from which specific uses of QoS types are derived.";
+ }
+ grouping fpc-qos-profile {
+ leaf qos-type {
+ type identityref {
+ base fpcbase:fpc-qos-type;
+ }
+ description "the profile type";
+ }
+ choice value {
+ case qos-pmip {
+ uses qos-pmip:qosattribute;
+ }
+ case threegpp-qos {
+ uses threegpp:threeGPP-QoS;
+ }
+ }
+ }
+
+ // Vendor Specific Attributes
+ identity vendor-specific-type {
+ description "Vendor Specific Attribute Type";
+ }
+ grouping vendor-attributes {
+ leaf vendor-id {
+ type fpcbase:fpc-identity;
+ }
+ leaf vendor-type {
+ type identityref {
+ base "fpcbase:vendor-specific-type";
+ }
+ }
+ choice value {
+ case empty-type {
+ leaf empty-type {
+ type empty;
+ }
+ }
+ }
+ }
+
+ // Topology
+ typedef fpc-domain-id {
+ type fpcbase:fpc-identity;
+ }
+ grouping fpc-domain {
+ leaf domain-id {
+ type fpcbase:fpc-domain-id;
+ }
+ leaf domain-name {
+ type string;
+ }
+ leaf domain-type {
+ type string;
+ }
+ }
+
+ typedef fpc-dpn-id {
+ type fpcbase:fpc-identity;
+ description "DPN Identifier";
+ }
+ identity fpc-dpn-control-protocol {
+ description "DPN Control Protocol";
+ }
+ grouping fpc-dpn {
+ leaf dpn-id {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf dpn-name {
+ type string;
+ }
+ leaf-list dpn-groups {
+ type fpcbase:fpc-dpn-group-id;
+ }
+ leaf node-reference {
+ type instance-identifier;
+ }
+ leaf abstract {
+ type boolean;
+ }
+ leaf strategy {
+ type string;
+ }
+ leaf-list dpn-ids {
+ type fpcbase:fpc-dpn-id;
+ }
+ leaf node-id {
+ type string;
+ }
+ leaf network-id {
+ type string;
+ }
+ }
+
+ typedef fpc-dpn-group-id {
+ type fpcbase:fpc-identity;
+ description "DPN Group Identifier";
+ }
+ identity fpc-forwaridingplane-role {
+ description "Role of DPN Group in the Forwarding Plane";
+ }
+ identity fpc-access-type {
+ description "Access Type of the DPN Group";
+ }
+ identity fpc-mobility-profile-type {
+ description "Mobility Profile Type";
+ }
+
+ grouping fpc-dpn-peer-group {
+ leaf remote-dpn-group-id {
+ type fpcbase:fpc-dpn-group-id;
+ }
+ leaf remote-mobility-profile {
+ type identityref {
+ base "fpcbase:fpc-mobility-profile-type";
+ }
+ }
+ leaf remote-data-plane-role {
+ type identityref {
+ base "fpcbase:fpc-forwaridingplane-role";
+ }
+ }
+ leaf remote-endpoint-address {
+ type inet:ip-address;
+ }
+ leaf local-endpoint-address {
+ type inet:ip-address;
+ }
+ leaf tunnel-mtu-size {
+ type uint32;
+ }
+ }
+
+ // Events, Probes & Notifications
+ identity event-type {
+ description "Base Event Type";
+ }
+
+ typedef event-type-id {
+ type uint32;
+ }
+
+ grouping monitor-id {
+ leaf monitor-id {
+ type fpcbase:fpc-identity;
+ }
+ }
+
+ identity report-type {
+ description "Type of Report";
+ }
+ identity periodic-report {
+ base "fpcbase:report-type";
+ }
+ identity threshold-report {
+ base "fpcbase:report-type";
+ }
+ identity scheduled-report {
+ base "fpcbase:report-type";
+ }
+ identity events-report {
+ base "fpcbase:report-type";
+ }
+
+ grouping report-config {
+ choice event-config-value {
+ case periodic-config {
+ leaf period {
+ type uint32;
+ }
+ }
+ case threshold-config {
+ leaf lo-thresh {
+ type uint32;
+ }
+ leaf hi-thresh {
+ type uint32;
+ }
+ }
+ case scheduled-config {
+ leaf report-time {
+ type uint32;
+ }
+ }
+ case events-config-ident {
+ leaf-list event-identities {
+ type identityref {
+ base "fpcbase:event-type";
+ }
+ }
+ }
+ case events-config {
+ leaf-list event-ids {
+ type uint32;
+ }
+ }
+ }
+ }
+
+ grouping monitor-config {
+ uses fpcbase:monitor-id;
+ uses fpcbase:target-value;
+ uses fpcbase:report-config;
+ }
+
+ grouping report {
+ uses fpcbase:monitor-config;
+ choice report-value {
+ leaf trigger {
+ type fpcbase:event-type-id;
+ }
+ case simple-empty {
+ leaf nothing {
+ type empty;
+ }
+ }
+ case simple-val32 {
+ leaf val32 {
+ type uint32;
+ }
+ }
+ case any-data {
+ leaf data {
+ type string;
+ }
+ }
+ }
+ }
+
+ // PMIP Identities
+ identity ietf-pmip-access-type {
+ base "fpcbase:fpc-access-type";
+ }
+
+ identity fpcp-qos-index-pmip {
+ base "fpcbase:fpc-qos-type";
+ }
+ identity traffic-selector-mip6 {
+ base "fpcbase:fpc-descriptor-type";
+ }
+ identity ietf-pmip {
+ base "fpcbase:fpc-mobility-profile-type";
+ }
+
+ // Threegpp
+ identity threeGPP-qos-profile-parameters {
+ base "fpcbase:fpc-qos-type";
+ }
+
+ identity threeGPP-access-type {
+ base "fpcbase:fpc-access-type";
+ }
+
+ // Profile Type
+ identity threeGPP-mobility {
+ base "fpcbase:fpc-mobility-profile-type";
+ }
+
+ // Policy Extensions
+ identity service-function {
+ base "fpcbase:fpc-descriptor-type";
+ description "Base Identifier for Service Functions.";
+ }
+
+ identity napt-service {
+ base "service-function";
+ }
+
+ identity nat-service {
+ base "service-function";
+ }
+
+ identity copy-forward {
+ base "fpcbase:fpc-descriptor-type";
+ description "Copies a packet then forwards to a specific destination";
+ }
+ grouping copy-forward {
+ container destination {
+ choice value {
+ case port-ref {
+ leaf port-ref {
+ type fpcbase:fpc-port-id;
+ }
+ }
+ case context-ref {
+ leaf context-ref {
+ type fpcbase:fpc-context-id;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-dmm-threegpp.yang b/models/fpcagent/src/main/yang/ietf-dmm-threegpp.yang
new file mode 100644
index 0000000..1439224
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-dmm-threegpp.yang
@@ -0,0 +1,330 @@
+module ietf-dmm-threegpp {
+ namespace "urn:ietf:params:xml:ns:yang:threegpp";
+ prefix threegpp;
+
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+ import ietf-traffic-selector-types { prefix traffic-selectors; revision-date 2016-01-14; }
+ import ietf-pmip-qos { prefix pmipqos; revision-date 2016-02-10; }
+
+
+ organization "IETF DMM Working Group";
+ contact "Satoru Matsushima <satoru.matsushima@g.softbank.co.jp>";
+
+ description
+ "This module contains YANG definition for
+ 3GPP Related Mobility Structures";
+
+ revision 2016-08-03 {
+ description "Initial";
+ reference "draft-ietf-dmm-fpc-cpdp-04";
+ }
+
+ // Tunnel Types
+ identity threeGPP-tunnel-type {
+ description "Base Tunnel Type";
+ }
+
+ identity gtpv1 {
+ base "threegpp:threeGPP-tunnel-type";
+ }
+
+ identity gtpv2 {
+ base "threegpp:threeGPP-tunnel-type";
+ }
+
+ grouping teid-value {
+ leaf tunnel-identifier {
+ description "TEID";
+ type uint32;
+ }
+ }
+
+ grouping threeGPP-tunnel {
+ leaf tunnel-type {
+ type identityref {
+ base "threegpp:threeGPP-tunnel-type";
+ }
+ }
+ uses threegpp:teid-value;
+ }
+
+ // QoS Profile
+ typedef fpc-qos-class-identifier {
+ type uint8 {
+ range "1..9";
+ }
+ description "QCI";
+ }
+
+ grouping threeGPP-QoS {
+ leaf qci {
+ type fpc-qos-class-identifier;
+ }
+ leaf gbr {
+ type uint32;
+ }
+ leaf mbr {
+ type uint32;
+ }
+ leaf apn-ambr {
+ type uint32;
+ }
+ leaf ue-ambr {
+ type uint32;
+ }
+ container arp {
+ uses pmipqos:Allocation-Retention-Priority-Value;
+ }
+ }
+
+ typedef ebi-type {
+ type uint8 {
+ range "0..15";
+ }
+ }
+
+ // From 3GPP TS 24.008 version 13.5.0 Release 13
+ typedef component-type-enum {
+ type enumeration {
+ enum ipv4RemoteAddress { value 16; }
+ enum ipv4LocalAddress { value 17; }
+ enum ipv6RemoteAddress { value 32; }
+ enum ipv6RemoteAddressPrefix { value 33; }
+ enum ipv6LocalAddressPrefix { value 35; }
+ enum protocolNextHeader { value 48; }
+ enum localPort { value 64; }
+ enum localPortRange { value 65; }
+ enum reomotePort { value 80; }
+ enum remotePortRange { value 81; }
+ enum secParamIndex { value 96; }
+ enum tosTraffClass { value 112; }
+ enum flowLabel { value 128; }
+ }
+ }
+
+ typedef packet-filter-direction {
+ type enumeration {
+ enum preRel7Tft { value 0; }
+ enum uplink { value 1; }
+ enum downlink { value 2; }
+ enum bidirectional { value 3; }
+ }
+ }
+
+ typedef component-type-id {
+ type uint8 {
+ range "16 | 17 | 32 | 33 | 35 | 48 | 64 | 65 | 80 | 81 | 96 | 112 | 128";
+ }
+ }
+
+ typedef sponsor-identity-type {
+ type string;
+ }
+
+ grouping packet-filter {
+ leaf direction {
+ type threegpp:packet-filter-direction;
+ }
+ leaf identifier {
+ type uint8 {
+ range "1..15";
+ }
+ }
+ leaf evaluation-precedence {
+ type uint8;
+ }
+ list contents {
+ key component-type-identifier;
+ leaf component-type-identifier {
+ type threegpp:component-type-id;
+ }
+ choice value {
+ case ipv4-local {
+ leaf ipv4-local {
+ type inet:ipv4-address;
+ }
+ leaf ipv4-local-mask {
+ type inet:ipv4-address;
+ }
+ }
+ case ipv6-address-local {
+ leaf ipv6-address-local {
+ type inet:ipv6-prefix;
+ }
+ leaf ipv6-address-local-mask {
+ type inet:ipv6-prefix;
+ }
+ }
+ case ipv6-prefix-local {
+ leaf ipv6-prefix-local {
+ type inet:ipv6-prefix;
+ }
+ }
+
+ case ipv4-ipv6-remote {
+ leaf ipv4-ipv6-remote {
+ type inet:ip-address;
+ }
+ leaf ipv4-ipv6-remote-mask {
+ type inet:ip-address;
+ }
+ }
+
+ case ipv4-remote {
+ leaf ipv4-remote {
+ type inet:ipv4-address;
+ }
+ leaf ipv4-remote-mask {
+ type inet:ipv4-address;
+ }
+ }
+ case ipv6-address-remote {
+ leaf ipv6-address-remote {
+ type inet:ipv6-prefix;
+ }
+ leaf ipv6-address-remote-mask {
+ type inet:ipv6-prefix;
+ }
+ }
+ case ipv6-prefix-remote {
+ leaf ipv6-prefix-remote {
+ type inet:ipv6-prefix;
+ }
+ }
+
+ case protocol-next-header {
+ leaf next-header {
+ type uint8;
+ }
+ }
+
+ case local-port {
+ leaf local-port {
+ type inet:port-number;
+ }
+ }
+ case local-port-range {
+ leaf local-port-lo {
+ type inet:port-number;
+ }
+ leaf local-port-hi {
+ type inet:port-number;
+ }
+ }
+ case remote-port {
+ leaf remote-port {
+ type inet:port-number;
+ }
+ }
+ case remote-port-range {
+ leaf remote-port-lo {
+ type inet:port-number;
+ }
+ leaf remote-port-hi {
+ type inet:port-number;
+ }
+ }
+ case ipsec-index {
+ leaf ipsec-index {
+ type traffic-selectors:ipsec-spi;
+ }
+ }
+ case traffic-class {
+ leaf traffic-class {
+ type inet:dscp;
+ }
+ }
+ case traffic-class-range {
+ leaf traffic-class-lo {
+ type inet:dscp;
+ }
+ leaf traffic-class-hi {
+ type inet:dscp;
+ }
+ }
+ case flow-label-type {
+ leaf-list flow-label-type {
+ type inet:ipv6-flow-label;
+ }
+ }
+ }
+ }
+ }
+
+ grouping tft {
+ list packet-filters {
+ key identifier;
+ uses threegpp:packet-filter;
+ }
+ }
+
+ typedef imsi-type {
+ type uint64;
+ }
+
+ typedef threegpp-instr {
+ description "Instruction Set for 3GPP R11";
+ type bits {
+ bit assign-ip {
+ position 0;
+ }
+ bit assign-fteid-ip {
+ position 1;
+ }
+ bit assign-fteid-teid {
+ position 2;
+ }
+ bit session {
+ position 3;
+ }
+ bit uplink {
+ position 4;
+ }
+ bit downlink {
+ position 5;
+ }
+ bit assign-dpn {
+ position 6;
+ }
+ bit indirect-forward {
+ position 7;
+ }
+ bit create_new_tft {
+ position 8;
+ }
+ bit delete_existing_tft {
+ position 9;
+ }
+ bit add_filters_to_existing_tft {
+ position 10;
+ }
+ bit replace_filters_in_existing_tft {
+ position 11;
+ }
+ bit delete_filters_from_existing_tft {
+ position 12;
+ }
+ bit no_tft_op {
+ position 13;
+ }
+ }
+ }
+
+ grouping threegpp-properties {
+ leaf imsi {
+ type threegpp:imsi-type;
+ }
+ leaf ebi {
+ type threegpp:ebi-type;
+ }
+ leaf lbi {
+ type threegpp:ebi-type;
+ }
+ }
+
+ grouping threegpp-commandset {
+ leaf instr-3gpp-mob {
+ type threegpp:threegpp-instr;
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-pmip-qos.yang b/models/fpcagent/src/main/yang/ietf-pmip-qos.yang
new file mode 100644
index 0000000..4a22355
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-pmip-qos.yang
@@ -0,0 +1,564 @@
+module ietf-pmip-qos {
+ yang-version 1;
+
+ namespace
+ "urn:ietf:params:xml:ns:yang:ietf-pmip-qos";
+
+ prefix "qos-pmip";
+
+ import ietf-inet-types {
+ prefix inet;
+ revision-date 2013-07-15;
+ }
+ import ietf-traffic-selector-types { prefix traffic-selectors; }
+
+ organization
+ "IETF DMM (Dynamic Mobility Management) Working Group";
+
+ contact
+ "WG Web: <https://datatracker.ietf.org/wg/dmm/>
+ WG List: <mailto:dmm@ietf.org>
+
+ WG Chair: Dapeng Liu
+ <mailto:maxpassion@gmail.com>
+
+ WG Chair: Jouni Korhonen
+ <mailto:jouni.nospam@gmail.com>
+
+ Editor:
+ <mailto:>";
+
+ description
+ "This module contains a collection of YANG definitions for
+ quality of service paramaters used in Proxy Mobile IPv6.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module was created as part of the IETF
+ DMM FPC YANG modules; see the RFC itself for full legal notices.";
+
+ revision 2016-02-10 {
+ description "Initial revision";
+ reference
+ "RFC 7222: Quality-of-Service Option for Proxy Mobile IPv6";
+ }
+
+ // Type Definitions
+
+ // QoS Option Field Type Definitions
+ typedef sr-id {
+ type uint8;
+ description
+ "An 8-bit unsigned integer used
+ for identifying the QoS Service Request. Its uniqueness is within
+ the scope of a mobility session. The local mobility anchor always
+ allocates the Service Request Identifier. When a new QoS Service
+ Request is initiated by a mobile access gateway, the Service
+ Request Identifier in the initial request message is set to a
+ value of (0), and the local mobility anchor allocates a Service
+ Request Identifier and includes it in the response. For any new
+ QoS Service Requests initiated by a local mobility anchor, the
+ Service Request Identifier is set to the allocated value.";
+ }
+
+ typedef traffic-class {
+ type inet:dscp;
+ description
+ "Traffic Class consists of a 6-bit DSCP field followed by a 2-bit
+ reserved field.";
+ reference
+ "RFC 3289: Management Information Base for the Differentiated
+ Services Architecture
+ RFC 2474: Definition of the Differentiated Services Field
+ (DS Field) in the IPv4 and IPv6 Headers
+ RFC 2780: IANA Allocation Guidelines For Values In
+ the Internet Protocol and Related Headers";
+ }
+
+ typedef operational-code {
+ type enumeration {
+ enum RESPONSE { value 0; }
+ enum ALLOCATE { value 1; }
+ enum DE-ALLOCATE { value 2; }
+ enum MODIFY { value 3; }
+ enum QUERY { value 4; }
+ enum NEGOTIATE { value 5; }
+ }
+ description
+ "1-octet Operational code indicates the type of QoS request.
+
+ RESPONSE: (0)
+ Response to a QoS request
+
+ ALLOCATE: (1)
+ Request to allocate QoS resources
+
+ DE-ALLOCATE: (2)
+ Request to de-Allocate QoS resources
+
+ MODIFY: (3)
+ Request to modify QoS parameters for a previously negotiated
+ QoS Service Request
+
+ QUERY: (4)
+ Query to list the previously negotiated QoS Service Requests
+ that are still active
+
+ NEGOTIATE: (5)
+ Response to a QoS Service Request with a counter QoS proposal
+
+ Reserved: (6) to (255)
+ Currently not used. Receiver MUST ignore the option received
+ with any value in this range.";
+ }
+
+ // QoS Attribute Types
+
+ //The enumeration value for mapping - don't confuse with the identities
+ typedef qos-attrubite-type-enum {
+ type enumeration {
+ enum Reserved { value 0; }
+ enum Per-MN-Agg-Max-DL-Bit-Rate { value 1; }
+ enum Per-MN-Agg-Max-UL-Bit-Rate { value 2; }
+ enum Per-Session-Agg-Max-DL-Bit-Rate { value 3; }
+ enum Per-Session-Agg-Max-UL-Bit-Rate { value 4; }
+ enum Allocation-Retention-Priority { value 5; }
+ enum Aggregate-Max-DL-Bit-Rate { value 6; }
+ enum Aggregate-Max-UL-Bit-Rate { value 7; }
+ enum Guaranteed-DL-Bit-Rate { value 8; }
+ enum Guaranteed-UL-Bit-Rate { value 9; }
+ enum QoS-Traffic-Selector { value 10; }
+ enum QoS-Vendor-Specific-Attribute { value 11; }
+ }
+ description
+ "8-bit unsigned integer indicating the type of the QoS
+ attribute. This specification reserves the following values.
+ (0) - Reserved
+ This value is reserved and cannot be used
+
+ (1) - Per-MN-Agg-Max-DL-Bit-Rate
+ Per-Mobile-Node Aggregate Maximum Downlink Bit Rate.
+
+ (2) - Per-MN-Agg-Max-UL-Bit-Rate
+ Per-Mobile-Node Aggregate Maximum Uplink Bit Rate.
+
+ (3) - Per-Session-Agg-Max-DL-Bit-Rate
+ Per-Mobility-Session Aggregate Maximum Downlink Bit Rate.
+
+ (4) - Per-Session-Agg-Max-UL-Bit-Rate
+ Per-Mobility-Session Aggregate Maximum Uplink Bit Rate.
+
+ (5) - Allocation-Retention-Priority
+ Allocation and Retention Priority.
+
+ (6) - Aggregate-Max-DL-Bit-Rate
+ Aggregate Maximum Downlink Bit Rate.
+
+ (7) - Aggregate-Max-UL-Bit-Rate
+ Aggregate Maximum Uplink Bit Rate.
+
+ (8) - Guaranteed-DL-Bit-Rate
+ Guaranteed Downlink Bit Rate.
+
+ (9) - Guaranteed-UL-Bit-Rate
+ Guaranteed Uplink Bit Rate.
+
+ (10) - QoS-Traffic-Selector
+ QoS Traffic Selector.
+
+ (11) - QoS-Vendor-Specific-Attribute
+ QoS Vendor-Specific Attribute.
+
+ (12) to (254) - Reserved
+ These values are reserved for future allocation.
+
+ (255) - Reserved
+ This value is reserved and cannot be used.";
+ }
+
+ // Attribute Type as Identities
+ // Added for convenience of inclusion and extension in other YANG modules.
+ identity qos-attribute-type {
+ description
+ "Base type for Quality of Service Attributes";
+ }
+
+ identity Per-MN-Agg-Max-DL-Bit-Rate-type {
+ base qos-attribute-type;
+ description
+ "Per-Mobile-Node Aggregate Maximum Downlink Bit Rate.";
+ }
+
+ identity Per-MN-Agg-Max-UL-Bit-Rate-type {
+ base qos-attribute-type;
+ description
+ "Per-Mobile-Node Aggregate Maximum Uplink Bit Rate";
+ }
+
+ identity Per-Session-Agg-Max-DL-Bit-Rate-type {
+ base qos-attribute-type;
+ description
+ "Per-Mobility-Session Aggregate Maximum Downlink Bit Rate.";
+ }
+
+ identity Per-Session-Agg-Max-UL-Bit-Rate-type {
+ base qos-attribute-type;
+ description
+ "Per-Mobility-Session Aggregate Maximum Uplink Bit Rate.";
+ }
+
+ identity Allocation-Retention-Priority-type {
+ base qos-attribute-type;
+ description
+ "Allocation and Retention Priority.";
+ }
+
+ identity Aggregate-Max-DL-Bit-Rate-type {
+ base qos-attribute-type;
+ description "Aggregate Maximum Downlink Bit Rate.";
+ }
+
+ identity Aggregate-Max-UL-Bit-Rate-type {
+ base qos-attribute-type;
+ description "Aggregate Maximum Uplink Bit Rate.";
+ }
+
+ identity Guaranteed-DL-Bit-Rate-type {
+ base qos-attribute-type;
+ description "Guaranteed Downlink Bit Rate.";
+ }
+
+ identity Guaranteed-UL-Bit-Rate-type {
+ base qos-attribute-type;
+ description "Guaranteed Uplink Bit Rate.";
+ }
+
+ identity QoS-Traffic-Selector-type {
+ base qos-attribute-type;
+ description "QoS Traffic Selector.";
+ }
+
+ identity QoS-Vendor-Specific-Attribute-type {
+ base qos-attribute-type;
+ description "QoS Vendor-Specific Attribute.";
+ }
+
+ //value definitions
+ typedef Per-MN-Agg-Max-DL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the aggregate maximum downlink bit rate that is
+ requested/allocated for all the mobile node's IP flows. The
+ measurement units for Per-MN-Agg-Max-DL-Bit-Rate are bits per
+ second.";
+ }
+
+ typedef Per-MN-Agg-Max-UL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the aggregate maximum uplink bit rate that is requested/
+ allocated for the mobile node's IP flows. The measurement units
+ for Per-MN-Agg-Max-UL-Bit-Rate are bits per second.";
+ }
+
+ // Generic Structure for the uplink and downlink
+ grouping Per-Session-Agg-Max-Bit-Rate-Value {
+ leaf max-rate {
+ type uint32;
+ mandatory true;
+ description
+ "This is a 32-bit unsigned integer
+ that indicates the aggregate maximum bit rate that is requested/allocated
+ for all the IP flows associated with that mobility session. The measurement
+ units for Per-Session-Agg-Max-UL/DL-Bit-Rate are bits per second.";
+ }
+ leaf service-flag {
+ type boolean;
+ mandatory true;
+ description
+ "This flag is used for extending the scope of the
+ target flows for Per-Session-Agg-Max-UL/DL-Bit-Rate from(UL)/to(DL) the mobile
+ node's other mobility sessions sharing the same Service
+ Identifier. 3GPP Access Point Name (APN) is an example of a
+ Service Identifier, and that identifier is carried using the
+ Service Selection mobility option [RFC5149].
+
+ * When the (S) flag is set to a value of (1), then the Per-
+ Session-Agg-Max-Bit-Rate is measured as an aggregate across
+ all the mobile node's other mobility sessions sharing the same
+ Service Identifier associated with this mobility session.
+
+ * When the (S) flag is set to a value of (0), then the target
+ flows are limited to the current mobility session.
+
+ * The (S) flag MUST NOT be set to a value of (1) when there is no
+ Service Identifier associated with the mobility session.";
+ reference
+ "RFC 5149 - Service Selection mobility option";
+ }
+ leaf exclude-flag {
+ type boolean;
+ mandatory true;
+ description
+ "This flag is used to request that the uplink/downlink
+ flows for which the network is providing Guaranteed-Bit-Rate
+ service be excluded from the target IP flows for which Per-
+ Session-Agg-Max-UL/DL-Bit-Rate is measured.
+
+ * When the (E) flag is set to a value of (1), then the request is
+ to exclude the IP flows for which Guaranteed-UL/DL-Bit-Rate
+ is negotiated from the flows for which Per-Session-Agg-Max-UL/DL-Bit-Rate
+ is measured.
+
+ * When the (E) flag is set to a value of (0), then the request is
+ not to exclude any IP flows from the target IP flows for which
+ Per-Session-Agg-Max-UL/DL-Bit-Rate is measured.
+
+ * When the (S) flag and (E) flag are both set to a value of (1),
+ then the request is to exclude all the IP flows sharing the
+ Service Identifier associated with this mobility session from
+ the target flows for which Per-Session-Agg-Max-UL/DL-Bit-Rate is
+ measured.";
+ }
+ }
+
+ grouping Allocation-Retention-Priority-Value {
+ leaf prioirty-level {
+ type uint8 {
+ range "0..15";
+ }
+ mandatory true;
+ description
+ "This is a 4-bit unsigned integer value. It
+ is used to decide whether a mobility session establishment or
+ modification request can be accepted; this is typically used for
+ admission control of Guaranteed Bit Rate traffic in case of
+ resource limitations. The priority level can also be used to
+
+ decide which existing mobility session to preempt during resource
+ limitations. The priority level defines the relative timeliness
+ of a resource request.
+
+ Values 1 to 15 are defined, with value 1 as the highest level of
+ priority.
+
+ Values 1 to 8 should only be assigned for services that are
+ authorized to receive prioritized treatment within an operator
+ domain. Values 9 to 15 may be assigned to resources that are
+ authorized by the home network and thus applicable when a mobile
+ node is roaming.";
+ }
+ leaf premption-capability {
+ type enumeration {
+ enum enabled { value 0; }
+ enum disabled { value 1; }
+ enum reserved1 { value 2; }
+ enum reserved2 { value 3; }
+ }
+ mandatory true;
+ description
+ "This is a 2-bit unsigned integer
+ value. It defines whether a service data flow can get resources
+ that were already assigned to another service data flow with a
+ lower priority level. The following values are defined:
+
+ Enabled (0): This value indicates that the service data flow is
+ allowed to get resources that were already assigned to another
+ IP data flow with a lower priority level.
+
+ Disabled (1): This value indicates that the service data flow
+ is not allowed to get resources that were already assigned to
+ another IP data flow with a lower priority level. The values
+ (2) and (3) are reserved.";
+ }
+ leaf premption-vulnerability {
+ type enumeration {
+ enum enabled { value 0; }
+ enum disabled { value 1; }
+ enum reserved1 { value 2; }
+ enum reserved2 { value 3; }
+ }
+ mandatory true;
+ description
+ "This is a 2-bit unsigned integer
+ value. It defines whether a service data flow can lose the
+ resources assigned to it in order to admit a service data flow
+ with a higher priority level. The following values are defined:
+
+ Enabled (0): This value indicates that the resources assigned
+ to the IP data flow can be preempted and allocated to a service
+ data flow with a higher priority level.
+
+ Disabled (1): This value indicates that the resources assigned
+ to the IP data flow shall not be preempted and allocated to a
+ service data flow with a higher priority level. The values (2)
+ and (3) are reserved.";
+ }
+ }
+
+ typedef Aggregate-Max-DL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the aggregate maximum downlink bit rate that is
+ requested/allocated for downlink IP flows. The measurement units
+ for Aggregate-Max-DL-Bit-Rate are bits per second.";
+ }
+
+ typedef Aggregate-Max-UL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the aggregate maximum downlink bit rate that is
+ requested/allocated for downlink IP flows. The measurement units
+ for Aggregate-Max-DL-Bit-Rate are bits per second.";
+ }
+
+ typedef Guaranteed-DL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the guaranteed bandwidth in bits per second for downlink
+ IP flows. The measurement units for Guaranteed-DL-Bit-Rate are
+ bits per second.";
+ }
+
+ typedef Guaranteed-UL-Bit-Rate-Value {
+ type uint32;
+ description
+ "This is a 32-bit unsigned integer that
+ indicates the guaranteed bandwidth in bits per second for uplink
+ IP flows. The measurement units for Guaranteed-UL-Bit-Rate are
+ bits per second.";
+ }
+
+ grouping QoS-Vendor-Specific-Attribute-Value-Base {
+ leaf vendorid {
+ type uint32;
+ mandatory true;
+ description
+ "The Vendor ID is the SMI (Structure of Management
+ Information) Network Management Private Enterprise Code of the
+ IANA-maintained 'Private Enterprise Numbers' registry [SMI].";
+ reference
+ "'PRIVATE ENTERPRISE NUMBERS', SMI Network Management
+ Private Enterprise Codes, April 2014,
+ <http://www.iana.org/assignments/enterprise-numbers>";
+ }
+ leaf subtype {
+ type uint8;
+ mandatory true;
+ description
+ "An 8-bit field indicating the type of vendor-specific
+ information carried in the option. The namespace for this sub-
+ type is managed by the vendor identified by the Vendor ID field.";
+ }
+ description
+ "QoS Vendor-Specific Attribute.";
+ }
+
+ //NOTE - We do NOT add the Status Codes or other changes in PMIP in this module
+
+ //Primary Structures (groupings)
+ grouping qosattribute {
+ leaf attributetype {
+ type identityref {
+ base qos-attribute-type;
+ }
+ mandatory true;
+ description "the attribute type";
+ }
+
+ //All of the sub-types by constraint
+ choice attribute-choice {
+ case per-mn-agg-max-dl-case {
+ when "../attributetype = 'Per-MN-Agg-Max-DL-Bit-Rate-type'";
+ leaf per-mn-agg-max-dl {
+ type qos-pmip:Per-MN-Agg-Max-DL-Bit-Rate-Value;
+ }
+ }
+ case per-mn-agg-max-ul-case {
+ when "../attributetype = 'Per-MN-Agg-Max-UL-Bit-Rate-type'";
+ leaf per-mn-agg-max-ul {
+ type qos-pmip:Per-MN-Agg-Max-UL-Bit-Rate-Value;
+ }
+ }
+ case per-session-agg-max-dl-case {
+ when "../attributetype = 'Per-Session-Agg-Max-DL-Bit-Rate-type'";
+ container per-session-agg-max-dl {
+ uses qos-pmip:Per-Session-Agg-Max-Bit-Rate-Value;
+ }
+ }
+ case per-session-agg-max-ul-case {
+ when "../attributetype = 'Per-Session-Agg-Max-UL-Bit-Rate-type'";
+ container per-session-agg-max-ul {
+ uses qos-pmip:Per-Session-Agg-Max-Bit-Rate-Value;
+ }
+ }
+ case allocation-retention-priority-case {
+ when "../attributetype = 'Allocation-Retention-Priority-type'";
+ uses qos-pmip:Allocation-Retention-Priority-Value;
+ }
+ case agg-max-dl-case {
+ when "../attributetype = 'Aggregate-Max-DL-Bit-Rate-type'";
+ leaf agg-max-dl {
+ type qos-pmip:Aggregate-Max-DL-Bit-Rate-Value;
+ }
+ }
+ case agg-max-ul-case {
+ when "../attributetype = 'Aggregate-Max-UL-Bit-Rate-type'";
+ leaf agg-max-ul {
+ type qos-pmip:Aggregate-Max-UL-Bit-Rate-Value;
+ }
+ }
+ case gbr-dl-case {
+ when "../attributetype = 'Guaranteed-DL-Bit-Rate-type'";
+ leaf gbr-dl {
+ type qos-pmip:Guaranteed-DL-Bit-Rate-Value;
+ }
+ }
+ case gbr-ul-case {
+ when "../attributetype = 'Guaranteed-UL-Bit-Rate-type'";
+ leaf gbr-ul {
+ type qos-pmip:Guaranteed-UL-Bit-Rate-Value;
+ }
+ }
+ case traffic-selector-case {
+ when "../attributetype = 'QoS-Traffic-Selector-type'";
+ container traffic-selector {
+ uses traffic-selectors:traffic-selector;
+ }
+ }
+ }
+ }
+
+ grouping qosoption {
+ leaf srid {
+ type sr-id;
+ mandatory true;
+ }
+ leaf trafficclass {
+ type traffic-class;
+ mandatory true;
+ }
+ leaf operationcode {
+ type operational-code;
+ mandatory true;
+ }
+ list attributes {
+ unique "attributetype";
+ uses qosattribute;
+ min-elements 1;
+ }
+ }
+}
diff --git a/models/fpcagent/src/main/yang/ietf-traffic-selector-types.yang b/models/fpcagent/src/main/yang/ietf-traffic-selector-types.yang
new file mode 100644
index 0000000..029f3ec
--- /dev/null
+++ b/models/fpcagent/src/main/yang/ietf-traffic-selector-types.yang
@@ -0,0 +1,508 @@
+module ietf-traffic-selector-types {
+ yang-version 1;
+
+ namespace
+ "urn:ietf:params:xml:ns:yang:ietf-traffic-selector-types";
+
+ prefix "ietf-traffic-selectors";
+
+ import ietf-inet-types {
+ prefix inet;
+ revision-date 2013-07-15;
+ }
+
+ organization
+ "IETF DMM (Dynamic Mobility Management) Working Group";
+
+ contact
+ "WG Web: <https://datatracker.ietf.org/wg/dmm/>
+ WG List: <mailto:dmm@ietf.org>
+
+ WG Chair: Dapeng Liu
+ <mailto:maxpassion@gmail.com>
+
+ WG Chair: Jouni Korhonen
+ <mailto:jouni.nospam@gmail.com>
+
+ Editor:
+ <mailto:>";
+
+ description
+ "This module contains a collection of YANG definitions for
+ traffic selectors for flow bindings.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module was created as part of the IETF
+ DMM FPC YANG modules; see the RFC itself for full legal notices.";
+
+ revision 2016-01-14 {
+ description "Updated for IETF-PACKET-FIELDS module alignment";
+ reference
+ "draft-ietf-netmod-acl-model-06";
+ }
+
+ revision 2016-01-12 {
+ description "Initial revision";
+ reference
+ "RFC 6088: Traffic Selectors for Flow Bindings";
+ }
+
+ // Identities
+ identity traffic-selector-format {
+ description "The base type for Traffic-Selector Formats";
+ }
+
+ identity ipv4-binary-selector-format {
+ base traffic-selector-format;
+ description
+ "IPv4 Binary Traffic Selector Format";
+ }
+
+ identity ipv6-binary-selector-format {
+ base traffic-selector-format;
+ description
+ "IPv6 Binary Traffic Selector Format";
+ }
+
+ // Type definitions and groupings
+ typedef ipsec-spi {
+ type uint32;
+ description "This type defines the first 32-bit IPsec Security Parameter
+ Index (SPI) value on data packets sent from a corresponding
+ node to the mobile node as seen by the home agent. This field
+ is defined in [RFC4303].";
+ reference
+ "RFC 4303: IP Encapsulating Security Payload (ESP)";
+ }
+
+ grouping traffic-selector-base {
+ description "A grouping of the commen leaves between the v4 and v6 Traffic Selectors";
+ container ipsec-spi-range {
+ presence "Enables setting ipsec spi range";
+ description
+ "Inclusive range representing IPSec Security Parameter Indices to be used.
+ When only start-spi is present, it represents a single spi.";
+ leaf start-spi {
+ type ipsec-spi;
+ mandatory true;
+ description
+ "This field identifies the first 32-bit IPsec SPI value, from the
+ range of SPI values to be matched, on data packets sent from a
+ corresponding node to the mobile node as seen by the home agent.
+ This field is defined in [RFC4303].";
+ }
+ leaf end-spi {
+ type ipsec-spi;
+ must ". >= ../start-spi" {
+ error-message
+ "The end-spi must be greater than or equal to start-spi";
+ }
+ description
+ "If more than one contiguous SPI value needs to be matched, then
+ this field can be used to indicate the end value of a range
+ starting from the value of the Start SPI field. This field
+ MUST NOT be included unless the Start SPI field is included
+ and has a value less than or equal to this field.
+
+ When this field is included, the receiver will match all of the
+ SPI values between fields start-spi and end-spi,
+ inclusive of start-spi and end-spi.";
+ }
+ }
+ container source-port-range {
+ presence "Enables setting source port range";
+ description
+ "Inclusive range representing source ports to be used.
+ When only start-port is present, it represents a single port.";
+ leaf start-port {
+ type inet:port-number;
+ mandatory true;
+ description
+ "This field identifies the first 16-bit source port number, from
+ the range of port numbers to be matched, on data packets sent from
+ a corresponding node to the mobile node as seen by the home agent.
+ This is from the range of port numbers defined by IANA
+ (http://www.iana.org).";
+ }
+ leaf end-port {
+ type inet:port-number;
+ must ". >= ../start-port" {
+ error-message
+ "The end-port must be greater than or equal to start-port";
+ }
+ description
+ "If more than one contiguous source port number needs to be
+ matched, then this field can be used to indicate the end value of
+ a range starting from the value of the Start Port field.
+ This field MUST NOT be included unless the Start Port field
+ is included and has a value less than or equal to this field.
+
+ When this field is included, the receiver will match
+ all of the port numbers between fields start-port and
+ end-port, inclusive of start-port and end-port.";
+ }
+ }
+ container destination-port-range {
+ presence "Enables setting destination port range";
+ description
+ "Inclusive range representing destination ports to be used. When
+ only start-port is present, it represents a single port.";
+ leaf start-port {
+ type inet:port-number;
+ mandatory true;
+ description
+ "This field identifies the first 16-bit destination port number,
+ from the range of port numbers to be matched, on data packets sent
+ from a corresponding node to the mobile node as seen by the home
+ agent.";
+ }
+ leaf end-port {
+ type inet:port-number;
+ must ". >= ../start-port" {
+ error-message
+ "The end-port must be greater than or equal to start-port";
+ }
+ description
+ "If more than one contiguous destination port number needs to be
+ matched, then this field can be used to indicate the end value of
+ a range starting from the value of the Start Destination Port
+ field. This field MUST NOT be included unless the Start
+ Port field is included and has a value less than or equal to this
+ field.
+
+ When this field is included, the receiver will match all of the
+ port numbers between fields start-port and end-port, inclusive of
+ start-port and end-port.";
+ }
+ }
+ }
+
+ grouping ipv4-binary-traffic-selector {
+ container source-address-range-v4 {
+ presence "Enables setting source IPv4 address range";
+ description
+ "Inclusive range representing IPv4 addresses to be used. When
+ only start-address is present, it represents a single address.";
+ leaf start-address {
+ type inet:ipv4-address;
+ mandatory true;
+ description
+ "This field identifies the first source address, from the range of
+ 32-bit IPv4 addresses to be matched, on data packets sent from a
+ corresponding node to the mobile node as seen by the home agent.
+ In other words, this is one of the addresses of the correspondent
+ node.";
+ }
+ leaf end-address {
+ type inet:ipv4-address;
+ description
+ "If more than one contiguous source address needs to be matched,
+ then this field can be used to indicate the end value of a range
+ starting from the value of the Start Address field. This
+ field MUST NOT be included unless the Start Address field
+ is included. When this field is included, the receiver will match
+ all of the addresses between fields start-address and
+ end-address, inclusive of start-address and end-address.";
+ }
+ }
+ container destination-address-range-v4 {
+ presence "Enables setting destination IPv4 address range";
+ description
+ "Inclusive range representing IPv4 addresses to be used. When
+ only start-address is present, it represents a single address.";
+ leaf start-address {
+ type inet:ipv4-address;
+ mandatory true;
+ description
+ "This field identifies the first destination address, from the
+ range of 32-bit IPv4 addresses to be matched, on data packets sent
+ from a corresponding node to the mobile node as seen by the home
+ agent. In other words, this is one of the registered home
+ addresses of the mobile node.";
+ }
+ leaf end-address {
+ type inet:ipv4-address;
+ description
+ "If more than one contiguous destination address needs to be
+ matched, then this field can be used to indicate the end value of
+ a range starting from the value of the Start Destination Address
+ field. This field MUST NOT be included unless the Start
+ Address field is included. When this field is included, the receiver
+ will match all of the addresses between fields start-address and
+ end-address, inclusive of start-address and end-address.";
+ }
+ }
+ container ds-range {
+ presence "Enables setting dscp range";
+ description
+ "Inclusive range representing DiffServ Codepoints to be used. When
+ only start-ds is present, it represents a single Codepoint.";
+ leaf start-ds {
+ type inet:dscp;
+ mandatory true;
+ description
+ "This field identifies the first differential services value, from
+ the range of differential services values to be matched, on data
+ packets sent from a corresponding node to the mobile node as seen
+ by the home agent. Note that this field is called a 'Type of
+ Service field' in [RFC0791]. [RFC3260] then clarified that the
+ field has been redefined as a 6-bit DS field with 2 bits reserved,
+ later claimed by Explicit Congestion Notification (ECN) [RFC3168].
+ For the purpose of this specification, the Start DS field is 8
+ bits long, where the 6 most significant bits indicate the DS field
+ to be matched and the 2 least significant bits' values MUST be
+ ignored in any comparison.";
+ }
+ leaf end-ds {
+ type inet:dscp;
+ must ". >= ../start-ds" {
+ error-message
+ "The end-ds must be greater than or equal to start-ds";
+ }
+ description
+ "If more than one contiguous DS value needs to be matched, then
+ this field can be used to indicate the end value of a range
+ starting from the value of the Start DS field. This field MUST
+ NOT be included unless the Start DS field is included. When this
+ field is included, it MUST be coded the same way as defined for
+ start-ds. When this field is included, the receiver will match all of
+ the values between fields start-ds and end-ds, inclusive of start-ds
+ and end-ds.";
+ }
+ }
+ container protocol-range {
+ presence "Enables setting protocol range";
+ description
+ "Inclusive range representing IP protocol(s) to be used. When
+ only start-protocol is present, it represents a single protocol.";
+ leaf start-protocol {
+ type uint8;
+ mandatory true;
+ description
+ "This field identifies the first 8-bit protocol value, from the
+ range of protocol values to be matched, on data packets sent from
+ a corresponding node to the mobile node as seen by the home agent.";
+ }
+ leaf end-protocol {
+ type uint8;
+ must ". >= ../start-protocol" {
+ error-message
+ "The end-protocol must be greater than or equal to start-protocol";
+ }
+ description
+ "If more than one contiguous protocol value needs to be matched,
+ then this field can be used to indicate the end value of a range
+ starting from the value of the Start Protocol field. This field
+ MUST NOT be included unless the Start Protocol field is included.
+ When this field is included, the receiver will match all of the
+ values between fields start-protocol and end-protocol, inclusive
+ of start-protocol and end-protocol.";
+ }
+ }
+ }
+
+ grouping ipv6-binary-traffic-selector {
+ container source-address-range-v6 {
+ presence "Enables setting source IPv6 address range";
+ description
+ "Inclusive range representing IPv6 addresses to be used. When
+ only start-address is present, it represents a single address.";
+ leaf start-address {
+ type inet:ipv6-address;
+ mandatory true;
+ description
+ "This field identifies the first source address, from the range of
+ 128-bit IPv6 addresses to be matched, on data packets sent from a
+ corresponding node to the mobile node as seen by the home agent.
+ In other words, this is one of the addresses of the correspondent
+ node.";
+ }
+ leaf end-address {
+ type inet:ipv6-address;
+ description
+ "If more than one contiguous source address needs to be matched,
+ then this field can be used to indicate the end value of a range
+ starting from the value of the Start Address field. This
+ field MUST NOT be included unless the Start Address field is included.
+ When this field is included, the receiver will match all of the addresses
+ between fields start-address and end-address, inclusive of start-address
+ and end-address .";
+ }
+ }
+ container destination-address-range-v6 {
+ presence "Enables setting destination IPv6 address range";
+ description
+ "Inclusive range representing IPv6 addresses to be used. When
+ only start-address is present, it represents a single address.";
+ leaf start-address {
+ type inet:ipv6-address;
+ mandatory true;
+ description
+ "This field identifies the first destination address, from the
+ range of 128-bit IPv6 addresses to be matched, on data packets
+ sent from a corresponding node to the mobile node as seen by the
+ home agent. In other words, this is one of the registered home
+ addresses of the mobile node.";
+ }
+ leaf end-address {
+ type inet:ipv6-address;
+ description
+ "If more than one contiguous destination address needs to be
+ matched, then this field can be used to indicate the end value of
+ a range starting from the value of the Start Address field. This
+ field MUST NOT be included unless the Start Address field is included.
+ When this field is included, the receiver will match all of the
+ addresses between fields start-address and end-address, inclusive of
+ start-address and end-address.";
+ }
+ }
+ container flow-label-range {
+ presence "Enables setting Flow Label range";
+ description
+ "Inclusive range representing IPv4 addresses to be used. When
+ only start-flow-label is present, it represents a single flow label.";
+ leaf start-flow-label {
+ type inet:ipv6-flow-label;
+ description
+ "This field identifies the first flow label value, from the range
+ of flow label values to be matched, on data packets sent from a
+ corresponding node to the mobile node as seen by the home agent.
+ According to [RFC2460], the flow label is 24 bits long. For the
+ purpose of this specification, the sender of this option MUST
+ prefix the flow label value with 8 bits of '0' before inserting it
+ in the start-flow-label field. The receiver SHOULD ignore the
+ first 8 bits of this field before using it in comparisons with
+ flow labels in packets.";
+ }
+ leaf end-flow-label {
+ type inet:ipv6-flow-label;
+ must ". >= ../start-flow-label" {
+ error-message
+ "The end-flow-lable must be greater than or equal to start-flow-label";
+ }
+ description
+ "If more than one contiguous flow label value needs to be matched,
+ then this field can be used to indicate the end value of a range
+ starting from the value of the Start Flow Label field. This field
+ MUST NOT be included unless the Start Flow Label field is
+ included. When this field is included, the receiver will match
+ all of the flow label values between fields start-flow-label
+ and end-flow-label, inclusive of start-flow-label and end-flow-label.
+ When this field is included, it MUST be coded the same way as defined
+ for end-flow-label.";
+ }
+ }
+ container traffic-class-range {
+ presence "Enables setting the traffic class range";
+ description
+ "Inclusive range representing IPv4 addresses to be used. When
+ only start-traffic-class is present, it represents a single traffic class.";
+ leaf start-traffic-class {
+ type inet:dscp;
+ description
+ "This field identifies the first traffic class value, from the
+ range of traffic class values to be matched, on data packets sent
+ from a corresponding node to the mobile node as seen by the home
+ agent. This field is equivalent to the Start DS field in the IPv4
+ traffic selector in Figure 1. As per RFC 3260, the field is
+ defined as a 6-bit DS field with 2 bits reserved, later claimed by
+ Explicit Congestion Notification (ECN) RFC 3168. For the purpose
+ of this specification, the start-traffic-class field is 8 bits long, where
+ the 6 most significant bits indicate the DS field to be matched
+ and the 2 least significant bits' values MUST be ignored in any
+ comparison.";
+ reference
+ "RFC 3260: New Terminology and Clarifications for Diffserv
+ RFC 3168: The Addition of Explicit Congestion Notification (ECN) to IP";
+ }
+ leaf end-traffic-class {
+ type inet:dscp;
+ must ". >= ../start-traffic-class" {
+ error-message
+ "The end-traffic-class must be greater than or equal to start-traffic-class";
+ }
+ description
+ "If more than one contiguous TC value needs to be matched, then
+ this field can be used to indicate the end value of a range
+ starting from the value of the Start TC field. This field MUST
+ NOT be included unless the Start TC field is included. When this
+ field is included, it MUST be coded the same way as defined for
+ start-traffic-class. When this field is included, the receiver
+ will match all of the values between fields start-traffic-class
+ and end-traffic-class, inclusive of start-traffic-class and
+ end-traffic-class.";
+ }
+ }
+ container next-header-range {
+ presence "Enables setting Next Header range";
+ description
+ "Inclusive range representing Next Headers to be used. When
+ only start-next-header is present, it represents a single Next Header.";
+ leaf start-next-header {
+ type uint8;
+ description
+ "This field identifies the first 8-bit next header value, from the
+ range of next header values to be matched, on data packets sent
+ from a corresponding node to the mobile node as seen by the home
+ agent.";
+ }
+ leaf end-next-header {
+ type uint8;
+ must ". >= ../start-next-header" {
+ error-message
+ "The end-next-header must be greater than or equal to start-next-header";
+ }
+ description
+ "If more than one contiguous next header value needs to be matched,
+ then this field can be used to indicate the end value of a range
+ starting from the value of the Start NH field. This field MUST
+ NOT be included unless the Start next header field is included.
+ When this field is included, the receiver will match all of the
+ values between fields start-next-header and end-next-header,
+ inclusive of start-next-header and end-next-header.";
+ }
+ }
+ }
+
+ grouping traffic-selector {
+ leaf ts-format {
+ type identityref {
+ base traffic-selector-format;
+ }
+ description "Traffic Selector Format";
+ }
+ uses traffic-selector-base {
+ when "boolean(../ts-format/text() = 'ipv6-binary-selector-format') | boolean(../ts-format/text() = 'ipv4-binary-selector-format')";
+ }
+ uses ipv4-binary-traffic-selector {
+ when "boolean(../ts-format/text() = 'ipv4-binary-selector-format')";
+ }
+ uses ipv6-binary-traffic-selector {
+ when "boolean(../ts-format/text() = 'ipv6-binary-selector-format')";
+ }
+ description
+ "The traffic selector includes the parameters used to match
+ packets for a specific flow binding.";
+ reference
+ "RFC 6089: Flow Bindings in Mobile IPv6 and Network Mobility (NEMO) Basic Support";
+ }
+
+ grouping ts-list {
+ list selectors {
+ key index;
+ leaf index {
+ type uint64;
+ }
+ uses traffic-selector;
+ }
+ }
+}