From 09f2f8653d1ea559eddca015ea55f61d23d732ac Mon Sep 17 00:00:00 2001 From: Thomas Kee Date: Fri, 5 Sep 2014 23:58:33 -0700 Subject: [PATCH] Sync: md-sal augmentation re-model with broker. Traffic profile: Best Effort hooked up. Change-Id: I12551cf44db640d9ff3515214a87cfe1d2ba1f39 Signed-off-by: Thomas Kee --- packetcable-client/base.text | 101 ++++ packetcable-client/cableflow1.json | 36 ++ packetcable-client/cableflow1.xml | 36 ++ packetcable-client/cableflow2.json | 36 ++ packetcable-client/cableflow2.xml | 36 ++ packetcable-client/cableflow3.json | 36 ++ packetcable-client/cableflow3.xml | 37 ++ packetcable-client/cableflow4.json | 34 ++ packetcable-client/cableflow4.xml | 33 ++ packetcable-client/cableflow5.json | 50 ++ packetcable-client/cableflow5.xml | 50 ++ packetcable-client/cableflow7.json | 46 ++ packetcable-client/cableflow7.xml | 46 ++ packetcable-client/cableflow8.json | 46 ++ packetcable-client/cableflow8.xml | 46 ++ packetcable-client/make_json.sh | 10 + packetcable-client/make_xml.sh | 10 + packetcable-client/restconftest.py | 443 ++++++++++++++++++ packetcable-client/xml2json | 250 ++++++++++ packetcable-config/pom.xml | 82 ++++ .../src/main/resources/80-packetcable.xml | 43 ++ packetcable-driver/pom.xml | 26 +- .../main/java/org/pcmm/PCMMGlobalConfig.java | 20 + packetcable-karaf/pom.xml | 298 ++++++++++++ .../src/main/yang/packetcable-cmts.yang | 178 +------ .../main/yang/packetcable-match-types.yang | 308 ++++++------ .../src/main/yang/packetcable-service.yang | 380 --------------- .../yang/packetcable-traffic-profile.yang | 328 +++++++++++-- packetcable-provider/pom.xml | 17 +- .../impl/PacketcableProviderModule.java | 66 --- ...penDaylightPacketCableProviderService.java | 20 + .../OpendaylightPacketcableProvider.java | 343 +++++++------- .../processors/PCMMDataProcessor.java | 193 ++++++++ .../rev140131/PacketcableProviderModule.java | 30 ++ .../PacketcableProviderModuleFactory.java | 6 +- .../main/yang/packetcable-provider-impl.yang | 55 +-- .../src/main/yang/packetcable-provider.yang | 25 + pom.xml | 110 +++-- 38 files changed, 2794 insertions(+), 1116 deletions(-) create mode 100644 packetcable-client/base.text create mode 100644 packetcable-client/cableflow1.json create mode 100644 packetcable-client/cableflow1.xml create mode 100644 packetcable-client/cableflow2.json create mode 100644 packetcable-client/cableflow2.xml create mode 100644 packetcable-client/cableflow3.json create mode 100644 packetcable-client/cableflow3.xml create mode 100644 packetcable-client/cableflow4.json create mode 100644 packetcable-client/cableflow4.xml create mode 100644 packetcable-client/cableflow5.json create mode 100644 packetcable-client/cableflow5.xml create mode 100644 packetcable-client/cableflow7.json create mode 100644 packetcable-client/cableflow7.xml create mode 100644 packetcable-client/cableflow8.json create mode 100644 packetcable-client/cableflow8.xml create mode 100755 packetcable-client/make_json.sh create mode 100755 packetcable-client/make_xml.sh create mode 100755 packetcable-client/restconftest.py create mode 100755 packetcable-client/xml2json create mode 100644 packetcable-config/pom.xml create mode 100644 packetcable-config/src/main/resources/80-packetcable.xml create mode 100644 packetcable-karaf/pom.xml delete mode 100644 packetcable-model/src/main/yang/packetcable-service.yang delete mode 100644 packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModule.java create mode 100644 packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpenDaylightPacketCableProviderService.java create mode 100644 packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/processors/PCMMDataProcessor.java create mode 100644 packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModule.java rename packetcable-provider/src/main/java/org/opendaylight/{controller/config/yang/config/packetcable_provider/impl => yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131}/PacketcableProviderModuleFactory.java (53%) create mode 100644 packetcable-provider/src/main/yang/packetcable-provider.yang diff --git a/packetcable-client/base.text b/packetcable-client/base.text new file mode 100644 index 0000000..91c5420 --- /dev/null +++ b/packetcable-client/base.text @@ -0,0 +1,101 @@ +# Something from the real world + +# 0. Create a new cmts for adding cableflows +# Operation: POST +# URI: http://192.168.11.1:8181/restconf/config/opendaylight-inventory:nodes/node/cmts:1 +# /restconf/config/opendaylight-inventory:nodes/node/cmts:1 + +cmts1 = { + "cmts": { + "name": "SunnyvaleCMTS", + "id": "2", + "enable": "true", + "ipaddress": "10.200.90.3", + "port": 3918, + } +} + +# 1. Create a new flow on the switch cableflow:1 (in table 1) +# Operation: POST +# URI: http://192.168.11.1:8181/restconf/config/opendaylight-inventory:nodes/node/cableflow:1 +# /restconf/config/opendaylight-inventory:nodes/node/cableflow:1 + + +cableflow1 = { + "flow": { + "barrier": "false", + "flow-name": "FooXCableFlow1", + "id": "111", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "drop-action": null, + "order": "0" + } + "action": { + traffic-profile": "best-effort", + "order": "0" + } + }, + "order": "1" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "2048" + } + }, + "ipv4-destination": "10.0.0.1/24" + }, + "priority": "2", + } +} + + +# 2. Change strict to true in previous flow +# Operation: PUT +# URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 +# /restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 + +cableflow2 = { + "flow": { + "barrier": "false", + "flow-name": "FooXCableFlow2", + "id": "111", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + traffic-profile": "best-effort", + "order": "0" + } + }, + "order": "0" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "2048" + } + }, + "ipv4-destination": "10.0.0.1/24" + }, + "priority": "2", + } +} + +# 3. Show flow - check that strict is true +# Operation: GET +# URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 +# /restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 + +#4. Delete created flow +# Operation: DELETE +# URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 +# /restconf/config/opendaylight-inventory:nodes/node/cableflow:1/table/1/flow/111 + diff --git a/packetcable-client/cableflow1.json b/packetcable-client/cableflow1.json new file mode 100644 index 0000000..7fd247d --- /dev/null +++ b/packetcable-client/cableflow1.json @@ -0,0 +1,36 @@ +{ + "flow": { + "barrier": "false", + "cookie": "10", + "cookie_mask": "10", + "flow-name": "FooXf22", + "hard-timeout": "0", + "id": "111", + "idle-timeout": "0", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "flood-all-action": null, + "order": "1" + } + }, + "order": "1" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "2048" + } + }, + "ipv4-destination": "10.0.0.1/24" + }, + "out_group": "2", + "out_port": "10", + "priority": "2", + "strict": "false", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow1.xml b/packetcable-client/cableflow1.xml new file mode 100644 index 0000000..a9d445d --- /dev/null +++ b/packetcable-client/cableflow1.xml @@ -0,0 +1,36 @@ + + + false + + + 1 + + + 1 + + + + + + 2 + 111 + 10 + 10 + false + 2 + + + + 2048 + + + 10.0.0.1/24 + + 0 + 10 + 0 + FooXf22 + 2 + false + diff --git a/packetcable-client/cableflow2.json b/packetcable-client/cableflow2.json new file mode 100644 index 0000000..08ee08d --- /dev/null +++ b/packetcable-client/cableflow2.json @@ -0,0 +1,36 @@ +{ + "flow": { + "barrier": "false", + "cookie": "10", + "cookie_mask": "10", + "flow-name": "FooXf22", + "hard-timeout": "0", + "id": "111", + "idle-timeout": "0", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "flood-all-action": null, + "order": "1" + } + }, + "order": "1" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "2048" + } + }, + "ipv4-destination": "10.0.0.1/24" + }, + "out_group": "2", + "out_port": "10", + "priority": "2", + "strict": "true", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow2.xml b/packetcable-client/cableflow2.xml new file mode 100644 index 0000000..3feb128 --- /dev/null +++ b/packetcable-client/cableflow2.xml @@ -0,0 +1,36 @@ + + + true + + + 1 + + + 1 + + + + + + 2 + 111 + 10 + 10 + false + 2 + + + + 2048 + + + 10.0.0.1/24 + + 0 + 10 + 0 + FooXf22 + 2 + false + diff --git a/packetcable-client/cableflow3.json b/packetcable-client/cableflow3.json new file mode 100644 index 0000000..08ee08d --- /dev/null +++ b/packetcable-client/cableflow3.json @@ -0,0 +1,36 @@ +{ + "flow": { + "barrier": "false", + "cookie": "10", + "cookie_mask": "10", + "flow-name": "FooXf22", + "hard-timeout": "0", + "id": "111", + "idle-timeout": "0", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "flood-all-action": null, + "order": "1" + } + }, + "order": "1" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "2048" + } + }, + "ipv4-destination": "10.0.0.1/24" + }, + "out_group": "2", + "out_port": "10", + "priority": "2", + "strict": "true", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow3.xml b/packetcable-client/cableflow3.xml new file mode 100644 index 0000000..7032a91 --- /dev/null +++ b/packetcable-client/cableflow3.xml @@ -0,0 +1,37 @@ + + + true + + + 1 + + + 1 + + + + + + 2 + 111 + 10 + 10 + false + 2 + + + + 2048 + + + 10.0.0.1/24 + + 0 + 10 + 0 + FooXf22 + 2 + false + + diff --git a/packetcable-client/cableflow4.json b/packetcable-client/cableflow4.json new file mode 100644 index 0000000..813eae3 --- /dev/null +++ b/packetcable-client/cableflow4.json @@ -0,0 +1,34 @@ +{ + "flow": { + "barrier": "false", + "cookie": "10", + "cookie_mask": "10", + "flow-name": "FooXf45", + "hard-timeout": "12", + "id": "168", + "idle-timeout": "34", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "drop-action": null, + "order": "0" + } + }, + "order": "0" + } + }, + "match": { + "metadata": { + "metadata": "500", + "metadata-mask": "[B@46645a66" + } + }, + "out_group": "2", + "out_port": "10", + "priority": "2", + "strict": "false", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow4.xml b/packetcable-client/cableflow4.xml new file mode 100644 index 0000000..80c65ef --- /dev/null +++ b/packetcable-client/cableflow4.xml @@ -0,0 +1,33 @@ + + + false + + + 0 + + + 0 + + + + + + 2 + 168 + 10 + 10 + false + 2 + + + [B@46645a66 + 500 + + + 12 + 10 + 34 + FooXf45 + 2 + false + diff --git a/packetcable-client/cableflow5.json b/packetcable-client/cableflow5.json new file mode 100644 index 0000000..10efb10 --- /dev/null +++ b/packetcable-client/cableflow5.json @@ -0,0 +1,50 @@ +{ + "flow": { + "cookie": "27", + "cookie_mask": "255", + "flow-name": "FooXf27", + "hard-timeout": "1200", + "id": "150", + "idle-timeout": "3400", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "dec-nw-ttl": null, + "order": "0" + } + }, + "order": "0" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "34525" + } + }, + "ip-match": { + "ip-dscp": "60", + "ip-ecn": "3", + "ip-protocol": "6" + }, + "ipv6-destination": "fe80:2acf:e9ff:fe21::6431/94", + "ipv6-ext-header": { + "ipv6-exthdr": "0" + }, + "ipv6-label": { + "ipv6-flabel": "33" + }, + "ipv6-source": "1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76", + "metadata": { + "metadata": "12345" + }, + "tcp-destination-port": "8080", + "tcp-source-port": "183" + }, + "priority": "2", + "strict": "false", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow5.xml b/packetcable-client/cableflow5.xml new file mode 100644 index 0000000..134e1c9 --- /dev/null +++ b/packetcable-client/cableflow5.xml @@ -0,0 +1,50 @@ + + + false + FooXf27 + 150 + 255 + 27 + 2 + 2 + 1200 + 3400 + false + + + 0 + + + 0 + + + + + + + + + 34525 + + + 1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76 + fe80:2acf:e9ff:fe21::6431/94 + + 12345 + + + 33 + + + 0 + + + 6 + 60 + 3 + + 183 + 8080 + + + diff --git a/packetcable-client/cableflow7.json b/packetcable-client/cableflow7.json new file mode 100644 index 0000000..2a5ba63 --- /dev/null +++ b/packetcable-client/cableflow7.json @@ -0,0 +1,46 @@ +{ + "flow": { + "cookie": "101", + "cookie_mask": "255", + "flow-name": "set-field-ipv6-source-addr", + "hard-timeout": "1200", + "id": "256", + "idle-timeout": "3400", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "order": "0", + "set-field": { + "ipv6-source": "1004:5608:900c:d000:f00d::200f" + } + } + }, + "order": "0" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "34525" + } + }, + "ip-match": { + "ip-dscp": "60", + "ip-ecn": "3", + "ip-protocol": "6" + }, + "ipv6-destination": "fe80:2acf:e9ff:fe21::6431/94", + "ipv6-source": "1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76", + "metadata": { + "metadata": "12345" + }, + "tcp-destination-port": "8080", + "tcp-source-port": "183" + }, + "priority": "2", + "strict": "false", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow7.xml b/packetcable-client/cableflow7.xml new file mode 100644 index 0000000..da1e277 --- /dev/null +++ b/packetcable-client/cableflow7.xml @@ -0,0 +1,46 @@ + + + false + set-field-ipv6-source-addr + 256 + 255 + 101 + 2 + 2 + 1200 + 3400 + false + + + 0 + + + 0 + + 1004:5608:900c:d000:f00d::200f + + + + + + + + + 34525 + + + 1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76 + fe80:2acf:e9ff:fe21::6431/94 + + 12345 + + + 6 + 60 + 3 + + 183 + 8080 + + + diff --git a/packetcable-client/cableflow8.json b/packetcable-client/cableflow8.json new file mode 100644 index 0000000..6438878 --- /dev/null +++ b/packetcable-client/cableflow8.json @@ -0,0 +1,46 @@ +{ + "flow": { + "cookie": "101", + "cookie_mask": "255", + "flow-name": "set-field-ipv6-dest-addr", + "hard-timeout": "1200", + "id": "256", + "idle-timeout": "3400", + "installHw": "false", + "instructions": { + "instruction": { + "apply-actions": { + "action": { + "order": "0", + "set-field": { + "ipv6-destination": "2160:2160:216::6431" + } + } + }, + "order": "0" + } + }, + "match": { + "ethernet-match": { + "ethernet-type": { + "type": "34525" + } + }, + "ip-match": { + "ip-dscp": "60", + "ip-ecn": "3", + "ip-protocol": "6" + }, + "ipv6-destination": "fe80:2acf:e9ff:fe21::6431/94", + "ipv6-source": "1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76", + "metadata": { + "metadata": "12345" + }, + "tcp-destination-port": "8080", + "tcp-source-port": "183" + }, + "priority": "2", + "strict": "false", + "table_id": "2" + } +} \ No newline at end of file diff --git a/packetcable-client/cableflow8.xml b/packetcable-client/cableflow8.xml new file mode 100644 index 0000000..c05acdc --- /dev/null +++ b/packetcable-client/cableflow8.xml @@ -0,0 +1,46 @@ + + + false + set-field-ipv6-dest-addr + 256 + 255 + 101 + 2 + 2 + 1200 + 3400 + false + + + 0 + + + 0 + + 2160:2160:216::6431 + + + + + + + + + 34525 + + + 1234:5678:9ABC:DEF0:FDCD:A987:6543:210F/76 + fe80:2acf:e9ff:fe21::6431/94 + + 12345 + + + 6 + 60 + 3 + + 183 + 8080 + + + diff --git a/packetcable-client/make_json.sh b/packetcable-client/make_json.sh new file mode 100755 index 0000000..c818c33 --- /dev/null +++ b/packetcable-client/make_json.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +files=( *.xml ) +for file in "${files[@]}" +do + filename="${file##*/}" + filenameWithoutExtension="${filename%.*}" + echo "converting $filenameWithoutExtension ..." + ./xml2json -t xml2json $file --strip_text --strip_namespace --pretty -o "$filenameWithoutExtension".json +done diff --git a/packetcable-client/make_xml.sh b/packetcable-client/make_xml.sh new file mode 100755 index 0000000..bbda02d --- /dev/null +++ b/packetcable-client/make_xml.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +files=( *.json ) +for file in "${files[@]}" +do + filename="${file##*/}" + filenameWithoutExtension="${filename%.*}" + echo "converting $filenameWithoutExtension ..." + ./xml2json -t json2xml $file --strip_text --strip_namespace --pretty -o "$filenameWithoutExtension".xml +done diff --git a/packetcable-client/restconftest.py b/packetcable-client/restconftest.py new file mode 100755 index 0000000..0f1f156 --- /dev/null +++ b/packetcable-client/restconftest.py @@ -0,0 +1,443 @@ +#!/usr/bin/env python + +__author__ = 'xsited' +import os +import httplib +import json +import yaml +import base64 +import string +from urlparse import urlparse +from pprint import pprint +from os.path import basename + +toggle = 1 + +# consider refectoring with request http://docs.python-requests.org/en/latest/index.html + +class Error: + # indicates an HTTP error + def __init__(self, url, errcode, errmsg, headers): + self.url = url + self.errcode = errcode + self.errmsg = errmsg + self.headers = headers + def __repr__(self): + return ( + "" % + (self.url, self.errcode, self.errmsg) + ) + + +class RestfulAPI(object): + def __init__(self, server): + self.server = server + self.path = '/wm/staticflowentrypusher/json' + self.auth = '' + self.port = 8080 + + def get_server(self): + return self.server + + def set_server(self, server): + self.server = server + + + def set_path(self, path): + #print path + self.path = path + +# def set_path(self, path, port): +# self.path = path +# self.port = port + + def set_port(self, port): + #print port + self.port = port + + def use_creds(self): + u = self.auth is not None and len(self.auth) > 0 +# p = self.password is not None and len(self.password) > 0 + return u + + def credentials(self, username, password): + self.auth = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') + + def get(self, data=''): + ret = self.rest_call({}, 'GET') + #return json.loads(ret[2]) + return ret + + def set(self, data): + #ret = self.rest_call(data, 'PUT') + ret = self.rest_call2(data, 'PUT') + print ret[0], ret[1] + # return ret[0] == 200 + return ret + + def post(self, data): + ret = self.rest_call(data, 'POST') + #ret = self.rest_call2(data, 'POST') + print ret[0], ret[1] + return ret + + def put(self, data): + ret = self.rest_call(data, 'PUT') + return ret + #return ret[0] == 200 + + + def remove(self, objtype, data): + ret = self.rest_call(data, 'DELETE') + #return ret[0] == 200 + return ret + + def show(self, data): + print "" + print json.dumps(data, indent=4, sort_keys=True) +# print 'DATA:', repr(data) +# +# print "" +# data_string = json.dumps(data) +# print 'JSON:', data_string +# +# print "" +# data_string = json.dumps(data) +# print 'ENCODED:', data_string +# +# print "" +# decoded = json.loads(data_string) +# print 'DECODED:', decoded + + + def rest_call2(self, data, action, content_type='json'): + + #conn = httplib.HTTPConnection(self.server, self.port) + conn = httplib.HTTP(self.server, self.port) + conn.putrequest(action, self.path) + conn.putheader("Host", self.server+':%s'%self.port) + conn.putheader("User-Agent", "Python HTTP Auth") + conn.putheader('Content-type', 'application/%s' % content_type) + body = json.dumps(data) + #conn.putheader("Content-length", "%d" % len(data)) + conn.putheader("Content-length", "%d" % len(body)) + if self.use_creds(): + # print "using creds" + conn.putheader("Authorization", "Basic %s" % self.auth) + conn.endheaders() + + conn.send(body) + errcode, errmsg, headers = conn.getreply() + ret = (errcode, errmsg, headers) + + #if errcode != 201: + # raise Error(self.path, errcode, errmsg, headers) + + # get response + #response = conn.getresponse() + #headers = response.read() + #ret = (response.status, response.reason, headers) + #if response.status != 200: + # raise Error(self.path, response.status, response.reason, headers) + return ret + + + def rest_call(self, data, action, content_type='json'): + # this? + putheaders = {'content-type': 'application/json'} + getheaders = {'Accept': 'application/json'} + body = json.dumps(data) + if self.use_creds(): + # print "using creds" + headers = { + 'Content-type': 'application/%s' % content_type, + 'Accept': 'application/%s' % content_type, + 'Content-length': "%d" % len(body), + 'Authorization': "Basic %s" % self.auth, + } + else: + headers = { + 'Content-type': 'application/%s' % content_type, + 'Accept': 'application/%s' % content_type, + 'Content-length': "%d" % len(body), + } + + print self.server+':',self.port, self.path + conn = httplib.HTTPConnection(self.server, self.port) + conn.request(action, self.path, body, headers) + response = conn.getresponse() + data = response.read() + ret = (response.status, response.reason, data) + #print "status %d %s" % (response.status,response.reason) + conn.close() + return ret + + +class Menu(object): + def __init__(self): + pass + + def print_menu(self): + print (30 * '-') + print (" CABLEFLOW ") + print (30 * '-') + print ("1. Add CMTS 1 ") + print ("2. Add CMTS 2 ") + print ("3. Add Flow 1 CMTS 1 ") + print ("4. Add Flow 2 CMTS 2 ") + print ("5. Remove Flow 1 CMTS 1") + print ("6. Remove Flow 2 CMTS 2") + print ("7. Remove All Flows ") + print ("8. List Flow Stats ") + print ("9. List Topology ") + print ("10. List Flows ") + print ("11. Remove CMTS 1 ") + print ("12. Remove CMTS 2 ") + print ("q. Quit ") +# print (30 * '-') + + + def no_such_action(self): + print "Invalid option!" + + def run(self): + self.print_menu() + actions = { + "1": tests.flow_add_1, + "2": tests.flow_add_2, + "3": tests.flow_add_several, + "4": tests.flow_remove_1, + "5": tests.flow_remove_2, + "6": tests.flow_remove_all, + "8": tests.flow_list_stats, + "9": tests.topology_list, + "10":tests.flow_list, + "q": tests.exit_app, + } + + while True: + self.print_menu() + selection = raw_input("Enter selection: ") + if "quit" == selection: + return + toDo = actions.get(selection, self.no_such_action) + toDo() + + + + +class ODLCableflowRestconf(object): + def __init__(self): + ws.set_port(8181) + + def topology(self): + ws.set_path('/restconf/operational/opendaylight-inventory:nodes') + content = ws.get() + j=json.loads(content[2]) + ws.show(j) + + def cableflow_list(self): + ws.set_path('/config/opendaylight-inventory:nodes/node/%d/flow-node-inventory:table/0/flow') + content = ws.get() + j=json.loads(content[2]) + ws.show(j) + #ws.show(content[2]) + return(j) + + def cableflow_update(self, flow): + ws.set_path('/restconf/config/opendaylight-inventory:nodes/node/openflow:%d/table/0/flow/%d"' % flow['node']['id'], flow['id'] ) + content = ws.post(flow) + j=json.loads(content[2]) + + def cableflow_list(self): + ws.set_path('/restconf/config/opendaylight-inventory:nodes/node/openflow:%d/table/0/flow/%d') + content = ws.get() + j=json.loads(content[2]) + ws.show(j) + #ws.show(content[2]) + + def cableflow_add(self, flow): +# PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:%d/table/0/flow/%d" + ws.set_path('/restconf/config/opendaylight-inventory:nodes/node/openflow:%d/table/0/flow/%d"' % flow['node']['id'], flow['id'] ) + ws.show(flow) + content = ws.put(flow) + #print content + flowadd_response_codes = { + 201:"Flow Config processed successfully", + 400:"Failed to create Static Flow entry due to invalid flow configuration", + 401:"User not authorized to perform this operation", + 404:"The Container Name or nodeId is not found", + 406:"Cannot operate on Default Container when other Containers are active", + 409:"Failed to create Static Flow entry due to Conflicting Name or configuration", + 500:"Failed to create Static Flow entry. Failure Reason included in HTTP Error response", + 503:"One or more of Controller services are unavailable", + } + msg=flowadd_response_codes.get(content[0]) + print content[0], content[1], msg + + def cableflow_remove(self, flow): + ws.set_path('/restconf/config/opendaylight-inventory:nodes/node/openflow:%d/table/0/flow/%d"' % flow['node']['id'], flow['id'] ) + content = ws.remove("", flow) + + flowdelete_reponse_codes = { + 204:"Flow Config deleted successfully", + 401:"User not authorized to perform this operation", + 404:"The Container Name or Node-id or Flow Name passed is not found", + 406:"Failed to delete Flow config due to invalid operation. Failure details included in HTTP Error response", + 500:"Failed to delete Flow config. Failure Reason included in HTTP Error response", + 503:"One or more of Controller service is unavailable", + } + msg=flowdelete_reponse_codes.get(content[0]) + print content[0], content[1], msg + + def cableflow_remove_all(self): + allFlowConfigs = self.cableflow_list() + flowConfigs = allFlowConfigs['flowConfig'] + for fl in flowConfigs: + print "Removing ", fl['name'] + self.cableflow_remove(fl) + + + + def statistics_flows(self): + ws.set_path('/controller/nb/v2/statistics/default/flow') + content = ws.get() + allFlowStats = json.loads(content[2]) + + flowStats = allFlowStats['flowStatistics'] + # These JSON dumps were handy when trying to parse the responses + #print json.dumps(flowStats[0]['flowStat'][1], indent = 2) + #print json.dumps(flowStats[4], indent = 2) + for fs in flowStats: + print "\nSwitch ID : " + fs['node']['id'] + print '{0:8} {1:8} {2:5} {3:15}'.format('Count', 'Action', 'Port', 'DestIP') + if not 'flowStatistic' in fs.values(): + print ' none' + continue + for aFlow in fs['flowStatistic']: + #print "*", aFlow, "*", " ", len(aFlow), " ", not aFlow + count = aFlow['packetCount'] + actions = aFlow['flow']['actions'] + actionType = '' + actionPort = '' + #print actions + if(type(actions) == type(list())): + actionType = actions[1]['type'] + actionPort = actions[1]['port']['id'] + else: + actionType = actions['type'] + actionPort = actions['port']['id'] + dst = aFlow['flow']['match']['matchField'][0]['value'] + print '{0:8} {1:8} {2:5} {3:15}'.format(count, actionType, actionPort, dst) + + + def cableflow_remove_all(self): + allFlowConfigs = self.cableflow_list() + flowConfigs = allFlowConfigs['flowConfig'] + for fl in flowConfigs: + print "Removing ", fl['name'] + self.cableflow_remove(fl) + + + +class CableflowTests(object): + def __init__(self): + self.flows = {} + def cmts_add_1(): + print "Add cmts 1 " + odl.cmts_add(cmts1) + + def cmts_add_2(): + print "Add cmts 2 " + odl.cmts_add(cmts2) + + def cmts_remove_1(): + print "Add cmts 1 " + odl.cmts_remove(cmts1) + + def cmts_remove_2(): + print "Add cmts 2 " + odl.cmts_remove(cmts2) + + def flow_add_1(): + print "Add Flow 1 " + odl.cableflow_add(flow1) + + + def flow_add_2(): + print "Add Flow 2 " + odl.cableflow_add(flow2) + + def flow_add_several(): + print "Add Flow Several " + odl.cableflow_add(flow1) + odl.cableflow_add(flow2) + odl.cableflow_add(flow3) + odl.cableflow_add(flow4) + odl.cableflow_add(flow5) + + + def flow_remove_1(): + print "Remove Flow 1 " + odl.cableflow_remove(flow1) + + def flow_remove_2(): + print "Remove Flow 2 " + odl.cableflow_remove(flow2) + + def flow_remove_all(): + print "Remove All Flows " + odl.cableflow_remove_all() + + def flow_list_stats(): + print "List Flow Stats" + odl.statistics_flows() + + def topology_list(): + print "List Topology " + odl.topology() + + def flow_list(): + print "List Flows " + odl.cableflow_list() + + + def flows_read(self, content_type='json'): + #print "content_type = %s" % content_type + for path, dirs, files in os.walk('.'): + for filename in files: + if filename.endswith(".%s" % content_type): + base_filename = basename(filename) + print base_filename + #print filename + with open(filename) as fp: + data = fp.read() + print(data) + # jdata = yaml.load ( data ) + # print(jdata) + self.flows[filename]=data #equivalent to: self.varname= 'something' + if content_type == "xml": + pprint (self.flows[filename], width=4) + else: + # pprint (self.flows[filename], width=4) + json.dumps(json.loads(data), indent=4) + + def exit_app(): + print "Quit " + exit(0) + +ws = RestfulAPI('127.0.0.1') + +if __name__ == "__main__": + ws.credentials('admin', 'admin') + odl = ODLCableflowRestconf() + tests = CableflowTests() + tests.flows_read() + + exit(0) + menu=Menu() + menu.run() + exit(0) + + + diff --git a/packetcable-client/xml2json b/packetcable-client/xml2json new file mode 100755 index 0000000..7657b9d --- /dev/null +++ b/packetcable-client/xml2json @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +"""xml2json.py Convert XML to JSON + +Relies on ElementTree for the XML parsing. This is based on +pesterfish.py but uses a different XML->JSON mapping. +The XML->JSON mapping is described at +http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html + +Rewritten to a command line utility by Hay Kranen < github.com/hay > with +contributions from George Hamilton (gmh04) and Dan Brown (jdanbrown) + +XML JSON + "e": null +text "e": "text" + "e": { "@name": "value" } +text "e": { "@name": "value", "#text": "text" } + texttext "e": { "a": "text", "b": "text" } + text text "e": { "a": ["text", "text"] } + text text "e": { "#text": "text", "a": "text" } + +This is very similar to the mapping used for Yahoo Web Services +(http://developer.yahoo.com/common/json.html#xml). + +This is a mess in that it is so unpredictable -- it requires lots of testing +(e.g. to see if values are lists or strings or dictionaries). For use +in Python this could be vastly cleaner. Think about whether the internal +form can be more self-consistent while maintaining good external +characteristics for the JSON. + +Look at the Yahoo version closely to see how it works. Maybe can adopt +that completely if it makes more sense... + +R. White, 2006 November 6 +""" + +import json +import optparse +import sys +import os + +import xml.etree.cElementTree as ET + + +def strip_tag(tag): + strip_ns_tag = tag + split_array = tag.split('}') + if len(split_array) > 1: + strip_ns_tag = split_array[1] + tag = strip_ns_tag + return tag + + +def elem_to_internal(elem, strip_ns=1, strip=1): + """Convert an Element into an internal dictionary (not JSON!).""" + + d = {} + elem_tag = elem.tag + if strip_ns: + elem_tag = strip_tag(elem.tag) + else: + for key, value in list(elem.attrib.items()): + d['@' + key] = value + + # loop over subelements to merge them + for subelem in elem: + v = elem_to_internal(subelem, strip_ns=strip_ns, strip=strip) + + tag = subelem.tag + if strip_ns: + tag = strip_tag(subelem.tag) + + value = v[tag] + + try: + # add to existing list for this tag + d[tag].append(value) + except AttributeError: + # turn existing entry into a list + d[tag] = [d[tag], value] + except KeyError: + # add a new non-list entry + d[tag] = value + text = elem.text + tail = elem.tail + if strip: + # ignore leading and trailing whitespace + if text: + text = text.strip() + if tail: + tail = tail.strip() + + if tail: + d['#tail'] = tail + + if d: + # use #text element if other attributes exist + if text: + d["#text"] = text + else: + # text is the value if no attributes + d = text or None + return {elem_tag: d} + + +def internal_to_elem(pfsh, factory=ET.Element): + + """Convert an internal dictionary (not JSON!) into an Element. + + Whatever Element implementation we could import will be + used by default; if you want to use something else, pass the + Element class as the factory parameter. + """ + + attribs = {} + text = None + tail = None + sublist = [] + tag = list(pfsh.keys()) + if len(tag) != 1: + raise ValueError("Illegal structure with multiple tags: %s" % tag) + tag = tag[0] + value = pfsh[tag] + if isinstance(value, dict): + for k, v in list(value.items()): + if k[:1] == "@": + attribs[k[1:]] = v + elif k == "#text": + text = v + elif k == "#tail": + tail = v + elif isinstance(v, list): + for v2 in v: + sublist.append(internal_to_elem({k: v2}, factory=factory)) + else: + sublist.append(internal_to_elem({k: v}, factory=factory)) + else: + text = value + e = factory(tag, attribs) + for sub in sublist: + e.append(sub) + e.text = text + e.tail = tail + return e + + +def elem2json(elem, options, strip_ns=1, strip=1): + + """Convert an ElementTree or Element into a JSON string.""" + + if hasattr(elem, 'getroot'): + elem = elem.getroot() + + if options.pretty: + return json.dumps(elem_to_internal(elem, strip_ns=strip_ns, strip=strip), sort_keys=True, indent=4, separators=(',', ': ')) + else: + return json.dumps(elem_to_internal(elem, strip_ns=strip_ns, strip=strip)) + + +def json2elem(json_data, factory=ET.Element): + + """Convert a JSON string into an Element. + + Whatever Element implementation we could import will be used by + default; if you want to use something else, pass the Element class + as the factory parameter. + """ + + return internal_to_elem(json.loads(json_data), factory) + + +def xml2json(xmlstring, options, strip_ns=1, strip=1): + + """Convert an XML string into a JSON string.""" + + elem = ET.fromstring(xmlstring) + return elem2json(elem, options, strip_ns=strip_ns, strip=strip) + + +def json2xml(json_data, factory=ET.Element): + + """Convert a JSON string into an XML string. + + Whatever Element implementation we could import will be used by + default; if you want to use something else, pass the Element class + as the factory parameter. + """ + if not isinstance(json_data, dict): + json_data = json.loads(json_data) + + elem = internal_to_elem(json_data, factory) + return ET.tostring(elem) + + +def main(): + p = optparse.OptionParser( + description='Converts XML to JSON or the other way around. Reads from standard input by default, or from file if given.', + prog='xml2json', + usage='%prog -t xml2json -o file.json [file]' + ) + p.add_option('--type', '-t', help="'xml2json' or 'json2xml'", default="xml2json") + p.add_option('--out', '-o', help="Write to OUT instead of stdout") + p.add_option( + '--strip_text', action="store_true", + dest="strip_text", help="Strip text for xml2json") + p.add_option( + '--pretty', action="store_true", + dest="pretty", help="Format JSON output so it is easier to read") + p.add_option( + '--strip_namespace', action="store_true", + dest="strip_ns", help="Strip namespace for xml2json") + p.add_option( + '--strip_newlines', action="store_true", + dest="strip_nl", help="Strip newlines for xml2json") + options, arguments = p.parse_args() + + inputstream = sys.stdin + if len(arguments) == 1: + try: + inputstream = open(arguments[0]) + except: + sys.stderr.write("Problem reading '{0}'\n".format(arguments[0])) + p.print_help() + sys.exit(-1) + + input = inputstream.read() + + strip = 0 + strip_ns = 0 + if options.strip_text: + strip = 1 + if options.strip_ns: + strip_ns = 1 + if options.strip_nl: + input = input.replace('\n', '').replace('\r','') + if (options.type == "xml2json"): + out = xml2json(input, options, strip_ns, strip) + else: + out = json2xml(input) + + if (options.out): + file = open(options.out, 'w') + file.write(out) + file.close() + else: + print(out) + +if __name__ == "__main__": + main() + diff --git a/packetcable-config/pom.xml b/packetcable-config/pom.xml new file mode 100644 index 0000000..bfb9650 --- /dev/null +++ b/packetcable-config/pom.xml @@ -0,0 +1,82 @@ + + + + 4.0.0 + + + packetcable + org.opendaylight.packetcable + 1.1-SNAPSHOT + + + + packetcable-config + org.opendaylight.packetcable + Configuration files for md-sal + + jar + + + 80-packetcable.xml + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/${configfile} + xml + config + + + + + + + + + + + scm:git:ssh://git.opendaylight.org:29418/packetcable.git + scm:git:ssh://git.opendaylight.org:29418/packetcable.git + HEAD + https://git.opendaylight.org/gerrit/gitweb?p=packetcable.git;a=summary + + diff --git a/packetcable-config/src/main/resources/80-packetcable.xml b/packetcable-config/src/main/resources/80-packetcable.xml new file mode 100644 index 0000000..84f4600 --- /dev/null +++ b/packetcable-config/src/main/resources/80-packetcable.xml @@ -0,0 +1,43 @@ + + + + + urn:opendaylight:params:xml:ns:yang:packetcable:packetcable-provider:impl?module=packetcable-provider-impl&revision=2014-01-31 + urn:opendaylight:params:xml:ns:yang:packetcable:packetcable-provider?module=packetcable-provider&revision=2014-01-31 + + + + + + + + prefix:packetcable-provider-impl + + packetcable-provider-default-impl + + binding:binding-broker-osgi-registry + binding-osgi-broker + + + + + + + + prefix:packetcable-provider + + + packetcable-provider-default + /modules/module[type='packetcable-provider-impl'][name='packetcable-provider-default-impl'] + + + + + + diff --git a/packetcable-driver/pom.xml b/packetcable-driver/pom.xml index dcf970f..d5b4f03 100644 --- a/packetcable-driver/pom.xml +++ b/packetcable-driver/pom.xml @@ -10,7 +10,7 @@ packetcable-driver bundle - + A lightweight implementation of PCMM COPS PDP client @@ -62,32 +62,18 @@ junit junit - 4.11 ch.qos.logback logback-core - 1.0.9 ch.qos.logback logback-classic - 1.0.9 com.google.guava guava - 13.0.1 - - - javax.sip - jain-sip-ri - 1.2.158 - - - commons-primitives - commons-primitives - 20041207.202534 @@ -111,9 +97,17 @@ + + org.apache.felix + maven-bundle-plugin + + + org.pcmm*, org.umu.cops* + + + maven-compiler-plugin - 3.0 1.7 1.7 diff --git a/packetcable-driver/src/main/java/org/pcmm/PCMMGlobalConfig.java b/packetcable-driver/src/main/java/org/pcmm/PCMMGlobalConfig.java index 4f7f605..3d141d6 100644 --- a/packetcable-driver/src/main/java/org/pcmm/PCMMGlobalConfig.java +++ b/packetcable-driver/src/main/java/org/pcmm/PCMMGlobalConfig.java @@ -51,10 +51,30 @@ public class PCMMGlobalConfig { */ /* LAB Bench Layout */ +/* Sunnyvale Lab +*/ + public static String DefaultCMTS = "10.200.90.3"; + public static String SubscriberID = "10.50.201.51"; + public static String dstIP = "10.200.90.10"; + public static String srcIP = "10.50.201.51"; + + /* Demo Kit Layout + public static String DefaultCMTS = "10.32.4.3"; + public static String SubscriberID = "10.32.104.2"; + public static String srcIP = "10.32.154.2"; + */ + +/* LAB Bench Layout + public static String DefaultCMTS = "10.32.15.3"; + public static String SubscriberID = "10.32.115.143"; + public static String dstIP = "10.32.0.234"; + public static String srcIP = "10.32.215.111"; + public static String DefaultCMTS = "10.32.15.3"; public static String SubscriberID = "10.32.115.143"; public static String dstIP = "10.32.0.234"; public static String srcIP = "10.32.215.111"; +*/ public static String DefautRadius = "192.168.50.2"; public static short srcPort = 8081; diff --git a/packetcable-karaf/pom.xml b/packetcable-karaf/pom.xml new file mode 100644 index 0000000..7b76595 --- /dev/null +++ b/packetcable-karaf/pom.xml @@ -0,0 +1,298 @@ + + + 4.0.0 + + packetcable + org.opendaylight.packetcable + 1.1-SNAPSHOT + + packetcable-karaf + pom + + 3.0 + + + + 1.0.0-SNAPSHOT + 1.4.2-SNAPSHOT + 3.0.1 + + + + + + org.apache.karaf.features + framework + ${karaf.version} + kar + + + org.apache.karaf.features + standard + ${karaf.version} + features + xml + runtime + + + + + org.opendaylight.controller + karaf.branding + ${branding.version} + compile + + + + + org.opendaylight.controller + opendaylight-karaf-resources + ${karaf.resources.version} + + + + + + org.opendaylight.controller + features-mdsal + features + ${project.version} + xml + runtime + + + org.opendaylight.packetcable + features-packetcable + features + ${project.version} + xml + runtime + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.felix + maven-bundle-plugin + [0,) + + cleanVersions + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + [0,) + + copy + unpack + + + + + + + + + org.apache.karaf.tooling + karaf-maven-plugin + [0,) + + commands-generate-help + + + + + + + + + org.fusesource.scalate + maven-scalate-plugin + [0,) + + sitegen + + + + + + + + + org.apache.servicemix.tooling + depends-maven-plugin + [0,) + + generate-depends-file + + + + + + + + + + + + + + + org.apache.karaf.tooling + karaf-maven-plugin + ${karaf.version} + true + + + standard + odl-mdsal-apidocs + odl-packetcable-provider + + + + + + + process-resources + + install-kars + + process-resources + + + package + + instance-create-archive + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.6 + + + copy + + copy + + generate-resources + + + + org.opendaylight.controller + karaf.branding + ${karaf.branding.version} + target/assembly/lib + karaf.branding-${branding.version}.jar + + + + + + unpack-karaf-resources + + unpack-dependencies + + prepare-package + + ${project.build.directory}/assembly + org.opendaylight.controller + opendaylight-karaf-resources + META-INF\/** + true + false + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + prepare-package + + run + + + + + + + + + + + + + + + + + + + + + + + scm:git:ssh://git.opendaylight.org:29418/packetcable.git + scm:git:ssh://git.opendaylight.org:29418/packetcable.git + HEAD + https://git.opendaylight.org/gerrit/gitweb?p=packetcable.git;a=summary + + diff --git a/packetcable-model/src/main/yang/packetcable-cmts.yang b/packetcable-model/src/main/yang/packetcable-cmts.yang index e07aa70..02af8c2 100644 --- a/packetcable-model/src/main/yang/packetcable-cmts.yang +++ b/packetcable-model/src/main/yang/packetcable-cmts.yang @@ -5,6 +5,8 @@ module packetcable-cmts import ietf-yang-types { prefix yang; } import ietf-inet-types { prefix inet; } + import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} + import yang-ext {prefix ext; revision-date "2013-07-09";} // import ietf-interfaces { prefix if; } // import ietf-snmp { prefix snmp; } // import ietf-reverse-ssh { prefix rssh; } @@ -15,176 +17,24 @@ module packetcable-cmts revision "2014-01-20" { description "Initial revision of packetcable cmts"; } - - -typedef pcmm-version -{ - type enumeration { - enum "1"; - enum "2"; - enum "3"; - enum "4"; - enum "5"; - } - description "This enumeration contains the all PCMM versions released so far."; -} -typedef up-down-state-type { - type enumeration { - enum up; - enum down; - } - description "Type to specify state information for a port or a connection."; -} - -grouping cable-modem-subscriber-grouping -{ - description "A cable modem subscriber terminated by CMTS instance and it's configuration resources."; - leaf enabled { - type boolean; - mandatory true; - description "Specifies if the CM is enabled."; - } - - leaf subscriber-id { + grouping cmts-node-attributes { + description "A PCMM capable CMTS and other available configuration resources."; + + leaf address { type inet:ip-address; - mandatory true; - description "An identifier that identifies a cable modem. The IP address of the CM."; - } - leaf mac-address { - type yang:mac-address; - description "The MAC address of the CM."; - } -} - -typedef cmts-reference { - type instance-identifier; -} - - -grouping cmts-instance -{ - description "A PCMM capable CMTS and other available configuration resources."; - leaf id { - type inet:ip-address; - mandatory true; - description - "An unique but locally arbitrary identifier that identifies a PCMM capable CMTS - towards the management system and is persistent across reboots of the system."; - } - - leaf enabled { - type boolean; - mandatory true; - description "Specifies if the CMTS is enabled."; - } - - container managed-cable-modem-subscribers { - list managed-cable-modem-subscribers { - key "subscriber-id"; - unique "subscriber-id"; - description - "The list of all cable modems managed by CMTS instance."; - uses cable-modem-subscriber-grouping; - } - } - - container configuration-points { - list configuration-points { - key "id"; - unique "id"; - description - "The list of all configuration points known to the PCMM capable CMTS."; - uses cmts-configuration-point-grouping; - } - } -} - -grouping cmts-configuration-point-grouping -{ - description "Representation of a PCMM Configuration Point."; - leaf id { - type inet:uri; - description "An identifier that identifies a configuration point of the PCMM capable CMTS."; - } - leaf uri { - type inet:uri; - description - "A locator of the Configuration Point. This element MAY contain a locator - of the Configuration Point including, for example, an IP address and a port number."; - } - leaf protocols-supported { - type enumeration { - enum "pcmm"; - enum "snmp"; - enum "ssh"; - enum "telnet"; - enum "netconf"; - } - default "pcmm"; - description "The protocols that can used to configure the CMTS."; - } - leaf mac-address { - type yang:mac-address; - description "The MAC address of the CMTS for the NODE ID."; - } - container pcmm-configuration { - leaf ip-address { - type inet:ip-address; - mandatory true; - description "The IP address of the controller to connect to."; + description "IP Address of CMTS"; } + leaf port { type inet:port-number; - default 3918; - description "The port number at the controller to connect to."; - } - } - container snmp-configuration { -/* - leaf snmp-version { - type snmp:security-model; - default "v2c"; - } -*/ - reference "Sort out the SNMP yang declaration"; - leaf community-public { - type string; - description - "A community name that can be represented as a YANG string."; + description "TCP port number to connect"; } } - container shell-configuration { - leaf username { - type string; - description - "SSH or telnet username."; - } - reference "Sort out how to hide."; - leaf password { - type string; - description - "SSH or telnet password."; - } - } - container state { - description - "This container holds connection state information that indicate if the CMTS - is connected, what versions are supported, and which one is used."; - leaf connection-state { - type up-down-state-type; - description - "This object indicates if the Logical Switch is connected to the controller."; - } - leaf current-version { - type pcmm-version; - description - "This object contains the current PCMM version used between CMTS and Controller."; - } - leaf-list supported-versions { - type pcmm-version; - description - "This list of objects contains all the PCMM versions supported the controller."; + + augment "/inv:nodes/inv:node" { + ext:augment-identifier "cmts-capable-node"; + container cmts-node { + uses cmts-node-attributes ; } } } -} diff --git a/packetcable-model/src/main/yang/packetcable-match-types.yang b/packetcable-model/src/main/yang/packetcable-match-types.yang index 0a1abe1..1b5adbd 100644 --- a/packetcable-model/src/main/yang/packetcable-match-types.yang +++ b/packetcable-model/src/main/yang/packetcable-match-types.yang @@ -1,180 +1,188 @@ module packetcable-match-types { - namespace "urn:opendaylight:model:match:types"; - prefix "match"; - - import ietf-inet-types {prefix inet; } + namespace "urn:opendaylight:packetcable:match:types"; + prefix "packet-cable-match"; + + import yang-ext {prefix ext; revision-date "2013-07-09";} + import flow-node-inventory {prefix fni; revision-date "2013-08-19"; } + import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} + import sal-flow {prefix sal-flow;revision-date "2013-08-19";} + import packet-processing {prefix sal-packet;revision-date "2013-07-09";} + import ietf-inet-types {prefix inet; revision-date "2010-09-24";} + import ietf-yang-types {prefix yang; revision-date "2010-09-24";} + import opendaylight-flow-types {prefix flow;revision-date "2013-10-26";} + import opendaylight-flow-statistics {prefix odl-flow-stats;revision-date "2013-08-19";} revision "2014-01-20" { description "Initial revision of packetcable match types"; } - grouping "ip-match-fields" { - leaf ip-protocol { - description "IP protocol."; - type uint8; - } - - leaf ip-dscp { - description "IP DSCP (6 bits in ToS field)."; - type inet:dscp; - } - - leaf ip-ecn { - description "IP ECN (2 bits in ToS field)."; - type uint8; - } - - leaf ip-proto { - description "IP Proto (IPv4 or IPv6 Protocol Number)."; - type inet:ip-version; + grouping "udp-match-ranges-attributes" { + container upd-match-ranges { + leaf udp-source-port-start { + description "UDP source port start."; + type inet:port-number; + } + leaf udp-source-port-end { + description "UDP source port end."; + type inet:port-number; + } + leaf udp-destination-port-start { + description "UDP destination port start."; + type inet:port-number; + } + leaf udp-destination-port-end { + description "UDP destination port end."; + type inet:port-number; + } } } - grouping "ipv4-match-fields" { - leaf ipv4-source { - description "IPv4 source address."; - type inet:ipv4-prefix; - } - - leaf ipv4-destination { - description "IPv4 destination address."; - type inet:ipv4-prefix; - } - + + // MATCH augmentations for udp-match-range + // RPCS + augment "/sal-flow:add-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "udp-match-ranges-rpc-add-flow"; + uses udp-match-ranges-attributes; + } + augment "/sal-flow:remove-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "udp-match-ranges-rpc-remove-flow"; + uses udp-match-ranges-attributes; + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:original-flow/sal-flow:match" { + ext:augment-identifier "udp-match-ranges-rpc-update-flow-original"; + uses udp-match-ranges-attributes; + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:updated-flow/sal-flow:match" { + ext:augment-identifier "udp-match-ranges-rpc-update-flow-updated"; + uses udp-match-ranges-attributes; } - grouping "ipv6-match-fields" { - leaf ipv6-source { - description "IPv6 source address."; - type inet:ipv6-prefix; - } - - leaf ipv6-destination { - description "IPv6 destination address."; - type inet:ipv6-prefix; - } - - leaf ipv6-nd-target { - description "IPv6 target address for neighbour discovery message"; - type inet:ipv6-address; - } + // DATA + augment "/inv:nodes/inv:node/fni:table/fni:flow/fni:match" { + ext:augment-identifier "udp-match-ranges-nodes-node-table-flow"; + uses udp-match-ranges-attributes; + } - container "ipv6-label" { - leaf ipv6-flabel { - type inet:ipv6-flow-label; + // NOTIFICATIONS + augment "/sal-flow:switch-flow-removed/sal-flow:match" { + ext:augment-identifier "udp-match-ranges-notif-switch-flow-removed"; + uses udp-match-ranges-attributes; + } + augment "/sal-packet:packet-received/sal-packet:match" { + ext:augment-identifier "udp-match-ranges-notif-packet-in"; + uses udp-match-ranges-attributes; + } + augment "/odl-flow-stats:flows-statistics-update/odl-flow-stats:flow-and-statistics-map-list/odl-flow-stats:match" { + ext:augment-identifier "udp-match-ranges-notif-update-flow-stats"; + uses udp-match-ranges-attributes; + } + + grouping "tcp-match-ranges-attributes" { + container tcp-match-ranges { + leaf tcp-source-port-start { + description "TCP source port start."; + type inet:port-number; } - - leaf flabel-mask { - type binary; + leaf tcp-source-port-end { + description "TCP source port end."; + type inet:port-number; + } + leaf tcp-destination-port-begin { + description "TCP destination port begin."; + type inet:port-number; + } + leaf tcp-destination-port-end { + description "TCP destination port end."; + type inet:port-number; } - } - - leaf ipv6-exthdr { - description "IPv6 Extension Header field"; - type uint16; } } - - - grouping "udp-match-fields" { - leaf udp-source-port { - description "UDP source port."; - type inet:port-number; - } - leaf udp-destination-port { - description "UDP destination port."; - type inet:port-number; - } + +// MATCH augmentations for tcp-match-range +// RPCS + augment "/sal-flow:add-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "tcp-match-ranges-rpc-add-flow"; + uses tcp-match-ranges-attributes; } - - grouping "tcp-match-fields" { - leaf tcp-source-port { - description "TCP source port."; - type inet:port-number; - } - leaf tcp-destination-port { - description "TCP destination port."; - type inet:port-number; - } + augment "/sal-flow:remove-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "tcp-match-ranges-rpc-remove-flow"; + uses tcp-match-ranges-attributes; } - - grouping "udp-match-ranges" { - leaf udp-source-port-start { - description "UDP source port start."; - type inet:port-number; - } - leaf udp-source-port-end { - description "UDP source port end."; - type inet:port-number; - } - leaf udp-destination-port-start { - description "UDP destination port start."; - type inet:port-number; - } - leaf udp-destination-port-end { - description "UDP destination port end."; - type inet:port-number; - } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:original-flow/sal-flow:match" { + ext:augment-identifier "tcp-match-ranges-rpc-update-flow-original"; + uses tcp-match-ranges-attributes; + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:updated-flow/sal-flow:match" { + ext:augment-identifier "tcp-match-ranges-rpc-update-flow-updated"; + uses tcp-match-ranges-attributes; } - grouping "tcp-match-ranges" { - leaf tcp-source-port-start { - description "TCP source port start."; - type inet:port-number; - } - leaf tcp-source-port-end { - description "TCP source port end."; - type inet:port-number; - } - leaf tcp-destination-port-begin { - description "TCP destination port begin."; - type inet:port-number; - } - leaf tcp-destination-port-end { - description "TCP destination port end."; - type inet:port-number; - } +// DATA + augment "/inv:nodes/inv:node/fni:table/fni:flow/fni:match" { + ext:augment-identifier "tcp-match-ranges-nodes-node-table-flow"; + uses tcp-match-ranges-attributes; } - grouping match { +// NOTIFICATIONS + augment "/sal-flow:switch-flow-removed/sal-flow:match" { + ext:augment-identifier "tcp-match-ranges-notif-switch-flow-removed"; + uses tcp-match-ranges-attributes; + } + augment "/sal-packet:packet-received/sal-packet:match" { + ext:augment-identifier "tcp-match-ranges-notif-packet-in"; + uses tcp-match-ranges-attributes; + } + augment "/odl-flow-stats:flows-statistics-update/odl-flow-stats:flow-and-statistics-map-list/odl-flow-stats:match" { + ext:augment-identifier "tcp-match-ranges-notif-update-flow-stats"; + uses tcp-match-ranges-attributes; + } - container "ip-match" { - uses "ip-match-fields"; + grouping subscriber-id { + leaf subscriber-id { + type inet:ip-address; + description "Subscriber Id"; } + } + +// MATCH augmentations for susbcriber-id +// RPCS + augment "/sal-flow:add-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "subscriber-id-rpc-add-flow"; + uses subscriber-id; + } + augment "/sal-flow:remove-flow/sal-flow:input/sal-flow:match" { + ext:augment-identifier "subscriber-id-rpc-remove-flow"; + uses subscriber-id; + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:original-flow/sal-flow:match" { + ext:augment-identifier "subscriber-id-rpc-update-flow-original"; + uses subscriber-id; + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:updated-flow/sal-flow:match" { + ext:augment-identifier "subscriber-id-rpc-update-flow-updated"; + uses subscriber-id; + } - choice layer-3-match { - case "ipv4-match" { - uses "ipv4-match-fields"; - } - case "ipv6-match" { - uses "ipv6-match-fields"; - } - } +// DATA + augment "/inv:nodes/inv:node/fni:table/fni:flow/fni:match" { + ext:augment-identifier "subscriber-id-nodes-node-table-flow"; + uses subscriber-id; + } - description "if tpSrc then tpSrcStart = tpSrcEnd = tpSrc"; - choice layer-4-match { - case "udp-match" { - choice "udp-field-range" { - case "udp-field" { - uses "udp-match-fields"; - } - case "udp-range" { - uses "udp-match-ranges"; - } - } - } - case "tcp-match" { - choice "tcp-field-range" { - case "tcp-field" { - uses "tcp-match-fields"; - } - case "tcp-range" { - uses "tcp-match-ranges"; - } - } - } - } +// NOTIFICATIONS + augment "/sal-flow:switch-flow-removed/sal-flow:match" { + ext:augment-identifier "subscriber-id-notif-switch-flow-removed"; + uses subscriber-id; + } + augment "/sal-packet:packet-received/sal-packet:match" { + ext:augment-identifier "subscriber-id-notif-packet-in"; + uses subscriber-id; } + augment "/odl-flow-stats:flows-statistics-update/odl-flow-stats:flow-and-statistics-map-list/odl-flow-stats:match" { + ext:augment-identifier "subscriber-id-notif-update-flow-stats"; + uses subscriber-id; + } + } diff --git a/packetcable-model/src/main/yang/packetcable-service.yang b/packetcable-model/src/main/yang/packetcable-service.yang deleted file mode 100644 index b4b4afc..0000000 --- a/packetcable-model/src/main/yang/packetcable-service.yang +++ /dev/null @@ -1,380 +0,0 @@ -module packetcable-service{ - namespace "urn:opendaylight:packetcable:service"; - prefix pcmm; - - import yang-ext {prefix ext; revision-date "2013-07-09";} - import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} - import ietf-inet-types {prefix inet;revision-date 2010-09-24;} - import packetcable-cmts {prefix cmts; } - import packetcable-traffic-profile {prefix tp; } - import flow-capable-transaction {prefix tr;} - - - revision "2014-01-20" { - description "Initial revision of packetcable service"; - } - - grouping node-cmts { - uses "inv:node-context-ref"; - uses cmts:cmts-instance; - } - - /** Base configuration structure **/ - grouping update-cmts { - uses "inv:node-context-ref"; - - container original-cmts { - uses cmts:cmts-instance; - } - container updated-cmts { - uses cmts:cmts-instance; - } - } - - rpc cmts-add { - input { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses node-cmts; - } - output { - uses tr:transaction-aware; - } - } - - rpc cmts-remove { - input { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses node-cmts; - } - output { - uses tr:transaction-aware; - } - } - - rpc cmts-update { - input { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses update-cmts; - } - output { - uses tr:transaction-aware; - } - } - - notification cmts-added { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses node-cmts; - uses tr:transaction-aware; - } - - notification cmts-updated { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses node-cmts; - uses tr:transaction-aware; - } - - notification cmts-removed { - uses tr:transaction-metadata; - leaf cmts-ref { - type cmts:cmts-reference; - } - uses node-cmts; - uses tr:transaction-aware; - } - - grouping update-tp-defaults-flowspec { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:flowspec-envelope; - } - container update-tp { - uses tp:flowspec-envelope; - } - } - - rpc traffic-profile-get-defaults-flowspec { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-flowspec; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-flowspec { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-flowspec; - } - output { - uses tr:transaction-aware; - } - } - - grouping update-tp-defaults-docsis-service-class-name { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:flowspec-envelope; - } - container update-tp { - uses tp:flowspec-envelope; - } - } - - grouping update-tp-defaults-best-effort { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:default-envelope; - } - container update-tp { - uses tp:default-envelope; - } - } - - rpc traffic-profile-get-defaults-best-effort { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-best-effort; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-best-effort { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-best-effort; - } - output { - uses tr:transaction-aware; - } - } - - - grouping update-tp-defaults-non-real-time-polling-service { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:default-envelope; - } - container update-tp { - uses tp:default-envelope; - } - } - - rpc traffic-profile-get-defaults-non-real-time-polling-service { - - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-non-real-time-polling-service; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-non-real-time-polling-service { - - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-non-real-time-polling-service; - } - output { - uses tr:transaction-aware; - } - } - - - grouping update-tp-defaults-real-time-polling-service { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:default-envelope; - } - container update-tp { - uses tp:default-envelope; - } - } - - rpc traffic-profile-get-defaults-real-time-polling-service { - - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-real-time-polling-service; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-real-time-polling-service { - - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-real-time-polling-service; - } - output { - uses tr:transaction-aware; - } - } - - grouping update-tp-defaults-unsolicited-grant-service { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:ugs-envelope; - } - container update-tp { - uses tp:ugs-envelope; - } - } - - rpc traffic-profile-get-defaults-unsolicited-grant-service { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-unsolicited-grant-service; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-unsolicited-grant-service { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-unsolicited-grant-service; - } - output { - uses tr:transaction-aware; - } - } - - grouping update-tp-defaults-unsolicited-grant-service-with-activity-detection { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:ugs-envelope; - } - container update-tp { - uses tp:ugs-envelope; - } - } - - rpc traffic-profile-get-defaults-unsolicited-grant-service-with-activity-detection { - - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-unsolicited-grant-service-with-activity-detection; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-unsolicited-grant-service-with-activity-detection { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-unsolicited-grant-service-with-activity-detection; - } - output { - uses tr:transaction-aware; - } - } - - - grouping update-tp-defaults-downstream-service { - // uses "tp:tp-context-ref"; - - container original-tp { - uses tp:us-envelope; - } - - container update-tp { - uses tp:us-envelope; - } - } - - rpc traffic-profile-get-defaults-downstream-service { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - } - output { - uses update-tp-defaults-downstream-service; - uses tr:transaction-aware; - } - } - - rpc traffic-profile-update-defaults-downstream-service { - input { - uses tr:transaction-metadata; - leaf tp-ref { - type tp:tp-reference; - } - uses update-tp-defaults-downstream-service; - } - output { - uses tr:transaction-aware; - } - } - - -} diff --git a/packetcable-model/src/main/yang/packetcable-traffic-profile.yang b/packetcable-model/src/main/yang/packetcable-traffic-profile.yang index 23e270d..41ae2df 100644 --- a/packetcable-model/src/main/yang/packetcable-traffic-profile.yang +++ b/packetcable-model/src/main/yang/packetcable-traffic-profile.yang @@ -2,10 +2,18 @@ module packetcable-traffic-profile { namespace "urn:opendaylight:flow:traffic-profile"; prefix traffic; + + import flow-node-inventory {prefix fni; revision-date 2013-08-19; } + import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} + import sal-flow {prefix sal-flow;revision-date "2013-08-19";} + import sal-group {prefix sal-group;revision-date "2013-09-18";} + import packet-processing {prefix sal-packet;revision-date "2013-07-09";} + import opendaylight-flow-statistics {prefix odl-flow-stats;revision-date "2013-08-19";} + import opendaylight-group-statistics {prefix odl-group-stats;revision-date "2013-11-11";} organization "OpenDaylight Project"; contact "TBD"; - + description "This module contains a collection of groupings and data definition statements related to the configuration @@ -14,7 +22,6 @@ module packetcable-traffic-profile revision "2014-08-08" { description "Initial revision of packetcable traffic profile"; } - typedef tp-reference { @@ -72,7 +79,7 @@ module packetcable-traffic-profile } - grouping flowspec-envelope { + grouping flowspec-envelope-attributes { description " The values r, b, p, m, M, R, and s are defined and described @@ -169,7 +176,7 @@ Slack Term [S] } } - grouping default-envelope { + grouping default-envelope-attributes { leaf traffic-priority { type uint8; description @@ -298,7 +305,7 @@ Maximum Buffer is a 4-byte unsigned integer parameter that defines an upper limi } - grouping ugs-envelope { + grouping ugs-envelope-attributes { leaf request-transmission-policy { type uint32; description " @@ -366,7 +373,7 @@ Attribute Masks define a specific set of attributes associated with a DOCSIS 3.0 } - grouping us-envelope { + grouping us-envelope-attributes { leaf us-traffic-priority { type uint8; description " @@ -473,23 +480,23 @@ Attribute Masks define a specific set of attributes associated with a DOCSIS 3.0 } - grouping traffic-profile-flowspec { + grouping traffic-profile-flowspec-attributes { container f-authorized-envelope { - uses flowspec-envelope; + uses flowspec-envelope-attributes; description "mandatory"; } container f-reserved-envelope { - uses flowspec-envelope; + uses flowspec-envelope-attributes; description "optional"; } container f-committed-envelope { - uses flowspec-envelope; + uses flowspec-envelope-attributes; description "optional"; } } - grouping traffic-profile-docsis-service-class-name { + grouping traffic-profile-docsis-service-class-name-attributes { leaf service-class-name { type string; description @@ -504,127 +511,348 @@ Attribute Masks define a specific set of attributes associated with a DOCSIS 3.0 } - grouping traffic-profile-best-effort { + grouping traffic-profile-best-effort-attributes { container be-authorized-envelope { - uses default-envelope; + uses default-envelope-attributes; description "mandatory"; } container bereserved-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } container be-committed-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } } - grouping traffic-profile-non-real-time-polling-service { + grouping traffic-profile-non-real-time-polling-service-attributes { container nrtp-authorized-envelope { - uses default-envelope; + uses default-envelope-attributes; description "mandatory"; } container nrtp-reserved-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } container nrtp-committed-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } } - grouping traffic-profile-real-time-polling-service { + grouping traffic-profile-real-time-polling-service-attributes { container rtp-authorized-envelope { - uses default-envelope; + uses default-envelope-attributes; description "mandatory"; } container rtp-reserved-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } container rtp-committed-envelope { - uses default-envelope; + uses default-envelope-attributes; description "optional"; } } - grouping traffic-profile-unsolicited-grant-service { + grouping traffic-profile-unsolicited-grant-service-attributes { container ugs-authorized-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "mandatory"; } container ugs-reserved-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "optional"; } container ugs-committed-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "optional"; } } - grouping traffic-profile-unsolicited-grant-service-with-activity-detection { + grouping traffic-profile-unsolicited-grant-service-with-activity-detection-attributes { container usga-authorized-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "mandatory"; } container usga-reserved-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "optional"; } container usga-committed-envelope { - uses ugs-envelope; + uses ugs-envelope-attributes; description "optional"; } } - grouping traffic-profile-downstream-service { + grouping traffic-profile-downstream-service-attributes { container ds-authorized-envelope { - uses us-envelope; + uses us-envelope-attributes; description "mandatory"; } container ds-reserved-envelope { - uses us-envelope; + uses us-envelope-attributes; description "optional"; } container ds-committed-envelope { - uses us-envelope; + uses us-envelope-attributes; description "optional"; } } - grouping traffic-profile-upstream-drop { + grouping traffic-profile-upstream-drop-attributes { } - grouping traffic-profile-docsis-specific-parameterization { + grouping traffic-profile-docsis-specific-parameterization-attributes { } - grouping traffic-profile-grouping { + grouping traffic-profile-grouping-attributes { leaf tp-type { type traffic-profile-type; default best-effort; description "This attribute contains the type of upstream flow scheduling type."; } - choice tp-type-choice { - case "flowspec" { uses traffic-profile-flowspec; } - case "docsis-service-class-name" { uses traffic-profile-docsis-service-class-name; } - case "docsis-specific-parameterization" { uses traffic-profile-docsis-specific-parameterization; } - case "upstream-drop" { uses traffic-profile-upstream-drop; } - case "best-effort" { uses traffic-profile-best-effort; } - case "unsolicited-grant-service" { uses traffic-profile-unsolicited-grant-service; } - case "unsolicited-grant-service-with-activity-detection" { uses traffic-profile-unsolicited-grant-service-with-activity-detection; } - case "non-real-time-polling-service" { uses traffic-profile-non-real-time-polling-service; } - case "real-time-polling-service" { uses traffic-profile-real-time-polling-service; } - case "downstream-service" { uses traffic-profile-downstream-service; } - } } +// ACTION augmentations + + augment "/sal-flow:add-flow/sal-flow:input/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:write-actions-case/sal-flow:write-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + + augment "/sal-flow:add-flow/sal-flow:input/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:apply-actions-case/sal-flow:apply-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-flow:remove-flow/sal-flow:input/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:write-actions-case/sal-flow:write-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-flow:remove-flow/sal-flow:input/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:apply-actions-case/sal-flow:apply-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:original-flow/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:write-actions-case/sal-flow:write-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:original-flow/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:apply-actions-case/sal-flow:apply-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:updated-flow/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:write-actions-case/sal-flow:write-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-flow:update-flow/sal-flow:input/sal-flow:updated-flow/sal-flow:instructions/sal-flow:instruction/sal-flow:instruction/sal-flow:apply-actions-case/sal-flow:apply-actions/sal-flow:action/sal-flow:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-group:add-group/sal-group:input/sal-group:buckets/sal-group:bucket/sal-group:action/sal-group:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-group:remove-group/sal-group:input/sal-group:buckets/sal-group:bucket/sal-group:action/sal-group:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-group:update-group/sal-group:input/sal-group:original-group/sal-group:buckets/sal-group:bucket/sal-group:action/sal-group:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-group:update-group/sal-group:input/sal-group:updated-group/sal-group:buckets/sal-group:bucket/sal-group:action/sal-group:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/sal-packet:transmit-packet/sal-packet:input/sal-packet:action/sal-packet:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/inv:nodes/inv:node/fni:table/fni:flow/fni:instructions/fni:instruction/fni:instruction/fni:write-actions-case/fni:write-actions/fni:action/fni:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/inv:nodes/inv:node/fni:table/fni:flow/fni:instructions/fni:instruction/fni:instruction/fni:apply-actions-case/fni:apply-actions/fni:action/fni:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/inv:nodes/inv:node/fni:group/fni:buckets/fni:bucket/fni:action/fni:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/odl-flow-stats:flows-statistics-update/odl-flow-stats:flow-and-statistics-map-list/odl-flow-stats:instructions/odl-flow-stats:instruction/odl-flow-stats:instruction/odl-flow-stats:write-actions-case/odl-flow-stats:write-actions/odl-flow-stats:action/odl-flow-stats:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/odl-flow-stats:flows-statistics-update/odl-flow-stats:flow-and-statistics-map-list/odl-flow-stats:instructions/odl-flow-stats:instruction/odl-flow-stats:instruction/odl-flow-stats:apply-actions-case/odl-flow-stats:apply-actions/odl-flow-stats:action/odl-flow-stats:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } + augment "/odl-group-stats:group-desc-stats-updated/odl-group-stats:group-desc-stats/odl-group-stats:buckets/odl-group-stats:bucket/odl-group-stats:action/odl-group-stats:action" { + case "flowspec-case" { container flowspec {uses traffic-profile-flowspec-attributes; } } + case "docsis-service-class-name-case" { container docsis-service-class-name {uses traffic-profile-docsis-service-class-name-attributes; } } + case "docsis-specific-parameterization-case" { container docsis-specific-parameterization {uses traffic-profile-docsis-specific-parameterization-attributes; }} + case "upstream-drop-case" { container upstream-drop {uses traffic-profile-upstream-drop-attributes; } } + case "best-effort-case" { container best-effort {uses traffic-profile-best-effort-attributes; } } + case "unsolicited-grant-service-case" { container unsolicited-grant-service {uses traffic-profile-unsolicited-grant-service-attributes; } } + case "unsolicited-grant-service-with-activity-detection-case" { container unsolicited-grant-service-with-activity-detection {uses traffic-profile-unsolicited-grant-service-with-activity-detection-attributes; } } + case "non-real-time-polling-service-case" { container non-real-time-polling-service {uses traffic-profile-non-real-time-polling-service-attributes; } } + case "real-time-polling-service-case" { container real-time-polling-service {uses traffic-profile-real-time-polling-service-attributes; } } + case "downstream-service-case" { container downstream-service {uses traffic-profile-downstream-service-attributes; }} + } // grouping taffic-profile-default-singleton-grouping { // grouping flowspec { uses traffic-profile-flowspec; } diff --git a/packetcable-provider/pom.xml b/packetcable-provider/pom.xml index 0bfb97f..c9e35b7 100644 --- a/packetcable-provider/pom.xml +++ b/packetcable-provider/pom.xml @@ -15,6 +15,11 @@ + + ${project.groupId} + packetcable-driver + ${project.version} + ${project.groupId} packetcable-model @@ -52,12 +57,12 @@ - - maven-checkstyle-plugin - - true - - + + maven-checkstyle-plugin + + true + + org.apache.felix diff --git a/packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModule.java b/packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModule.java deleted file mode 100644 index ab0c880..0000000 --- a/packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModule.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.opendaylight.controller.config.yang.config.packetcable_provider.impl; - -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder; - -public class PacketcableProviderModule - extends - org.opendaylight.controller.config.yang.config.packetcable_provider.impl.AbstractPacketcableProviderModule { - public PacketcableProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { - super(identifier, dependencyResolver); - } - - public PacketcableProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.packetcable_provider.impl.PacketcableProviderModule oldModule, java.lang.AutoCloseable oldInstance) { - super(identifier, dependencyResolver, oldModule, oldInstance); - } - - @Override - public void customValidation() { - // add custom validation form module attributes here. - } -// - @Override - public java.lang.AutoCloseable createInstance() { -// final OpendaylightPacketcableProvider opendaylightPcmmProvider = new OpendaylightPacketcableProvider(); -// -// // Register to md-sal -// opendaylightPcmmProvider.setNotificationProvider(getNotificationServiceDependency()); -// -// DataBroker dataBrokerService = getDataBrokerDependency(); -// opendaylightPcmmProvider.setDataProvider(dataBrokerService); -// -// final ListenerRegistration dataChangeListenerRegistration = dataBrokerService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, OpendaylightPacketcableProvider.TOASTER_IID, opendaylightPcmmProvider, DataChangeScope.SUBTREE); -// -// final BindingAwareBroker.RpcRegistration rpcRegistration = getRpcRegistryDependency().addRpcImplementation(ToasterService.class, opendaylightPcmmProvider); -// -// // Register runtimeBean for toaster statistics via JMX -// final PacketcableProviderRuntimeRegistration runtimeReg = getRootRuntimeBeanRegistratorWrapper().register(opendaylightPcmmProvider); -// -// // Wrap PCMM driver as AutoCloseable and close registrations to md-sal at -// // close() -// final class AutoCloseablePcmmProvider implements AutoCloseable { -// -// @Override -// public void close() throws Exception { -// dataChangeListenerRegistration.close(); -// rpcRegistration.close(); -// runtimeReg.close(); -// opendaylightPcmmProvider.close(); -// -// log.info("Toaster provider (instance {}) torn down.", this); -// } -// } -// -// AutoCloseable ret = new AutoCloseablePcmmProvider(); -// log.info("Toaster provider (instance {}) initialized.", ret); -// return ret; - return null; - } - -} diff --git a/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpenDaylightPacketCableProviderService.java b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpenDaylightPacketCableProviderService.java new file mode 100644 index 0000000..63e8198 --- /dev/null +++ b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpenDaylightPacketCableProviderService.java @@ -0,0 +1,20 @@ +package org.opendaylight.controller.packetcable.provider; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileBestEffortAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileDocsisServiceClassNameAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileFlowspecAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; +import org.pcmm.gates.IClassifier; +import org.pcmm.gates.ITrafficProfile; + +public interface OpenDaylightPacketCableProviderService { + + public ITrafficProfile buildTrafficProfile(TrafficProfileBestEffortAttributes bestEffort); + + public ITrafficProfile buildTrafficProfile(TrafficProfileFlowspecAttributes flowSpec); + + public ITrafficProfile buildTrafficProfile(TrafficProfileDocsisServiceClassNameAttributes docsis); + + public IClassifier buildClassifier(Match sid); + +} diff --git a/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpendaylightPacketcableProvider.java b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpendaylightPacketcableProvider.java index 85d0d2e..5501153 100644 --- a/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpendaylightPacketcableProvider.java +++ b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/OpendaylightPacketcableProvider.java @@ -1,81 +1,88 @@ package org.opendaylight.controller.packetcable.provider; -import java.util.Iterator; -import java.util.List; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Collection; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; -import org.opendaylight.controller.config.yang.config.packetcable_provider.impl.PacketcableProviderRuntimeMXBean; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.packetcable.provider.processors.PCMMDataProcessor; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileBestEffortAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileDocsisServiceClassNameAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileFlowspecAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.BestEffortCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.DocsisServiceClassNameCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.FlowspecCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.CmtsInstance; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAddInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAddOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAddOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAdded; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAddedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemoveInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemoveOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemoveOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemovedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdateInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdateOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdateOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.PacketcableServiceService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsBestEffortInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsBestEffortOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsDownstreamServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsDownstreamServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsFlowspecInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsFlowspecOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsNonRealTimePollingServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsNonRealTimePollingServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsRealTimePollingServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsRealTimePollingServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsUnsolicitedGrantServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsUnsolicitedGrantServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsUnsolicitedGrantServiceWithActivityDetectionInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileGetDefaultsUnsolicitedGrantServiceWithActivityDetectionOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsBestEffortInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsBestEffortOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsDownstreamServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsDownstreamServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsFlowspecInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsFlowspecOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsNonRealTimePollingServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsNonRealTimePollingServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsRealTimePollingServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsRealTimePollingServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsUnsolicitedGrantServiceInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsUnsolicitedGrantServiceOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsUnsolicitedGrantServiceWithActivityDetectionInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.TrafficProfileUpdateDefaultsUnsolicitedGrantServiceWithActivityDetectionOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.CmtsCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.nodes.node.CmtsNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.SubscriberIdRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcRemoveFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcUpdateFlowOriginal; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcUpdateFlowUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.tcp.match.ranges.attributes.TcpMatchRanges; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.udp.match.ranges.attributes.UpdMatchRanges; +import org.opendaylight.yangtools.concepts.CompositeObjectRegistration; +import org.opendaylight.yangtools.concepts.CompositeObjectRegistration.CompositeObjectRegistrationBuilder; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.pcmm.gates.IClassifier; +import org.pcmm.gates.IExtendedClassifier; +import org.pcmm.gates.ITrafficProfile; +import org.pcmm.gates.impl.ExtendedClassifier; +import org.pcmm.rcd.IPCMMPolicyServer; +import org.pcmm.rcd.IPCMMPolicyServer.IPSCMTSClient; +import org.pcmm.rcd.impl.PCMMPolicyServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @SuppressWarnings("unused") -public class OpendaylightPacketcableProvider implements - PacketcableServiceService, PacketcableProviderRuntimeMXBean, - DataChangeListener, AutoCloseable { +public class OpendaylightPacketcableProvider implements DataChangeListener, + SalFlowService, OpenDaylightPacketCableProviderService, + BindingAwareProvider, AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(OpendaylightPacketcableProvider.class); private NotificationProviderService notificationProvider; @@ -86,13 +93,18 @@ public class OpendaylightPacketcableProvider implements // The following holds the Future for the current make toast task. // This is used to cancel the current toast. private final AtomicReference> currentConnectionsTasks = new AtomicReference<>(); - - private List> cmtsInstances; + private ProviderContext providerContext; + private NotificationProviderService notificationService; + private DataBroker dataBroker; + private ListenerRegistration listenerRegistration; + private PCMMDataProcessor pcmmDataProcessor; + private IPCMMPolicyServer policyServer; public OpendaylightPacketcableProvider() { executor = Executors.newCachedThreadPool(); - cmtsInstances = Lists.newArrayList(); - + pcmmDataProcessor = new PCMMDataProcessor(); + policyServer=new PCMMPolicyServer(); + policyServer.startServer(); } public void setNotificationProvider(final NotificationProviderService salService) { @@ -109,37 +121,26 @@ public class OpendaylightPacketcableProvider implements @Override public void close() throws ExecutionException, InterruptedException { executor.shutdown(); - if (dataProvider != null) { - for (Iterator> iter = cmtsInstances.iterator(); iter.hasNext();) { - WriteTransaction tx = dataProvider.newWriteOnlyTransaction(); - tx.delete(LogicalDatastoreType.OPERATIONAL, iter.next()); - Futures.addCallback(tx.submit(), new FutureCallback() { - @Override - public void onSuccess(final Void result) { - logger.debug("Delete commit result: " + result); - } - - @Override - public void onFailure(final Throwable t) { - logger.error("Delete operation failed", t); - } - }); - } - } + // if (dataProvider != null) { + // for (Iterator> iter = + // cmtsInstances.iterator(); iter.hasNext();) { + // WriteTransaction tx = dataProvider.newWriteOnlyTransaction(); + // tx.delete(LogicalDatastoreType.OPERATIONAL, iter.next()); + // Futures.addCallback(tx.submit(), new FutureCallback() { + // @Override + // public void onSuccess(final Void result) { + // logger.debug("Delete commit result: " + result); + // } + // + // @Override + // public void onFailure(final Throwable t) { + // logger.error("Delete operation failed", t); + // } + // }); + // } + // } } - // private CmtsInstance buildCmtsConnection(final String host) { - // InetAddress address = InetAddress.getByName(host); - // IpAddress ipAddress = - // IpAddressBuilder.getDefaultInstance(address.getHostAddress()); - // PcmmConfigurationBuilder pcmmConfigurationBuilder = new - // PcmmConfigurationBuilder().setIpAddress(ipAddress); - // org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.cmts.instance.ConfigurationPointsBuilder - // configurationPointsBuilder = new - // org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.cmts.instance.ConfigurationPointsBuilder().build(); - // return new CmtsAddedBuilder().setConfigurationPoints().build(); - // } - /** * Implemented from the DataChangeListener interface. */ @@ -150,141 +151,125 @@ public class OpendaylightPacketcableProvider implements } @Override - public Boolean getConnectionState() { - return null; - } - - @Override - public void closeCmtsConnection() { - for (Iterator> iter = cmtsInstances.iterator(); iter.hasNext();) { - - // notificationProvider.publish(paramNotification) - // iter.next().getId() + public Future> addFlow(AddFlowInput input) { + Match match = input.getMatch(); + //XXX this wrong fix it + CmtsNode cmts = (CmtsNode) input.getNode(); + ///end wrong + IClassifier classifier = buildClassifier(match); + ITrafficProfile trafficProfie = null; + for (Instruction i : input.getInstructions().getInstruction()) { + if (i.getInstruction() instanceof ApplyActionsCase) { + ApplyActionsCase aac = (ApplyActionsCase) i.getInstruction(); + for (Action a : aac.getApplyActions().getAction()) { + if (a.getAction() instanceof FlowspecCase) { + // not implemented + // trafficProfie = buildTrafficProfile(((FlowspecCase) a.getAction()).getFlowspec()); + } else if (a.getAction() instanceof BestEffortCase) { + trafficProfie = buildTrafficProfile(((BestEffortCase) a.getAction()).getBestEffort()); + break; + } else if (a.getAction() instanceof DocsisServiceClassNameCase) { + trafficProfie = buildTrafficProfile(((DocsisServiceClassNameCase) a.getAction()).getDocsisServiceClassName()); + break; + } + } + } } - } - - @Override - public Future> cmtsAdd(CmtsAddInput input) { - //TODO how to get this transaction id ??? - TransactionId transactionId = null; - if (transactionId != null) { - CmtsAdded cmtsAdded = new CmtsAddedBuilder().setCmtsRef(input.getCmtsRef()).setId(input.getId()).setConfigurationPoints(input.getConfigurationPoints()).setTransactionUri(input.getTransactionUri()).setTransactionId(transactionId).setNode(input.getNode()).setManagedCableModemSubscribers(input.getManagedCableModemSubscribers()).build(); - notificationProvider.publish(cmtsAdded); - CmtsAddOutput output = new CmtsAddOutputBuilder().setTransactionId(transactionId).build(); - return Futures.immediateFuture(RpcResultBuilder.success(output).build()); - } else { - return Futures.immediateFuture(RpcResultBuilder. failed().build()); + TransactionId transactionId=null; + try { + IPSCMTSClient requestCMTSConnection = policyServer.requestCMTSConnection(InetAddress.getByName(cmts.getAddress().getIpv4Address().getValue())); + transactionId=new TransactionId(new BigInteger(String.valueOf(requestCMTSConnection.getTransactionId()))); + } catch (UnknownHostException e) { + e.printStackTrace(); } - } - - @Override - public Future> cmtsRemove(CmtsRemoveInput input) { - TransactionId transactionId = null; - if (transactionId != null) { - CmtsRemoved cmtsRemoved = new CmtsRemovedBuilder().setCmtsRef(input.getCmtsRef()).setId(input.getId()).setConfigurationPoints(input.getConfigurationPoints()).setTransactionUri(input.getTransactionUri()).setTransactionId(transactionId).setNode(input.getNode()).setManagedCableModemSubscribers(input.getManagedCableModemSubscribers()).build(); - notificationProvider.publish(cmtsRemoved); - CmtsRemoveOutput output = new CmtsRemoveOutputBuilder().setTransactionId(transactionId).build(); - return Futures.immediateFuture(RpcResultBuilder.success(output).build()); - } else { - return Futures.immediateFuture(RpcResultBuilder. failed().build()); + if(transactionId==null) + { + return Futures.immediateFuture(RpcResultBuilder.failed().build()); } + return Futures.immediateFuture( + RpcResultBuilder.success( + new AddFlowOutputBuilder().setTransactionId(transactionId).build() + ).build() + ); } @Override - public Future> cmtsUpdate(CmtsUpdateInput input) { - TransactionId transactionId = null; - if (transactionId != null) { - CmtsUpdated cmtsUpdated = new CmtsUpdatedBuilder().setCmtsRef(input.getCmtsRef()).setId(input.getOriginalCmts().getId()).setConfigurationPoints(input.getOriginalCmts().getConfigurationPoints()).setTransactionUri(input.getTransactionUri()).setTransactionId(transactionId).setNode(input.getNode()).setManagedCableModemSubscribers(input.getOriginalCmts().getManagedCableModemSubscribers()).build(); - notificationProvider.publish(cmtsUpdated); - CmtsUpdateOutput output = new CmtsUpdateOutputBuilder().setTransactionId(transactionId).build(); - return Futures.immediateFuture(RpcResultBuilder.success(output).build()); - } else { - return Futures.immediateFuture(RpcResultBuilder. failed().build()); - } + public ITrafficProfile buildTrafficProfile(TrafficProfileDocsisServiceClassNameAttributes docsis) { + return pcmmDataProcessor.process(docsis); } @Override - public Future> trafficProfileGetDefaultsBestEffort(TrafficProfileGetDefaultsBestEffortInput input) { - // TODO Auto-generated method stub - return null; + public ITrafficProfile buildTrafficProfile(TrafficProfileBestEffortAttributes bestEffort) { + return pcmmDataProcessor.process(bestEffort); } @Override - public Future> trafficProfileGetDefaultsDownstreamService(TrafficProfileGetDefaultsDownstreamServiceInput input) { - // TODO Auto-generated method stub - return null; + public ITrafficProfile buildTrafficProfile(TrafficProfileFlowspecAttributes flowSpec) { + return pcmmDataProcessor.process(flowSpec); } @Override - public Future> trafficProfileGetDefaultsFlowspec(TrafficProfileGetDefaultsFlowspecInput input) { - // TODO Auto-generated method stub - return null; + public IClassifier buildClassifier(Match match) { + return pcmmDataProcessor.process(match); } @Override - public Future> trafficProfileGetDefaultsNonRealTimePollingService(TrafficProfileGetDefaultsNonRealTimePollingServiceInput input) { - // TODO Auto-generated method stub + public Future> removeFlow(RemoveFlowInput input) { + UdpMatchRangesRpcRemoveFlow updRange = input.getMatch().getAugmentation(UdpMatchRangesRpcRemoveFlow.class); return null; } @Override - public Future> trafficProfileGetDefaultsRealTimePollingService(TrafficProfileGetDefaultsRealTimePollingServiceInput input) { - // TODO Auto-generated method stub - return null; - } + public Future> updateFlow(UpdateFlowInput input) { + OriginalFlow foo = input.getOriginalFlow(); + UdpMatchRangesRpcUpdateFlowOriginal bar = foo.getMatch().getAugmentation(UdpMatchRangesRpcUpdateFlowOriginal.class); + UpdatedFlow updated = input.getUpdatedFlow(); + UdpMatchRangesRpcUpdateFlowUpdated updatedRange = updated.getMatch().getAugmentation(UdpMatchRangesRpcUpdateFlowUpdated.class); - @Override - public Future> trafficProfileGetDefaultsUnsolicitedGrantService(TrafficProfileGetDefaultsUnsolicitedGrantServiceInput input) { - // TODO Auto-generated method stub return null; } @Override - public Future> trafficProfileGetDefaultsUnsolicitedGrantServiceWithActivityDetection(TrafficProfileGetDefaultsUnsolicitedGrantServiceWithActivityDetectionInput input) { + public Collection getImplementations() { // TODO Auto-generated method stub return null; } @Override - public Future> trafficProfileUpdateDefaultsBestEffort(TrafficProfileUpdateDefaultsBestEffortInput input) { + public Collection getFunctionality() { // TODO Auto-generated method stub return null; } @Override - public Future> trafficProfileUpdateDefaultsDownstreamService(TrafficProfileUpdateDefaultsDownstreamServiceInput input) { - // TODO Auto-generated method stub - return null; + public void onSessionInitiated(ProviderContext session) { + providerContext = session; + notificationService = session.getSALService(NotificationProviderService.class); + dataBroker = session.getSALService(DataBroker.class); + InstanceIdentifier listenTo = InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(CmtsCapableNode.class).child(CmtsNode.class); + listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, listenTo, this, DataChangeScope.BASE); } @Override - public Future> trafficProfileUpdateDefaultsFlowspec(TrafficProfileUpdateDefaultsFlowspecInput input) { - // TODO Auto-generated method stub - return null; - } + public void onSessionInitialized(ConsumerContext session) { + // Noop - @Override - public Future> trafficProfileUpdateDefaultsNonRealTimePollingService(TrafficProfileUpdateDefaultsNonRealTimePollingServiceInput input) { - // TODO Auto-generated method stub - return null; } - @Override - public Future> trafficProfileUpdateDefaultsRealTimePollingService(TrafficProfileUpdateDefaultsRealTimePollingServiceInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> trafficProfileUpdateDefaultsUnsolicitedGrantService(TrafficProfileUpdateDefaultsUnsolicitedGrantServiceInput input) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Future> trafficProfileUpdateDefaultsUnsolicitedGrantServiceWithActivityDetection(TrafficProfileUpdateDefaultsUnsolicitedGrantServiceWithActivityDetectionInput input) { - // TODO Auto-generated method stub - return null; + public void onSessionAdded(/* Whatever you need per CmtsConnection */) { + CompositeObjectRegistrationBuilder builder = CompositeObjectRegistration. builderFor(this); + /* + * You will need a routedRpc registration per Cmts... I'm not doing the + * accounting of storing them here, but you will need to so you can + * close them when your provider is closed + */ + RoutedRpcRegistration registration = providerContext.addRoutedRpcImplementation(SalFlowService.class, this); + /* + * You will need to get your identifier somewhere... this is your + * nodeId. I would recommend adoption a convention like + * "cmts:" for CmtsCapableNodes + * registration.registerPath(NodeContext.class, getIdentifier()); + */ } } diff --git a/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/processors/PCMMDataProcessor.java b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/processors/PCMMDataProcessor.java new file mode 100644 index 0000000..aa98629 --- /dev/null +++ b/packetcable-provider/src/main/java/org/opendaylight/controller/packetcable/provider/processors/PCMMDataProcessor.java @@ -0,0 +1,193 @@ +/** + * + */ +package org.opendaylight.controller.packetcable.provider.processors; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileBestEffortAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileDocsisServiceClassNameAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.TrafficProfileFlowspecAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.traffic.profile.best.effort.attributes.BeAuthorizedEnvelope; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.traffic.profile.best.effort.attributes.BeCommittedEnvelope; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.traffic.profile.rev140808.traffic.profile.best.effort.attributes.BereservedEnvelope; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.SubscriberIdRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.TcpMatchRangesRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.UdpMatchRangesRpcAddFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.tcp.match.ranges.attributes.TcpMatchRanges; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.match.types.rev140120.udp.match.ranges.attributes.UpdMatchRanges; +import org.pcmm.gates.IClassifier; +import org.pcmm.gates.IExtendedClassifier; +import org.pcmm.gates.ITrafficProfile; +import org.pcmm.gates.impl.BestEffortService; +import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile; +import org.pcmm.gates.impl.ExtendedClassifier; +import org.pcmm.gates.impl.BestEffortService.BEEnvelop; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * PacketCable data processor + * + */ +public class PCMMDataProcessor { + + private Logger logger = LoggerFactory.getLogger(PCMMDataProcessor.class); + + public ITrafficProfile process(TrafficProfileBestEffortAttributes bestEffort) { + BestEffortService trafficProfile = new BestEffortService(BestEffortService.DEFAULT_ENVELOP); + getBEAuthorizedEnvelop(bestEffort, trafficProfile); + getBEReservedEnvelop(bestEffort, trafficProfile); + getBECommittedEnvelop(bestEffort, trafficProfile); + return trafficProfile; + } + + public ITrafficProfile process(TrafficProfileDocsisServiceClassNameAttributes docsis) { + DOCSISServiceClassNameTrafficProfile trafficProfile = new DOCSISServiceClassNameTrafficProfile(); + trafficProfile.setServiceClassName(docsis.getServiceClassName()); + return trafficProfile; + } + + // TODO + public ITrafficProfile process(TrafficProfileFlowspecAttributes flowSpec) { + throw new UnsupportedOperationException("Not impelemnted yet"); + } + + public IClassifier process(Match match) { + ExtendedClassifier classifier = new ExtendedClassifier(); + classifier.setProtocol(IClassifier.Protocol.NONE); + getUdpMatchRangeValues(match.getAugmentation(UdpMatchRangesRpcAddFlow.class), classifier); + getTcpMatchRangesValues(match.getAugmentation(TcpMatchRangesRpcAddFlow.class), classifier); + SubscriberIdRpcAddFlow subId = match.getAugmentation(SubscriberIdRpcAddFlow.class); + Ipv6Address ipv6Address = subId.getSubscriberId().getIpv6Address(); + if (ipv6Address != null) + try { + classifier.setDestinationIPAddress(InetAddress.getByName(ipv6Address.getValue())); + } catch (UnknownHostException e) { + logger.error(e.getMessage()); + } + + Ipv4Address ipv4Address = subId.getSubscriberId().getIpv4Address(); + if (ipv4Address != null) + try { + classifier.setDestinationIPAddress(InetAddress.getByName(ipv4Address.getValue())); + } catch (UnknownHostException e) { + logger.error(e.getMessage()); + } + return classifier; + } + + private void getBECommittedEnvelop(TrafficProfileBestEffortAttributes bestEffort, BestEffortService trafficProfile) { + BEEnvelop committedEnvelop = trafficProfile.getCommittedEnvelop(); + BeCommittedEnvelope beCommittedEnvelope = bestEffort.getBeCommittedEnvelope(); + if (beCommittedEnvelope.getTrafficPriority() != null) + committedEnvelop.setTrafficPriority(beCommittedEnvelope.getTrafficPriority().byteValue()); + else + committedEnvelop.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY); + if (beCommittedEnvelope.getMaximumTrafficBurst() != null) + committedEnvelop.setMaximumTrafficBurst(beCommittedEnvelope.getMaximumTrafficBurst().intValue()); + else + committedEnvelop.setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST); + if (beCommittedEnvelope.getRequestTransmissionPolicy() != null) + committedEnvelop.setRequestTransmissionPolicy(beCommittedEnvelope.getRequestTransmissionPolicy().intValue()); + // else + // committedEnvelop.setRequestTransmissionPolicy(PCMMGlobalConfig.BETransmissionPolicy); + if (beCommittedEnvelope.getMaximumSustainedTrafficRate() != null) + committedEnvelop.setMaximumSustainedTrafficRate(beCommittedEnvelope.getMaximumSustainedTrafficRate().intValue()); + // else + // committedEnvelop.setMaximumSustainedTrafficRate(PCMMGlobalConfig.DefaultLowBestEffortTrafficRate); + } + + private void getBEReservedEnvelop(TrafficProfileBestEffortAttributes bestEffort, BestEffortService trafficProfile) { + BEEnvelop reservedEnvelop = trafficProfile.getReservedEnvelop(); + BereservedEnvelope beReservedEnvelope = bestEffort.getBereservedEnvelope(); + if (beReservedEnvelope.getTrafficPriority() != null) + reservedEnvelop.setTrafficPriority(beReservedEnvelope.getTrafficPriority().byteValue()); + else + reservedEnvelop.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY); + if (beReservedEnvelope.getMaximumTrafficBurst() != null) + reservedEnvelop.setMaximumTrafficBurst(beReservedEnvelope.getMaximumTrafficBurst().intValue()); + else + reservedEnvelop.setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST); + if (beReservedEnvelope.getRequestTransmissionPolicy() != null) + reservedEnvelop.setRequestTransmissionPolicy(beReservedEnvelope.getRequestTransmissionPolicy().intValue()); + if (beReservedEnvelope.getMaximumSustainedTrafficRate() != null) + reservedEnvelop.setMaximumSustainedTrafficRate(beReservedEnvelope.getMaximumSustainedTrafficRate().intValue()); + } + + private void getBEAuthorizedEnvelop(TrafficProfileBestEffortAttributes bestEffort, BestEffortService trafficProfile) { + BEEnvelop authorizedEnvelop = trafficProfile.getAuthorizedEnvelop(); + BeAuthorizedEnvelope beAuthorizedEnvelope = bestEffort.getBeAuthorizedEnvelope(); + if (beAuthorizedEnvelope.getTrafficPriority() != null) + authorizedEnvelop.setTrafficPriority(beAuthorizedEnvelope.getTrafficPriority().byteValue()); + else + authorizedEnvelop.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY); + if (beAuthorizedEnvelope.getMaximumTrafficBurst() != null) + authorizedEnvelop.setMaximumTrafficBurst(beAuthorizedEnvelope.getMaximumTrafficBurst().intValue()); + else + authorizedEnvelop.setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST); + if (beAuthorizedEnvelope.getRequestTransmissionPolicy() != null) + authorizedEnvelop.setRequestTransmissionPolicy(beAuthorizedEnvelope.getRequestTransmissionPolicy().intValue()); + if (beAuthorizedEnvelope.getMaximumSustainedTrafficRate() != null) + authorizedEnvelop.setMaximumSustainedTrafficRate(beAuthorizedEnvelope.getMaximumSustainedTrafficRate().intValue()); + } + + private void getTcpMatchRangesValues(TcpMatchRangesAttributes tcpRange, IExtendedClassifier classifier) { + short srcPortStart, srcPortEnd, dstPortStart, dstPortEnd; + srcPortStart = srcPortEnd = dstPortStart = dstPortEnd = 0; + if (tcpRange != null) { + classifier.setProtocol(IClassifier.Protocol.TCP); + TcpMatchRanges tcpMatchRanges = tcpRange.getTcpMatchRanges(); + PortNumber tcpDestinationPortStart = tcpMatchRanges.getTcpDestinationPortBegin(); + if (tcpDestinationPortStart != null && tcpDestinationPortStart.getValue() != null) + dstPortStart = tcpDestinationPortStart.getValue().shortValue(); + PortNumber tcpSourcePortStart = tcpMatchRanges.getTcpSourcePortStart(); + if (tcpSourcePortStart != null && tcpSourcePortStart.getValue() != null) + srcPortStart = tcpSourcePortStart.getValue().shortValue(); + PortNumber tcpDestinationPortEnd = tcpMatchRanges.getTcpDestinationPortEnd(); + if (tcpDestinationPortEnd != null && tcpDestinationPortEnd.getValue() != null) + dstPortEnd = tcpDestinationPortEnd.getValue().shortValue(); + PortNumber tcpSourcePortEnd = tcpMatchRanges.getTcpSourcePortEnd(); + if (tcpSourcePortEnd != null && tcpSourcePortEnd.getValue() != null) + srcPortEnd = tcpSourcePortEnd.getValue().shortValue(); + } + classifier.setDestinationPortStart(dstPortStart); + classifier.setSourcePortStart(srcPortStart); + classifier.setDestinationPortEnd(dstPortEnd); + classifier.setSourcePortEnd(srcPortEnd); + } + + private void getUdpMatchRangeValues(UdpMatchRangesAttributes updRange, IExtendedClassifier classifier) { + short srcPortStart, srcPortEnd, dstPortStart, dstPortEnd; + srcPortStart = srcPortEnd = dstPortStart = dstPortEnd = 0; + if (updRange != null) { + classifier.setProtocol(IClassifier.Protocol.UDP); + UpdMatchRanges updMatchRanges = updRange.getUpdMatchRanges(); + PortNumber udpDestinationPortStart = updMatchRanges.getUdpDestinationPortStart(); + if (udpDestinationPortStart != null && udpDestinationPortStart.getValue() != null) + dstPortStart = udpDestinationPortStart.getValue().shortValue(); + PortNumber udpSourcePortStart = updMatchRanges.getUdpSourcePortStart(); + if (udpSourcePortStart != null && udpSourcePortStart.getValue() != null) + srcPortStart = udpSourcePortStart.getValue().shortValue(); + PortNumber udpDestinationPortEnd = updMatchRanges.getUdpDestinationPortEnd(); + if (udpDestinationPortEnd != null && udpDestinationPortEnd.getValue() != null) + dstPortEnd = udpDestinationPortEnd.getValue().shortValue(); + PortNumber udpSourcePortEnd = updMatchRanges.getUdpSourcePortEnd(); + if (udpSourcePortEnd != null && udpSourcePortEnd.getValue() != null) + srcPortEnd = udpSourcePortEnd.getValue().shortValue(); + } + classifier.setDestinationPortStart(dstPortStart); + classifier.setSourcePortStart(srcPortStart); + classifier.setDestinationPortEnd(dstPortEnd); + classifier.setSourcePortEnd(srcPortEnd); + } + +} diff --git a/packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModule.java b/packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModule.java new file mode 100644 index 0000000..50a0b15 --- /dev/null +++ b/packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModule.java @@ -0,0 +1,30 @@ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.provider.impl.rev140131; + +import org.opendaylight.controller.packetcable.provider.OpendaylightPacketcableProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PacketcableProviderModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.provider.impl.rev140131.AbstractPacketcableProviderModule { + private static final Logger logger = LoggerFactory.getLogger(PacketcableProviderModule.class); + public PacketcableProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public PacketcableProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.provider.impl.rev140131.PacketcableProviderModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + OpendaylightPacketcableProvider provider = new OpendaylightPacketcableProvider(); + this.getBrokerDependency().registerProvider(provider, null); + logger.info("PacketCableProvider Registered with Broker"); + return provider; + } + +} diff --git a/packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModuleFactory.java b/packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModuleFactory.java similarity index 53% rename from packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModuleFactory.java rename to packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModuleFactory.java index c196c60..35747fd 100644 --- a/packetcable-provider/src/main/java/org/opendaylight/controller/config/yang/config/packetcable_provider/impl/PacketcableProviderModuleFactory.java +++ b/packetcable-provider/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/packetcable/packetcable/provider/impl/rev140131/PacketcableProviderModuleFactory.java @@ -3,11 +3,11 @@ * * Generated from: yang module name: packetcable-provider-impl yang module local name: packetcable-provider-impl * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Thu Jul 24 00:40:30 CEST 2014 +* Generated at: Tue Sep 02 11:30:13 CDT 2014 * * Do not modify this file unless it is present under src/main directory */ -package org.opendaylight.controller.config.yang.config.packetcable_provider.impl; -public class PacketcableProviderModuleFactory extends org.opendaylight.controller.config.yang.config.packetcable_provider.impl.AbstractPacketcableProviderModuleFactory { +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.provider.impl.rev140131; +public class PacketcableProviderModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.packetcable.packetcable.provider.impl.rev140131.AbstractPacketcableProviderModuleFactory { } diff --git a/packetcable-provider/src/main/yang/packetcable-provider-impl.yang b/packetcable-provider/src/main/yang/packetcable-provider-impl.yang index 83e6a28..431a76e 100644 --- a/packetcable-provider/src/main/yang/packetcable-provider-impl.yang +++ b/packetcable-provider/src/main/yang/packetcable-provider-impl.yang @@ -1,12 +1,13 @@ module packetcable-provider-impl { yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:controller:config:packetcable-provider:impl"; + namespace "urn:opendaylight:params:xml:ns:yang:packetcable:packetcable-provider:impl"; prefix "packetcable-provider-impl"; import config { prefix config; revision-date 2013-04-05; } import rpc-context { prefix rpcx; revision-date 2013-06-17; } import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } + import packetcable-provider { prefix pcp; revision-date 2014-01-31; } import ietf-inet-types {prefix inet;revision-date 2010-09-24;} description @@ -21,7 +22,7 @@ module packetcable-provider-impl { // This is the definition of the service implementation as a module identity. identity packetcable-provider-impl { base config:module-type; - + config:provided-service pcp:packetcable-provider; // Specifies the prefix for generated java classes. config:java-name-prefix PacketcableProvider; } @@ -30,60 +31,14 @@ module packetcable-provider-impl { augment "/config:modules/config:module/config:configuration" { case packetcable-provider-impl { when "/config:modules/config:module/config:type = 'packetcable-provider-impl'"; - - container rpc-registry { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity mdsal:binding-rpc-registry; - } - } - } - - container notification-service { + container broker { uses config:service-ref { refine type { mandatory true; - config:required-identity mdsal:binding-notification-service; - } - } - } - - container data-broker { - uses config:service-ref { - refine type { - mandatory false; - config:required-identity mdsal:binding-async-data-broker; + config:required-identity mdsal:binding-broker-osgi-registry; } } } } } - - augment "/config:modules/config:module/config:state" { - case packetcable-provider-impl { - when "/config:modules/config:module/config:type = 'packetcable-provider-impl'"; - - leaf connection-state { - type boolean; - } - - rpcx:rpc-context-instance "close-cmts-connection-rpc"; - } - } - - identity close-cmts-connection-rpc; - - rpc close-cmts-connection { - description - "JMX call to close the cmts connection."; - - input { - uses rpcx:rpc-context-ref { - refine context-instance { - rpcx:rpc-context-instance close-cmts-connection-rpc; - } - } - } - } } diff --git a/packetcable-provider/src/main/yang/packetcable-provider.yang b/packetcable-provider/src/main/yang/packetcable-provider.yang new file mode 100644 index 0000000..4836cd1 --- /dev/null +++ b/packetcable-provider/src/main/yang/packetcable-provider.yang @@ -0,0 +1,25 @@ +module packetcable-provider { + + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:packetcable:packetcable-provider"; + prefix "packetcable-provider"; + + import config { prefix config; revision-date 2013-04-05; } + import rpc-context { prefix rpcx; revision-date 2013-06-17; } + import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } + import ietf-inet-types {prefix inet;revision-date 2010-09-24;} + + description + "This module contains the base YANG definitions for + packetcable-provider."; + + revision "2014-01-31" { + description + "Initial revision."; + } + + identity packetcable-provider{ + base config:service-type; + config:java-class "org.opendaylight.controller.packetcable.provider.OpenDaylightPacketCableProviderService"; + } +} diff --git a/pom.xml b/pom.xml index 3655465..4496638 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 org.opendaylight.controller @@ -28,16 +29,43 @@ packetcable-driver packetcable-model packetcable-provider - features-packetcable - + features-packetcable + packetcable-config + packetcable-karaf + scm:git:ssh://git.opendaylight.org:29418/packetcable.git scm:git:ssh://git.opendaylight.org:29418/packetcable.git HEAD https://wiki.opendaylight.org/view/PacketCablePCMM:Main - - + + + + opendaylight-mirror + opendaylight-mirror + http://nexus.opendaylight.org/content/groups/public/ + + false + + + true + never + + + + + opendaylight-snapshot + opendaylight-snapshot + http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/ + + true + + + false + + + org.opendaylight.controller.model @@ -63,31 +91,35 @@ org.opendaylight.yangtools.model opendaylight-l2-types + + org.opendaylight.controller.model + model-flow-statistics + - - - maven-checkstyle-plugin - - true - - - - + + + maven-checkstyle-plugin + + true + + + + + + + + + + + + + + + + - - - - - - - - - - - - @@ -107,32 +139,6 @@ - - - - opendaylight-snapshot - opendaylight-snapshot - ${nexusproxy}/repositories/opendaylight.snapshot - - true - - - false - - - - public - public - ${nexusproxy}/groups/public - - false - - - - - - - -- 2.36.6