</thead>
<tbody id="ces_table">
<tr ng-repeat="item in unis | orderBy: '[\'uni-id\']'">
- <td ng-init="device = ces.filterByField('dev-id',item.device)[0]">{{ device["device-name"] ? device["device-name"] : device["dev-id"]}}</td>
+ <td ng-init="device = ces.filterByField('dev-id',item.device)[0]">{{ device["device-name"] ? device["device-name"] : item.device}}</td>
<td>{{ item.prettyID }}</td>
<td ng-if="item['tenant-id'] != undefined" >
{{ item['tenant-id'] }} <button class="btn add-row right" ng-click="linkUniDialog.show($event, {'uni':item['uni-id'], tenants:tenantArray})">Edit</button>
<div ng-app="">
- <!--
- Main Tab
- -->
<div ui-view="cpeui" />
- <!--
- Tenant Data Tab
- -->
- <!-- div class="container" ng-show="isTabSet('main',2)">
- <h1>L2 Services - Tenant {{ currentTenent.name }}</h1>
- <div class="menu">
- <ul id="EVCs-tab" class="nav nav-pills" role="tablist">
- <li ng-class="{ active: isTabSet('tenantData',1)}" ng-click="setTab('tenantData',1)" >
- <a id="evcs-view-tab"> <i class="icon-search"></i> View</a>
- </li>
- <li ng-class="{ active: isTabSet('tenantData',2)}" ng-click="setTab('tenantData',2)" >
- <a id="evcs-configure-tab" > <i class="icon-wrench"></i> Configure</a>
- </li>
- <li ng-class="{ active: isTabSet('tenantData',3)}" ng-click="setTab('tenantData',3)" >
- <a id="dashboard-tab" > <i class="icon-signal"></i> Dashboard</a>
- </li>
- </ul>
- </div>
- <div id="EVCsContent" class="tab-content">
- <div role="tabpanel" class="tab-pane fade in active" id="evcs-view" ng-show="isTabSet('tenantData',1)" aria-labelledBy="evcs-view-tab">
- <br></br>
- <div class="panel panel-primary">
- <div class="panel-heading">
- <h3 class="panel-title">L2 Services Table</h3>
- </div>
- <div class="panel-body">
- <table class="table table-striped">
- <thead>
- <tr>
- <th>Service ID</th>
- <th>Service Type</th>
- <th>CEs in Service</th>
- <th>UNIs in Service</th>
- </tr>
- </thead>
- <tbody id="evc_table" />
- </table>
- </div>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane fade in active" id="evcs-configure" ng-show="isTabSet('tenantData',2)" aria-labelledBy="evcs-configure-tab">
- <br></br>
- <div class="panel panel-primary" style="width: 500px;">
- <div class="panel-heading">
- <h3 class="panel-title">EVCs Actions</h3>
- </div>
- <div class="panel-body">
- <button type="button" class="btn btn-lg" data-toggle="modal" onclick="prepareCreateEVC()" data-target="#createEVCModal">Create EVC</button>
- <button type="button" class="btn btn-lg" data-toggle="modal" onclick="prepareRemoveEVC(evcs_list)" data-target="#removeEVCModal">Remove EVC</button>
- </div>
- </div>
- </div>
- </div>
- <button class="btn btn-default pull-right" ng-click="setTab('main',1)" > Back </button>
- </div -->
</div>
<div ng-message="pattern">name must be only numbers and English characters</div>
<div ng-message="md-maxlength">The name has to be less than 30 characters long.</div>
</div>
-
-
-
-
-
</md-input-container>
</md-content>
</div>
// TODO didn't find a better way to keep other uni fields, PATCH method is not supported :(
$http({
method:'GET',
- url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/" + id + "/"
+ url:"/restconf/operational/mef-interfaces:mef-interfaces/unis/uni/" + id + "/"
}).then(function successCallback(response) {
uni = response.data;
uni["uni"][0]["tenant-id"] = tenantid;
var unis;
$http({
method:'GET',
- url:"/restconf/config/mef-interfaces:mef-interfaces/unis/"
+ url:"/restconf/operational/mef-interfaces:mef-interfaces/unis/"
}).then(function successCallback(response) {
unis = response.data["unis"]["uni"];
if (unis != undefined){
}
}
}
- unis.forEach(function(u) {
- u.prettyID = u['uni-id'].split(":")[u['uni-id'].split(":").length - 1];
- });
- if (callback != undefined) {
+ var confMap = {}
+ $http({
+ method:'GET',
+ url:"/restconf/config/mef-interfaces:mef-interfaces/unis/"
+ }).then(function(response){
+ var confUnis = response.data["unis"]["uni"];
+ confUnis.forEach(function(u) {
+ confMap[u['uni-id']] = u;
+ });
+ }).finally(function(){
+ unis.forEach(function(u) {
+ u.prettyID = u['uni-id'].split(":")[u['uni-id'].split(":").length - 1];
+ // copy config fields like tenant-id
+ if (confMap[u['uni-id']]){
+ for (var attrname in confMap[u['uni-id']]) {
+ u[attrname] = confMap[u['uni-id']][attrname];
+ }
+ }
+ });
+ if (callback != undefined) {
callback(unis);
- }
+ }
+ });
}, function errorCallback(response) {
+ if (response.status == 404) {
+ callback([]);
+ }
console.log(response);
});
};
});
};
- svc.addIpUni = function(uniid, ipuni_id, ip_address, vlan, subnets, callback) {
+ svc.addIpUni = function(uniid, ipuni_id, ip_address, vlan, callback) {
var data = {"ip-uni":{
"ip-uni-id": ipuni_id,
- "ip-address": ip_address,
- "subnets":{
- "subnet":subnets
- }
+ "ip-address": ip_address
}};
if (vlan){
data["ip-uni"].vlan = vlan;
});
};
- svc.addIpUniSubnet = function(uniid, ipuniid, subnet, gateway,
- callback) {
+ svc.getAllIpUniSubnets = function(callback) {
+ $http({
+ method:'GET',
+ url : "/restconf/config/mef-interfaces:mef-interfaces/subnets/"
+ }).then(function successCallback(response) {
+ var raw_subnets = response.data["subnets"]["subnet"];
+ var subnets ={}
+ raw_subnets.forEach(function(sub){
+ if (subnets[sub["uni-id"]] == undefined) {
+ subnets[sub["uni-id"]] = {};
+ }
+ if (subnets[sub["uni-id"]][sub["ip-uni-id"]] == undefined) {
+ subnets[sub["uni-id"]][sub["ip-uni-id"]] = [];
+ }
+ subnets[sub["uni-id"]][sub["ip-uni-id"]].push(sub);
+ });
+ if (callback != undefined) {
+ callback(subnets);
+ }
+ }, function errorCallback(response) {
+ console.log(response);
+ });
+ };
+
+ svc.addIpUniSubnet = function(uniid, ipuniid, subnet, gateway, callback) {
var data = {
"subnet":
{
"subnet": subnet,
+ "uni-id":uniid,
+ "ip-uni-id":ipuniid,
"gateway": gateway
}
-
};
$http(
{
method : 'POST',
- url : "/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuniid+"/subnets/",
+ url : "/restconf/config/mef-interfaces:mef-interfaces/subnets/",
data : data
}).then(function successCallback(response) {
if (callback != undefined) {
$http({
method:'DELETE',
- url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/subnets/subnet/"+subnet.replace("/","%2F")+"/"
+ url:"/restconf/config/mef-interfaces:mef-interfaces/subnets/subnet/"+uniid+"/"+ipuni_id+"/"+subnet.replace("/","%2F")+"/"
}).then(function successCallback(response) {
if (callback != undefined) {
callback();
svc.getIpUniSubnets = function(uniid, ipuni_id, callback) {
$http({
method:'GET',
- url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/subnets"
+ url:"/restconf/config/mef-interfaces:mef-interfaces/subnets/"
+ //subnet/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/subnets"
}).then(function successCallback(response) {
subnets = response.data["subnets"]["subnet"];
+ subnets = subnets.filterByField('uni-id',uniid).filterByField('ip-uni-id',ipuni_id);
if (callback != undefined) {
callback(subnets);
}
};
$http({
method:'PUT',
- url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/"+uni_id,
+ url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/"+uni_id+"/"+ipuni_id,
data: data
}).then(function successCallback(response) {
if (callback != undefined) {
});
};
- svc.deleteIpvcUni = function(svcid, uni_id, callback) {
+ svc.deleteIpvcUni = function(svcid, uni_id, ipuni_id, callback) {
$http({
method:'DELETE',
- url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/" + uni_id + "/"
+ url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/" + uni_id +"/"+ipuni_id + "/"
}).then(function successCallback(response) {
if (callback != undefined) {
callback();
$scope.unisTables = {};
$scope.unis = [];
$scope.ces = [];
- $scope.ipvcs = []
+ $scope.ipvcs = [];
+ $scope.subnets = {};
$scope.cesDisplayNames = {};
$scope.unisMap = {};
$scope.networkNames = {};
}
});
});
+ CpeuiSvc.getAllIpUniSubnets(function(subnets){
+ $scope.subnets = subnets;
+ });
};
$scope.title = function(str) {
};
$scope.ipUniDialog = new CpeuiDialogs.Dialog('AddIpUni', {}, function(obj) {
- CpeuiSvc.addIpUni(obj['uni-id'], obj['ip-uni-id'], obj['ip-address'], obj.vlan, obj.subnets, function() {
+ CpeuiSvc.addIpUni(obj['uni-id'], obj['ip-uni-id'], obj['ip-address'], obj.vlan, function() {
var uni = $scope.unis.filterByField('uni-id',obj['uni-id'])[0];
if (uni['ip-unis'] == undefined || uni['ip-unis']['ip-uni'] == undefined){
uni['ip-unis'] = {'ip-uni':[]};
$scope.ipUniSubnetDialog = new CpeuiDialogs.Dialog('AddIpUniSubnet', {}, function(obj) {
CpeuiSvc.addIpUniSubnet(obj.uniid, obj.ipuniid, obj.subnet, obj.gateway, function() {
- CpeuiSvc.getIpUniSubnets(obj.uniid, obj.ipuniid, function(subnets) {
- $scope.unis.filterByField('uni-id',obj.uniid)[0]['ip-unis']['ip-uni'].filterByField('ip-uni-id',obj.ipuniid)[0].subnets = {subnet:subnets};
- });
+ if ($scope.subnets[obj.uniid] == undefined){
+ $scope.subnets[obj.uniid] = {};
+ }
+ if ($scope.subnets[obj.uniid][obj.ipuniid] == undefined){
+ $scope.subnets[obj.uniid][obj.ipuniid] = [];
+ }
+ $scope.subnets[obj.uniid][obj.ipuniid].push({
+ "uni-id": obj.uniid,
+ "ip-uni-id": obj.ipuniid,
+ "subnet": obj.subnet,
+ "gateway": obj.gateway
+ });
});
});
});
});
};
- $scope.deleteIpvcUni = function(svc_id, uni_id) {
+ $scope.deleteIpvcUni = function(svc_id, uni_id, ipuni_id) {
CpeuiDialogs.confirm(function() {
- CpeuiSvc.deleteIpvcUni(svc_id, uni_id, function() {
+ CpeuiSvc.deleteIpvcUni(svc_id, uni_id, ipuni_id, function() {
$scope.updateEvcView();
});
});
<td>{{ ipuni.prettyID }}</td>
<td>{{serviceIpuni['ip-address']}}</td>
<td>{{serviceIpuni.vlan}}</td>
- <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'])"> <i class="icon-trash"></i> </button></td>
+ <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'], ipuni['ip-uni-id'])"> <i class="icon-trash"></i> </button></td>
</tr>
</tbody>
</table>
<td>{{ ipuni.prettyID }}</td>
<td>{{serviceIpuni['ip-address']}}</td>
<td>{{serviceIpuni.vlan}}</td>
- <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'])"> <i class="icon-trash"></i> </button></td>
+ <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'], ipuni['ip-uni-id'])"> <i class="icon-trash"></i> </button></td>
</tr>
</tbody>
</table>
<td class="minimal-width">{{ ipuni.vlan }}</td>
<td class="minimal-width">{{ ipuni['ip-address'] }}</td>
<td>
- <button class="btn add-row" ng-click="expandFlags.ipuni[ipuni['ip-uni-id']] = true" ng-if="!expandFlags.ipuni[ipuni['ip-uni-id']]">
+ <button class="btn add-row" ng-click="expandFlags.ipuni[uni['uni-id']+':'+ipuni['ip-uni-id']] = true" ng-if="!expandFlags.ipuni[uni['uni-id']+':'+ipuni['ip-uni-id']]">
<i class="icon-plus"></i> Show Subnets
</button>
- <table class="footable table table-striped inner-table" ng-if="expandFlags.ipuni[ipuni['ip-uni-id']]">
+ <table class="footable table table-striped inner-table" ng-if="expandFlags.ipuni[uni['uni-id']+':'+ipuni['ip-uni-id']]">
<thead>
<tr>
<th class="minimal-width">
- <button class="btn add-row" ng-click="expandFlags.ipuni[ipuni['ip-uni-id']] = false">
+ <button class="btn add-row" ng-click="expandFlags.ipuni[uni['uni-id']+':'+ipuni['ip-uni-id']] = false">
<i class="icon-minus"></i>
</button>
</th>
</tr>
</thead>
<tbody>
- <tr ng-repeat="subnet in ipuni['subnets']['subnet'] | orderBy: subnet">
+ <tr ng-repeat="subnet in subnets[uni['uni-id']][ipuni['ip-uni-id']] | orderBy: subnet" ng-if="subnets[uni['uni-id']]">
<td colspan="2">{{ subnet.subnet }}</td>
<td>{{ subnet.gateway }}</td>
<td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpUniSubnet(uni['uni-id'],ipuni['ip-uni-id'],subnet.subnet)"> <i class="icon-trash"></i> </button></td>
-module mef-interfaces {\r
- namespace "http://metroethernetforum.org/ns/yang/mef-interfaces";\r
- prefix mef-interfaces;\r
- import ietf-inet-types { prefix inet; }\r
- import ietf-yang-types { prefix yang; }\r
- import mef-types { prefix mef-types; }\r
- import mef-global { prefix mef-global; }\r
- import mef-topology { prefix mef-topology; }\r
-\r
- import opendaylight-l2-types { prefix ethertype; }\r
- // revision-date "2013-08-27";\r
-\r
- organization "Metro Ethernet Forum";\r
- contact\r
- "Web URL: http://metroethernetforum.org/ E-mail: mibs@metroethernetforum.org\r
- Postal: Metro Ethernet Forum 6033 W. Century Boulevard, Suite\r
- 1107 Los Angeles, CA 90045 U.S.A. Phone: +1 310-642-2800 Fax:\r
- +1 310-642-2808";\r
- description\r
- "This module implements the UNI functionality specified in MEF\r
- 10.3, MEF 6.2, and MEF 7.2. Reference Overview: A number of base\r
- documents have been used to create the MEF Interfaces YANG Module.\r
- The following are the abbreviations for the baseline documents:\r
- [RFC 6991] refers to IETF RFC 6991 'Common YANG Data Types', 2013-07-15\r
- [RFC 6643] refers to IETF RFC 6643 'Translation of Structure of\r
- Management Information Version 2 (SMIv2) MIB Modules to YANG Modules',\r
- 2011-11-25 [802.1AB] refers to 'Station and Media Access Control\r
- Connectivity Discovery', IEEE 802.1AB-2009, September 2009 [802.1q]\r
- refers to IEEE 802.1Q-2011 'IEEE Standard for Local and metropolitan\r
- area networks --Media Access Control (MAC) Bridges and Virtual\r
- Bridged Local Area Networks, August 2011 [802-2001] refers to\r
- 'IEEE Standard for Local and Metropolitan Area Networks: Overview\r
- and Architecture', IEEE 802-2001, February 2002 [MEF10.3] refers\r
- to MEF 10.3 'Ethernet Services Attributes Phase 3', October 2013\r
- [MEF6.2] refers to MEF 6.2 'EVC Ethernet Services Defintions Phase\r
- 3', August 2014 [MEF40] refers to MEF 40 'UNI and EVC Definition\r
- of Managed Objects', April 2013 [MEF45] refers to MEF 45 'Multi-CEN\r
- L2CP', August 2014 [MEF7.2] refers to MEF 7.2 'Carrier Ethernet\r
- Management Information Model', April 2013 [MEF7.3] refers to MEF\r
- 7.3 'Carrier Ethernet Management Information Model', Working Draft\r
- #1 2015 [RFC 2737] refers to IETF RFC 2737 'Entity MIB (Version\r
- 2)', December 1999 [RFC 2863] refers to IETF RFC 2863 'The Interfaces\r
- Group MIB', June 2000 [RFC 3419] refers to IETF RFC 3419 'Textual\r
- Conventions for Transport Addresses', December 2002 [Y.1731] refers\r
- to ITU-T Y.1731 'OAM functions and mechanisms for Ethernet based\r
- networks', July 2011 [Q.840.1] refers to ITU-T Q.840.1 'Requirements\r
- and analysis for NMS-EMS management interface of Ethernet over\r
- Transport and Metro Ethernet Network(EoT/MEN)' March 2007";\r
- revision 2015-05-26 {\r
- description\r
- "Formal Project Review Draft 1.";\r
- reference "EVC Ethernet Services Definitions YANG Modules " +\r
- "(MEF XX), TBD";\r
- }\r
- container mef-interfaces {\r
- description\r
- "MEF Interfaces";\r
- container unis {\r
- description\r
- "User Network Interface(UNI).";\r
- list uni {\r
- must "not(./ingress-bw-profile-per-uni) or " +\r
- "((./ingress-bw-profile-per-uni) and " +\r
- "not(./ingress-envelopes))" {\r
- error-message "If there is a per UNI Ingress Bandwidth " +\r
- "Profile, then there cannot be any other Ingress " +\r
- "Bandwidth Profiles at that UNI.";\r
- description\r
- "If there is a per UNI Ingress Bandwidth Profile, " +\r
- "then there cannot be any other Ingress Bandwidth " +\r
- "Profiles at that UNI.";\r
- }\r
- must "not(./egress-bw-profile-per-uni) or " +\r
- "((./egress-bw-profile-per-uni) and " +\r
- "not(./egress-envelopes))" {\r
- error-message "If there is a per UNI Egress Bandwidth " +\r
- "Profile, then there cannot be any other Egress " +\r
- "Bandwidth Profiles at that UNI.";\r
- description\r
- "If there is a per UNI Egress Bandwidth Profile, " +\r
- "then there cannot be any other Egress Bandwidth " +\r
- "Profiles at that UNI.";\r
- }\r
- must "(not(/mef-global:mef-global/mef-global:" +\r
- "subscribers) and " +\r
- "not(./subscriber)) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "subscribers and " +\r
- "./subscriber)" {\r
- error-message "If the Subscribers list has been " +\r
- "populated, a UNI must be configured for " +\r
- "a single Subscriber.";\r
- description\r
- "[MEF103] [R1] A UNI must be dedicated to a single " +\r
- "Subscriber. This must statement is effectively " +\r
- "a 'mandatory true' when the Global Subscribers " +\r
- "list is being used.";\r
- }\r
- must "(not(/mef-global:mef-global/mef-global:cens) and " +\r
- "not(./cen-id)) or " +\r
- "(/mef-global:mef-global/mef-global:cens and " +\r
- "./cen-id)" {\r
- error-message "If the CENs list has been populated, " +\r
- "a UNI must be configured for a single CEN.";\r
- description\r
- "[MEF103] [R57] A UNI must be dedicated to a " +\r
- "single CEN. This must statement is effectively " +\r
- "a 'mandatory true' when the Global CENs list " +\r
- "is being used.";\r
- }\r
- key "uni-id";\r
- description\r
- "MEF UNI List.";\r
- reference "[MEF6.2] Section 8.2.2.";\r
- container ip-unis {\r
- list ip-uni {\r
- key "ip-uni-id";\r
- leaf ip-uni-id {\r
- type mef-types:identifier45;\r
- }\r
- leaf id {\r
- type mef-types:identifier45;\r
- }\r
- leaf ip-address {\r
- type inet:ip-prefix;\r
- }\r
- leaf vlan {\r
- type ethertype:vlan-id;\r
- }\r
- container subnets {\r
- list subnet {\r
- key "subnet";\r
- leaf subnet {\r
- type inet:ip-prefix;\r
- }\r
- leaf gateway {\r
- type inet:ip-address;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- container physical-layers {\r
- description\r
- "The Physical Layer MUST operate in a full duplex " +\r
- "mode. It is not configurable.";\r
- reference "[MEF10.3] Section 9.2, [R61], [R62]";\r
- container links {\r
- presence "A UNI must have links.";\r
- description\r
- "The Physical Layer for each physical link " +\r
- "implementing the UNI MUST be one of the " +\r
- "PHYs listed in IEEE Std 802.3–2012 but " +\r
- "excluding 1000BASE-PX-D and 1000BASE-PX-U.";\r
- reference "[MEF10.3] Section 9.2 [R60]";\r
- list link {\r
- must "count(.) >= 1" {\r
- error-message "A UNI must have at least one " +\r
- "physical link configured.";\r
- description\r
- "A UNI must have at least one physical link " +\r
- "configured.";\r
- }\r
- key "device interface";\r
- description\r
- "A list of all the physical ports associated " +\r
- "with this Link Layer.";\r
- leaf device {\r
- type leafref {\r
- path "/mef-topology:mef-topology/mef-topology:" +\r
- "devices/mef-topology:device/" +\r
- "mef-topology:dev-id";\r
- }\r
- description\r
- "The Physical Layer for each physical link " +\r
- "implementing the UNI MUST be one of the " +\r
- "PHYs listed in IEEE Std 802.3–2012 but " +\r
- "excluding 1000BASE-PX-D and 1000BASE-PX-U.";\r
- reference "[MEF10.3] Section 9.2 [R60]";\r
- }\r
- leaf interface {\r
- type leafref {\r
- path "/mef-topology:mef-topology/mef-topology:" +\r
- "devices/mef-topology:device" +\r
- "[mef-topology:dev-id = " +\r
- "current()/../device]" +\r
- "/mef-topology:interfaces/mef-topology:" +\r
- "interface/mef-topology:phy";\r
- }\r
- description\r
- "The Physical Layer for each physical link " +\r
- "implementing the UNI MUST be one of the " +\r
- "PHYs listed in IEEE Std 802.3–2012 but " +\r
- "excluding 1000BASE-PX-D and 1000BASE-PX-U.";\r
- reference "[MEF10.3] Section 9.2 [R60]";\r
- }\r
- leaf ieee8023-phy {\r
- type identityref {\r
- base mef-types:ieee-8023-interface-type;\r
- }\r
- must "(. != 'mef-types:" +\r
- "ieee8023-1000BASE-PX-D') and " +\r
- "(. != 'mef-types:ieee8023-1000BASE-PX-U')" {\r
- error-message "The Physical Layer for each " +\r
- "physical link implementing the UNI " +\r
- "cannot be 1000BASE-PX-D and 1000BASE-PX-U.";\r
- description\r
- "The Physical Layer for each physical " +\r
- "link implementing the UNI cannot be " +\r
- "1000BASE-PX-D and 1000BASE-PX-U.";\r
- }\r
- description\r
- "The Physical Layer for each physical link " +\r
- "implementing the UNI MUST be one of the " +\r
- "PHYs listed in IEEE Std 802.3–2012 but " +\r
- "excluding 1000BASE-PX-D and 1000BASE-PX-U.";\r
- reference "[MEF10.3] Section 9.2 [R60]";\r
- }\r
- leaf connection-speed {\r
- type mef-types:ext-if-physical-layer-type;\r
- units "bits-per-second";\r
- default "1G";\r
- description\r
- "Physical Layer Connection Speed (Max Data Rate).";\r
- reference "[MEF10.3] Section 9.2. [MEF6.2] " +\r
- "Section 8.2.2. [MEF20] [R80].";\r
- }\r
- leaf phy-auto-neg {\r
- type mef-types:auto-negotiation-type;\r
- default "on";\r
- description\r
- "Auto-Negotiation ON/OFF/Auto.";\r
- reference "[MEF6.2] Section 8.2.2. [MEF20] [R80]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf sync-mode-enabled {\r
- type boolean;\r
- must ".='false' or (.='true' and " +\r
- "../clock-accuracy)" {\r
- error-message "The quality of the clock " +\r
- "reference must be set if Synchronous " +\r
- "Mode is enabled.";\r
- description\r
- "The quality of the clock reference must " +\r
- "be set if Synchronous Mode is enabled.";\r
- }\r
- default "false";\r
- description\r
- "Enabled or Disabled for each physical link " +\r
- "implementing the UNI.";\r
- reference "[MEF10.3] Section 9.3. [MEF6.2] " +\r
- "Section 8.2.2. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf clock-accuracy {\r
- type decimal64 {\r
- fraction-digits 3;\r
- }\r
- units "ppm";\r
- description\r
- "ESMC:Ethernet Equipment Slave Clock Accuracy " +\r
- "in PPM. IEEE 802.3 standard specifies " +\r
- "that Ethernet clock accuracy is to be less " +\r
- "than or equal to +- 4.6 PPM.";\r
- reference "[MEF10.3] Section 9.3, [R62]. " +\r
- "[MEF22.1], [IEEE802.3].";\r
- }\r
- }\r
- }\r
- leaf number-of-links {\r
- type uint32 {\r
- range "1..max";\r
- }\r
- must ". = count(../links/link)" {\r
- error-message "The UNI Number of Links value " +\r
- "must match to the number of interfaces " +\r
- "in the link list.";\r
- description\r
- "The UNI Number of Links value must match " +\r
- "to the number of interfaces in the link list.";\r
- }\r
- default "1";\r
- description\r
- "The number of links configured in the links list.";\r
- reference "[MEF10.3] [R63]. [MEF7.3] Section 10.2.2.";\r
- }\r
- }\r
- container ce-vlans {\r
- description\r
- "Each Device (and by extension UNIs) MUST have list " +\r
- "of the CE-VLAN ID including mappings to configured " +\r
- "EVCs if assigned. This list of ce-vlans is a " +\r
- "complete list of all VLANs associated with this " +\r
- "UNI. At the Service Module level, there are two " +\r
- "lists: This one and the list of CE-VLAN IDs " +\r
- "associated with the EVC's UNI List as part of " +\r
- "the MEF Service Definition. ";\r
- reference "[MEF10.3] Section 9.10, [R77], [R78]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- list ce-vlan {\r
- key "vid";\r
- description\r
- "A list of all EC-VLANs allowed ingres or egress " +\r
- "on the UNI. This is the UNI-specific CE-VLAN ID " +\r
- "listing as part of the Service Level " +\r
- "CE-VLAN ID / EVC Map.";\r
- reference "[MEF10.3] Section 9.10.1.";\r
- leaf vid {\r
- type mef-types:vlan-id-type;\r
- description\r
- "The Customer Edge VLAN ID is equivalent " +\r
- "to a Static VLAN allowed on that port " +\r
- "(ie. Port is not Forbidden). The " +\r
- "association with the EVC is part of " +\r
- "the EVC configuration.";\r
- reference "[MEF10.3] Section 9.10.";\r
- }\r
- }\r
- }\r
- container ingress-envelopes {\r
- presence "Ingress Bandwidth Profile Envelopes " +\r
- "configured.";\r
- description\r
- "UNI Bandwidth Profile Flow Envelopes.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1: [R3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- list envelope {\r
- key "env-id";\r
- description\r
- "UNI Bandwidth Profile Flow Envelope List.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1, [R3], " +\r
- "Section 8.2.2, [R4]. [MEF7.3] " +\r
- "Section 10.2.2.";\r
- container bwp-flows {\r
- presence "Bandwidth Profile configured for " +\r
- "this envelope.";\r
- description\r
- "UNI Bandwidth Profile Flows per Envelope.";\r
- reference "[MEF10.3] Section 12.1. " +\r
- "[MEF6.2] Section 10.1.";\r
- list bwp-flow {\r
- key "bw-profile";\r
- ordered-by user;\r
- description\r
- "UNI Bandwidth Profile Flow List per Envelope. " +\r
- "The order of entries in the list is user " +\r
- "controlled. The first element of the list " +\r
- "has the lowest priority and the last " +\r
- "element will have the highest priority.";\r
- reference "[MEF10.3] Section 12.1. " +\r
- "[MEF6.2] Section 10.1. " +\r
- "[MEF6.2] Section 8.2.1, [R3]. ";\r
- leaf bw-profile {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:" +\r
- "ingress-bwp-flows/mef-global:" +\r
- "bwp-flow/mef-global:bw-profile";\r
- }\r
- must "(../../../../../token-share-enabled = " +\r
- "'true') or " +\r
- "((../../../../../token-share-enabled = " +\r
- "'false') and " +\r
- "(count(../../bwp-flow) = 1))" {\r
- error-message "A UNI with Token Share " +\r
- "Disabled MUST have exactly one " +\r
- "Bandwidth Profile Flow per envelope.";\r
- description\r
- "A UNI with Token Share Disabled MUST " +\r
- "have exactly one Bandwidth Profile Flow " +\r
- "per envelope.";\r
- }\r
- must "(../../../coupling-enabled = 'false') or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:" +\r
- "ingress-bwp-flows/mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = current()]/" +\r
- "mef-global:coupling-enabled = 'false')" {\r
- error-message "If an Ingress Envelope's " +\r
- "Coupling Flag is Enabled, then " +\r
- "the Coupling Flags must be disabled " +\r
- "for all Bandwidth Profile Flows " +\r
- "mapped to the Envelope.";\r
- description\r
- "If an Ingress Envelope's Coupling Flag is " +\r
- "Enabled, then the Coupling Flags must " +\r
- "be disabled for all Bandwidth Profile " +\r
- "Flows mapped to the Envelope.";\r
- }\r
- description\r
- "If no Ingress Bandwidth Profile per UNI " +\r
- "has been defined (ie. 'No'), then the " +\r
- "behavior has been defined at the Service " +\r
- "Level of the configuration.";\r
- reference "[MEF10.3] Section 9.14, " +\r
- "Section 12.1, [R84], [R134]. " +\r
- "[MEF6.2] Section 8.2.1,[R3],[R136]. " +\r
- "Section 8.2.2, 10.1, [R6]. [MEF7.3] " +\r
- "Section 10.2.2.";\r
- }\r
- }\r
- }\r
- leaf env-id {\r
- type mef-types:identifier45;\r
- description\r
- "This attribute identifies the Envelope of " +\r
- "Bandwidth Profile Parameters.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- leaf coupling-enabled {\r
- type boolean;\r
- must "not(../bwp-flows) or " +\r
- "(../bwp-flows/bwp-flow[2]) or " +\r
- "(. = 'false')" {\r
- error-message "When only one Bandwidth Profile " +\r
- "Flow is mapped to an envelope, Envelope " +\r
- "Coupling must be Disabled.";\r
- description\r
- "When only one Bandwidth Profile Flow is " +\r
- "mapped to an envelope, Envelope " +\r
- "Coupling must be Disabled.";\r
- }\r
- default "false";\r
- description\r
- "The Envelope Coupling Flag (CF) attribute.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- }\r
- }\r
- container egress-envelopes {\r
- presence "Egress Bandwidth Profile Envelopes configured.";\r
- description\r
- "UNI Bandwidth Profile Flow Envelopes.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1: [R3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- list envelope {\r
- key "env-id";\r
- description\r
- "UNI Bandwidth Profile Flow Envelope List.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1, [R3], " +\r
- "Section 8.2.2, [R4]. [MEF7.3] " +\r
- "Section 10.2.2.";\r
- container bwp-flows {\r
- presence "Bandwidth Profile configured for " +\r
- "this envelope.";\r
- description\r
- "UNI Bandwidth Profile Flows per Envelope.";\r
- reference "[MEF10.3] Section 12.1. [MEF6.2] " +\r
- "Section 10.1.";\r
- list bwp-flow {\r
- key "bw-profile";\r
- ordered-by user;\r
- description\r
- "UNI Bandwidth Profile Flow List per Envelope. " +\r
- "The order of entries in the list is user " +\r
- "controlled. The first element of the list " +\r
- "has the lowest priority and the last element " +\r
- "will have the highest priority.";\r
- reference "[MEF10.3] Section 12.1. " +\r
- "[MEF6.2] Section 10.1. " +\r
- "[MEF6.2] Section 8.2.1, [R3]. ";\r
- leaf bw-profile {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:egress-bwp-flows" +\r
- "/mef-global:bwp-flow/" +\r
- "mef-global:bw-profile";\r
- }\r
- must "(../../../../../token-share-enabled = " +\r
- "'true') or " +\r
- "((../../../../../token-share-enabled = " +\r
- "'false') and " +\r
- "(count(../../bwp-flow) = 1))" {\r
- error-message "A UNI with Token Share " +\r
- "Disabled must have exactly one " +\r
- "Bandwidth Profile Flow per envelope.";\r
- description\r
- "A UNI with Token Share Disabled must have " +\r
- "exactly one Bandwidth Profile Flow per " +\r
- "envelope.";\r
- }\r
- must "(../../../coupling-enabled = 'false') or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:" +\r
- "egress-bwp-flows/mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = current()]/" +\r
- "mef-global:coupling-enabled = 'false')" {\r
- error-message "If an Egress Envelope's " +\r
- "Coupling Flag is Enabled, then the " +\r
- "Coupling Flags must be disabled " +\r
- "for all Bandwidth Profile Flows " +\r
- "mapped to the Envelope.";\r
- description\r
- "If an Egress Envelope's Coupling Flag " +\r
- "is Enabled, then the Coupling Flags must " +\r
- "be disabled for all Bandwidth Profile " +\r
- "Flows mapped to the Envelope.";\r
- }\r
- description\r
- "UNI Bandwidth Profile Flow per Envelope.";\r
- reference "[MEF10.3] Section 12.1. " +\r
- "[MEF6.2] Section 10.1. " +\r
- "[MEF6.2] Section 8.2.1, [R3], [R136]. ";\r
- }\r
- }\r
- }\r
- leaf env-id {\r
- type mef-types:identifier45;\r
- description\r
- "This attribute identifies the Envelope of " +\r
- "Bandwidth Profile Parameters.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- leaf coupling-enabled {\r
- type boolean;\r
- must "not(../bwp-flows) or " +\r
- "(../bwp-flows/bwp-flow[2]) or " +\r
- "(. = 'false')" {\r
- error-message "When only one Bandwidth Profile " +\r
- "Flow is mapped to an envelope, " +\r
- "Envelope Coupling must be Disabled.";\r
- description\r
- "When only one Bandwidth Profile Flow is " +\r
- "mapped to an envelope, Envelope Coupling " +\r
- "must be Disabled.";\r
- }\r
- default "false";\r
- description\r
- "The Envelope Coupling Flag (CF) attribute.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- }\r
- }\r
- container status {\r
- description\r
- "This group is related to the MEF 7.3 External " +\r
- "Network Interface";\r
- leaf oper-state-enabled {\r
- type boolean;\r
- default "false";\r
- config false;\r
- description\r
- "Operational Status of the Link as " +\r
- "Enabled/Disabled.";\r
- reference "[MEF15]. [MEF7.3] Section 10.1.1.";\r
- }\r
- leaf available-status {\r
- type mef-types:ext-if-availability-type;\r
- default "not-installed";\r
- config false;\r
- description\r
- "Availability Status of the Link.";\r
- reference "[MEF15]. [MEF7.3] Section 10.1.1.";\r
- }\r
- leaf physical-layer {\r
- type mef-types:ext-if-physical-layer-type;\r
- default "1G";\r
- config false;\r
- description\r
- "Physical Layer Connection Speed.";\r
- reference "[MEF15]. [MEF7.3] Section 10.1.1.";\r
- }\r
- leaf number-of-links {\r
- type uint32;\r
- default "0";\r
- config false;\r
- description\r
- "A count of the number of physical links in this " +\r
- "physical layer.";\r
- reference "[MEF15]. [MEF7.3] Section 10.1.1.";\r
- }\r
- leaf svc-frame-format {\r
- type mef-types:svc-frame-format-type;\r
- default "ctag";\r
- config false;\r
- description\r
- "The format must be that of a MAC Frame specified " +\r
- "in IEEE Std 802.3-2012 Clause 3.";\r
- reference "[MEF10.3] Section 9.6. [MEF15]. " +\r
- "[MEF7.2]. [MEF7.3] Section 10.1.1.";\r
- }\r
- }\r
- leaf cen-id {\r
- when "/mef-global:mef-global/mef-global:cens" {\r
- description\r
- "Only configure when the Global CENs list " +\r
- "has been populated.";\r
- }\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:cens/" +\r
- "mef-global:cen/mef-global:cen-id";\r
- }\r
- description\r
- "A CEN is defined as a network from a Service " +\r
- "Provider (SP). The CEN ID must be unique for " +\r
- "a specific Service Provider.";\r
- reference "[MEF10.3] Section 7.";\r
- }\r
- leaf uni-id {\r
- type mef-types:identifier45;\r
- description\r
- " The UNI IDs must be be unique within a specific CEN.";\r
- reference "[MEF10.3] Section 9.1, [R1], [R57], [R58], " +\r
- "[R59]. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf uni-type {\r
- type mef-types:uni-mode-type;\r
- default "uni";\r
- description\r
- " The UNI Type must be one of {UNI, VUNI}.";\r
- reference "[MEF10.3] Section 9.1, [R1], [R57], [R58], " +\r
- "[R59]. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf subscriber {\r
- when "/mef-global:mef-global/mef-global:subscribers" {\r
- description\r
- "UNI Subscriber Attribute is only configurable " +\r
- "when multiple Global Subscribers have been " +\r
- "configured.";\r
- }\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:subscribers/" +\r
- "mef-global:subscriber/mef-global:sub-id";\r
- }\r
- description\r
- "A UNI MUST be dedicated to a single Subscriber. " +\r
- "This value can only be configured if the " +\r
- "'/mef-global/subscribers/subscriber' list " +\r
- "has been populated.";\r
- reference "[MEF10.3] Section 7.";\r
- }\r
- leaf admin-state-enabled {\r
- type boolean;\r
- default "true";\r
- description\r
- "Locked/Unlocked is inconsistent with Oper Status " +\r
- "and will be confusing.";\r
- reference "MEF 15. MEF 7.3 Section 10.1.1.";\r
- }\r
- leaf mac-address {\r
- type yang:mac-address;\r
- description\r
- "MAC Address.";\r
- reference "[MEF15]. [MEF7.3] Section 10.1.1.";\r
- }\r
- leaf uni-resiliency {\r
- type mef-types:uni-resiliency-type;\r
- must "(. != 'none') or ((. = 'none') and " +\r
- "(../physical-layers/number-of-links = 1))" {\r
- error-message "If uni-resiliency is 'none', " +\r
- "number-of-links must be 1.";\r
- description\r
- "If uni-resiliency is 'none', number-of-links " +\r
- "must be 1.";\r
- }\r
- must "(. != 'dual-link-aggregation') or " +\r
- "((. = 'dual-link-aggregation') and " +\r
- "(../physical-layers/number-of-links = 2))" {\r
- error-message "If uni-resiliency is " +\r
- "'dual-link-aggregation', " +\r
- "number-of-links must be 2.";\r
- description\r
- "If uni-resiliency is 'dual-link-aggregation', " +\r
- "number-of-links must be 2.";\r
- }\r
- must "(. != 'other') or " +\r
- "((. = 'other') and " +\r
- "(../physical-layers/number-of-links > 2))" {\r
- error-message "If uni-resiliency is 'other', " +\r
- "number-of-links must be 3 or greater.";\r
- description\r
- "If uni-resiliency is 'other', number-of-links " +\r
- "must be 3 or greater.";\r
- }\r
- default "none";\r
- description\r
- "UNI Resiliency.";\r
- reference "[MEF10.3] Section 9.5 [R64], [R65], [R66], " +\r
- "[R67]. [MEF6.2] Section 8.2.2.";\r
- }\r
- leaf max-svc-frame-size {\r
- type mef-types:max-svc-frame-size-type;\r
- default "1600";\r
- description\r
- "This attribute describes the maximum service frame " +\r
- "size for the UNI.";\r
- reference "[MEF10.3] Section 9.7, [R71], MEF 6.2 " +\r
- "Section 8.2.2 and MEF 22.1: [D2]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf svc-mux-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "Service Multiplexing Enable - Enable if to support " +\r
- "multiple EVCs per UNI.";\r
- reference "[MEF10.3] Section 9.8. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf bundling-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "When a UNI has Bundling Enabled, it MUST be able to " +\r
- "support more than one CE-VLAN ID mapping to a " +\r
- "particular EVC at the UNI. When more than one " +\r
- "CE-VLAN-ID is mapped to an EVC at a UNI, the " +\r
- "EVC have CE-VLAN ID Preservation enabled";\r
- reference "[MEF10.3] Section 9.12, [R25], [R77], " +\r
- "[R78], [R80]. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf all-to-one-bundling-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "When all-to-one-bundling-enabled = true, all " +\r
- "CE-VLAN IDs MUST map to a single EVC at the " +\r
- "UNI. This also means that the UNI cannot " +\r
- "have svc-mux-enabled = true. When " +\r
- "all-to-one-bundling-enabled = true, " +\r
- "all other UNIs in the EVC associating this UNI " +\r
- "must have all-to-one-bundling-enabled = true. " +\r
- "If this values is true, the value of " +\r
- "ce-vlan-id-for-untagged-and-priority is not " +\r
- "applicable.";\r
- reference "[MEF10.3] Section 9.13, Table 12 " +\r
- "(5 valid combinations), [R82], [R83]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf ce-vlan-id-for-untagged-and-priority {\r
- type mef-types:vlan-id-type;\r
- default "1";\r
- description\r
- "The ce-vlan-id-for-untagged-and-priority is " +\r
- "equivalent to the Layer 2 PVID (Port VLAN ID) " +\r
- "with the Q-BRIDGE-MIB option for frame admitance set " +\r
- "to admitAll. With AdmitAll set, all Untagged and " +\r
- "Priority Tagged Service Frames are treated with " +\r
- "the CE-VLAN-ID tag on ingress. It is not applicable " +\r
- "if All in One Bundling is enabled.";\r
- reference "[MEF10.3] Section 9.9, [R73], [R74], " +\r
- "[R75]. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf max-evc-count {\r
- type uint32 {\r
- range "1..max";\r
- }\r
- default "1";\r
- description\r
- "The Maximum Number of EVCs that can be supported " +\r
- "by this UNI (Default 1).";\r
- reference "[MEF10.3] Section 9.11, [R79]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf token-share-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "Token Share Enabled/Disabled is used to indicate " +\r
- "whether a given UNI is capable of sharing tokens " +\r
- "across Bandwidth Profile Flows in an envelope.";\r
- reference "[MEF6.2] Section 8.2.1, [R2], [D1], [R3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf ingress-bw-profile-per-uni {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/mef-global:" +\r
- "bwp-flow/mef-global:bw-profile";\r
- }\r
- description\r
- "Ingress Bandwidth Profile for this UNI.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1: [R3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf egress-bw-profile-per-uni {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:egress-bwp-flows/mef-global:" +\r
- "bwp-flow/mef-global:bw-profile";\r
- }\r
- description\r
- "Egress Bandwidth Profile Flow for this UNI.";\r
- reference "[MEF10.3] Section 9.15, Section 12.1. " +\r
- "[MEF6.2] Section 8.2.1: [R3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf link-oam-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "Link OAM Enabled/Disabled.";\r
- reference "[MEF10.3] Section 9.16, [R86]. " +\r
- "[MEF6.2] Section 8.2.2, [D3]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf uni-meg-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "Enables / Disables the Maintenance Entity Group (MEG).";\r
- reference "[MEF10.3] Section 9.17, [R87]. " +\r
- "[MEF30.1] Section 7.9. [MEF6.2] Section 8.2.2, " +\r
- "[D4]. [MEF7.3] Section 10.2.2.";\r
- }\r
- leaf elmi-enabled {\r
- type boolean;\r
- must "(. = 'false') or " +\r
- "(. = 'true' and " +\r
- "(../elmi-profile))" {\r
- error-message "ELMI Profile must be set if " +\r
- "ELMI is Enabled.";\r
- description\r
- "Ethernet Local Management Interface(ELMI) " +\r
- "Profile ID must be set if ELMI is Enabled.";\r
- }\r
- default "false";\r
- description\r
- "Ethernet Local Management Interface(ELMI) " +\r
- "Enabled / Disabled.";\r
- reference "[MEF10.3] Section 9.18, [R88]. " +\r
- "[MEF16]. [MEF6.2] Section 8.2.2, [D5]. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf elmi-profile {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:elmi/mef-global:elmi-profile/" +\r
- "mef-global:id";\r
- }\r
- description\r
- "The ELMI Profile is only applicable when ELMI " +\r
- "is enabled. The E-LMI protocol is based on " +\r
- "ITU-T Q.933, X.36 and other relevant " +\r
- "recommendations as well as Frame Relay " +\r
- "Local Management Interface (FR-LMI) " +\r
- "Implementation Agreement document defined " +\r
- "by the Frame Relay Forum and related " +\r
- "ITU-T recommendations.";\r
- reference "[MEF10.3] Section 9.18. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf l2cp-address-set {\r
- type mef-types:l2cp-address-set-type;\r
- default "aware-cta";\r
- description\r
- "The L2CP Address Set Service Attribute specifies " +\r
- "the subset of the Bridge Reserved Addresses " +\r
- "that are filtered (i.e. L2CP Frames with " +\r
- "this destination address are Peered or " +\r
- "Discarded but not Passed) at a L2CP Decision Point.";\r
- reference "[MEF10.3] Section 9.19. " +\r
- "[MEF45] Section 8.1, [R2] through [R9]. " +\r
- "[MEF6.2] Section 8.2.2, [R1]. " +\r
- "[MEF45] Section 8.1.";\r
- }\r
- leaf l2cp-peering-profile {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:l2cp-peering/mef-global:" +\r
- "l2cp-profile/mef-global:id";\r
- }\r
- description\r
- "L2CP Peering Profile for this UNI. This profile " +\r
- "may contain groups of L2CP Destination " +\r
- "MAC Addresses and protocols to be peered at " +\r
- "the UNI (as opposed to being passed or discarded).";\r
- reference "[MEF10.3] Section 9.19. " +\r
- "[MEF45] Section 8.2. " +\r
- "[MEF7.3] Section 10.2.2.";\r
- }\r
- leaf tenant-id {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:tenants-instances/mef-global:tenant-list/mef-global:name";\r
- }\r
- }\r
- }\r
- }\r
- }\r
-}\r
+module mef-interfaces {
+ namespace "http://metroethernetforum.org/ns/yang/mef-interfaces";
+ prefix mef-interfaces;
+ import ietf-inet-types { prefix inet; }
+ import ietf-yang-types { prefix yang; }
+ import mef-types { prefix mef-types; }
+ import mef-global { prefix mef-global; }
+ import mef-topology { prefix mef-topology; }
+ import yang-ext {prefix ext; revision-date "2013-07-09";}
+
+ import opendaylight-l2-types { prefix ethertype; }
+ // revision-date "2013-08-27";
+
+ organization "Metro Ethernet Forum";
+ contact
+ "Web URL: http://metroethernetforum.org/ E-mail: mibs@metroethernetforum.org
+ Postal: Metro Ethernet Forum 6033 W. Century Boulevard, Suite
+ 1107 Los Angeles, CA 90045 U.S.A. Phone: +1 310-642-2800 Fax:
+ +1 310-642-2808";
+ description
+ "This module implements the UNI functionality specified in MEF
+ 10.3, MEF 6.2, and MEF 7.2. Reference Overview: A number of base
+ documents have been used to create the MEF Interfaces YANG Module.
+ The following are the abbreviations for the baseline documents:
+ [RFC 6991] refers to IETF RFC 6991 'Common YANG Data Types', 2013-07-15
+ [RFC 6643] refers to IETF RFC 6643 'Translation of Structure of
+ Management Information Version 2 (SMIv2) MIB Modules to YANG Modules',
+ 2011-11-25 [802.1AB] refers to 'Station and Media Access Control
+ Connectivity Discovery', IEEE 802.1AB-2009, September 2009 [802.1q]
+ refers to IEEE 802.1Q-2011 'IEEE Standard for Local and metropolitan
+ area networks --Media Access Control (MAC) Bridges and Virtual
+ Bridged Local Area Networks, August 2011 [802-2001] refers to
+ 'IEEE Standard for Local and Metropolitan Area Networks: Overview
+ and Architecture', IEEE 802-2001, February 2002 [MEF10.3] refers
+ to MEF 10.3 'Ethernet Services Attributes Phase 3', October 2013
+ [MEF6.2] refers to MEF 6.2 'EVC Ethernet Services Defintions Phase
+ 3', August 2014 [MEF40] refers to MEF 40 'UNI and EVC Definition
+ of Managed Objects', April 2013 [MEF45] refers to MEF 45 'Multi-CEN
+ L2CP', August 2014 [MEF7.2] refers to MEF 7.2 'Carrier Ethernet
+ Management Information Model', April 2013 [MEF7.3] refers to MEF
+ 7.3 'Carrier Ethernet Management Information Model', Working Draft
+ #1 2015 [RFC 2737] refers to IETF RFC 2737 'Entity MIB (Version
+ 2)', December 1999 [RFC 2863] refers to IETF RFC 2863 'The Interfaces
+ Group MIB', June 2000 [RFC 3419] refers to IETF RFC 3419 'Textual
+ Conventions for Transport Addresses', December 2002 [Y.1731] refers
+ to ITU-T Y.1731 'OAM functions and mechanisms for Ethernet based
+ networks', July 2011 [Q.840.1] refers to ITU-T Q.840.1 'Requirements
+ and analysis for NMS-EMS management interface of Ethernet over
+ Transport and Metro Ethernet Network(EoT/MEN)' March 2007";
+ revision 2015-05-26 {
+ description
+ "Formal Project Review Draft 1.";
+ reference "EVC Ethernet Services Definitions YANG Modules " +
+ "(MEF XX), TBD";
+ }
+ container mef-interfaces {
+ description
+ "MEF Interfaces";
+ container unis {
+ description
+ "User Network Interface(UNI).";
+ list uni {
+ must "not(./ingress-bw-profile-per-uni) or " +
+ "((./ingress-bw-profile-per-uni) and " +
+ "not(./ingress-envelopes))" {
+ error-message "If there is a per UNI Ingress Bandwidth " +
+ "Profile, then there cannot be any other Ingress " +
+ "Bandwidth Profiles at that UNI.";
+ description
+ "If there is a per UNI Ingress Bandwidth Profile, " +
+ "then there cannot be any other Ingress Bandwidth " +
+ "Profiles at that UNI.";
+ }
+ must "not(./egress-bw-profile-per-uni) or " +
+ "((./egress-bw-profile-per-uni) and " +
+ "not(./egress-envelopes))" {
+ error-message "If there is a per UNI Egress Bandwidth " +
+ "Profile, then there cannot be any other Egress " +
+ "Bandwidth Profiles at that UNI.";
+ description
+ "If there is a per UNI Egress Bandwidth Profile, " +
+ "then there cannot be any other Egress Bandwidth " +
+ "Profiles at that UNI.";
+ }
+ must "(not(/mef-global:mef-global/mef-global:" +
+ "subscribers) and " +
+ "not(./subscriber)) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "subscribers and " +
+ "./subscriber)" {
+ error-message "If the Subscribers list has been " +
+ "populated, a UNI must be configured for " +
+ "a single Subscriber.";
+ description
+ "[MEF103] [R1] A UNI must be dedicated to a single " +
+ "Subscriber. This must statement is effectively " +
+ "a 'mandatory true' when the Global Subscribers " +
+ "list is being used.";
+ }
+ must "(not(/mef-global:mef-global/mef-global:cens) and " +
+ "not(./cen-id)) or " +
+ "(/mef-global:mef-global/mef-global:cens and " +
+ "./cen-id)" {
+ error-message "If the CENs list has been populated, " +
+ "a UNI must be configured for a single CEN.";
+ description
+ "[MEF103] [R57] A UNI must be dedicated to a " +
+ "single CEN. This must statement is effectively " +
+ "a 'mandatory true' when the Global CENs list " +
+ "is being used.";
+ }
+ key "uni-id";
+ description
+ "MEF UNI List.";
+ reference "[MEF6.2] Section 8.2.2.";
+ container ip-unis {
+ list ip-uni {
+ key "ip-uni-id";
+ leaf ip-uni-id {
+ type mef-types:identifier45;
+ }
+ leaf ip-address {
+ type inet:ip-prefix;
+ }
+ leaf vlan {
+ type ethertype:vlan-id;
+ }
+ }
+ }
+ container physical-layers {
+ description
+ "The Physical Layer MUST operate in a full duplex " +
+ "mode. It is not configurable.";
+ reference "[MEF10.3] Section 9.2, [R61], [R62]";
+ container links {
+ presence "A UNI must have links.";
+ description
+ "The Physical Layer for each physical link " +
+ "implementing the UNI MUST be one of the " +
+ "PHYs listed in IEEE Std 802.3–2012 but " +
+ "excluding 1000BASE-PX-D and 1000BASE-PX-U.";
+ reference "[MEF10.3] Section 9.2 [R60]";
+ list link {
+ must "count(.) >= 1" {
+ error-message "A UNI must have at least one " +
+ "physical link configured.";
+ description
+ "A UNI must have at least one physical link " +
+ "configured.";
+ }
+ key "device interface";
+ description
+ "A list of all the physical ports associated " +
+ "with this Link Layer.";
+ leaf device {
+ type leafref {
+ path "/mef-topology:mef-topology/mef-topology:" +
+ "devices/mef-topology:device/" +
+ "mef-topology:dev-id";
+ }
+ description
+ "The Physical Layer for each physical link " +
+ "implementing the UNI MUST be one of the " +
+ "PHYs listed in IEEE Std 802.3–2012 but " +
+ "excluding 1000BASE-PX-D and 1000BASE-PX-U.";
+ reference "[MEF10.3] Section 9.2 [R60]";
+ }
+ leaf interface {
+ type leafref {
+ path "/mef-topology:mef-topology/mef-topology:" +
+ "devices/mef-topology:device" +
+ "[mef-topology:dev-id = " +
+ "current()/../device]" +
+ "/mef-topology:interfaces/mef-topology:" +
+ "interface/mef-topology:phy";
+ }
+ description
+ "The Physical Layer for each physical link " +
+ "implementing the UNI MUST be one of the " +
+ "PHYs listed in IEEE Std 802.3–2012 but " +
+ "excluding 1000BASE-PX-D and 1000BASE-PX-U.";
+ reference "[MEF10.3] Section 9.2 [R60]";
+ }
+ leaf ieee8023-phy {
+ type identityref {
+ base mef-types:ieee-8023-interface-type;
+ }
+ must "(. != 'mef-types:" +
+ "ieee8023-1000BASE-PX-D') and " +
+ "(. != 'mef-types:ieee8023-1000BASE-PX-U')" {
+ error-message "The Physical Layer for each " +
+ "physical link implementing the UNI " +
+ "cannot be 1000BASE-PX-D and 1000BASE-PX-U.";
+ description
+ "The Physical Layer for each physical " +
+ "link implementing the UNI cannot be " +
+ "1000BASE-PX-D and 1000BASE-PX-U.";
+ }
+ description
+ "The Physical Layer for each physical link " +
+ "implementing the UNI MUST be one of the " +
+ "PHYs listed in IEEE Std 802.3–2012 but " +
+ "excluding 1000BASE-PX-D and 1000BASE-PX-U.";
+ reference "[MEF10.3] Section 9.2 [R60]";
+ }
+ leaf connection-speed {
+ type mef-types:ext-if-physical-layer-type;
+ units "bits-per-second";
+ default "1G";
+ description
+ "Physical Layer Connection Speed (Max Data Rate).";
+ reference "[MEF10.3] Section 9.2. [MEF6.2] " +
+ "Section 8.2.2. [MEF20] [R80].";
+ }
+ leaf phy-auto-neg {
+ type mef-types:auto-negotiation-type;
+ default "on";
+ description
+ "Auto-Negotiation ON/OFF/Auto.";
+ reference "[MEF6.2] Section 8.2.2. [MEF20] [R80]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf sync-mode-enabled {
+ type boolean;
+ must ".='false' or (.='true' and " +
+ "../clock-accuracy)" {
+ error-message "The quality of the clock " +
+ "reference must be set if Synchronous " +
+ "Mode is enabled.";
+ description
+ "The quality of the clock reference must " +
+ "be set if Synchronous Mode is enabled.";
+ }
+ default "false";
+ description
+ "Enabled or Disabled for each physical link " +
+ "implementing the UNI.";
+ reference "[MEF10.3] Section 9.3. [MEF6.2] " +
+ "Section 8.2.2. [MEF7.3] Section 10.2.2.";
+ }
+ leaf clock-accuracy {
+ type decimal64 {
+ fraction-digits 3;
+ }
+ units "ppm";
+ description
+ "ESMC:Ethernet Equipment Slave Clock Accuracy " +
+ "in PPM. IEEE 802.3 standard specifies " +
+ "that Ethernet clock accuracy is to be less " +
+ "than or equal to +- 4.6 PPM.";
+ reference "[MEF10.3] Section 9.3, [R62]. " +
+ "[MEF22.1], [IEEE802.3].";
+ }
+ }
+ }
+ leaf number-of-links {
+ type uint32 {
+ range "1..max";
+ }
+ must ". = count(../links/link)" {
+ error-message "The UNI Number of Links value " +
+ "must match to the number of interfaces " +
+ "in the link list.";
+ description
+ "The UNI Number of Links value must match " +
+ "to the number of interfaces in the link list.";
+ }
+ default "1";
+ description
+ "The number of links configured in the links list.";
+ reference "[MEF10.3] [R63]. [MEF7.3] Section 10.2.2.";
+ }
+ }
+ container ce-vlans {
+ description
+ "Each Device (and by extension UNIs) MUST have list " +
+ "of the CE-VLAN ID including mappings to configured " +
+ "EVCs if assigned. This list of ce-vlans is a " +
+ "complete list of all VLANs associated with this " +
+ "UNI. At the Service Module level, there are two " +
+ "lists: This one and the list of CE-VLAN IDs " +
+ "associated with the EVC's UNI List as part of " +
+ "the MEF Service Definition. ";
+ reference "[MEF10.3] Section 9.10, [R77], [R78]. " +
+ "[MEF7.3] Section 10.2.2.";
+ list ce-vlan {
+ key "vid";
+ description
+ "A list of all EC-VLANs allowed ingres or egress " +
+ "on the UNI. This is the UNI-specific CE-VLAN ID " +
+ "listing as part of the Service Level " +
+ "CE-VLAN ID / EVC Map.";
+ reference "[MEF10.3] Section 9.10.1.";
+ leaf vid {
+ type mef-types:vlan-id-type;
+ description
+ "The Customer Edge VLAN ID is equivalent " +
+ "to a Static VLAN allowed on that port " +
+ "(ie. Port is not Forbidden). The " +
+ "association with the EVC is part of " +
+ "the EVC configuration.";
+ reference "[MEF10.3] Section 9.10.";
+ }
+ }
+ }
+ container ingress-envelopes {
+ presence "Ingress Bandwidth Profile Envelopes " +
+ "configured.";
+ description
+ "UNI Bandwidth Profile Flow Envelopes.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1: [R3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ list envelope {
+ key "env-id";
+ description
+ "UNI Bandwidth Profile Flow Envelope List.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1, [R3], " +
+ "Section 8.2.2, [R4]. [MEF7.3] " +
+ "Section 10.2.2.";
+ container bwp-flows {
+ presence "Bandwidth Profile configured for " +
+ "this envelope.";
+ description
+ "UNI Bandwidth Profile Flows per Envelope.";
+ reference "[MEF10.3] Section 12.1. " +
+ "[MEF6.2] Section 10.1.";
+ list bwp-flow {
+ key "bw-profile";
+ ordered-by user;
+ description
+ "UNI Bandwidth Profile Flow List per Envelope. " +
+ "The order of entries in the list is user " +
+ "controlled. The first element of the list " +
+ "has the lowest priority and the last " +
+ "element will have the highest priority.";
+ reference "[MEF10.3] Section 12.1. " +
+ "[MEF6.2] Section 10.1. " +
+ "[MEF6.2] Section 8.2.1, [R3]. ";
+ leaf bw-profile {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:" +
+ "ingress-bwp-flows/mef-global:" +
+ "bwp-flow/mef-global:bw-profile";
+ }
+ must "(../../../../../token-share-enabled = " +
+ "'true') or " +
+ "((../../../../../token-share-enabled = " +
+ "'false') and " +
+ "(count(../../bwp-flow) = 1))" {
+ error-message "A UNI with Token Share " +
+ "Disabled MUST have exactly one " +
+ "Bandwidth Profile Flow per envelope.";
+ description
+ "A UNI with Token Share Disabled MUST " +
+ "have exactly one Bandwidth Profile Flow " +
+ "per envelope.";
+ }
+ must "(../../../coupling-enabled = 'false') or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:" +
+ "ingress-bwp-flows/mef-global:bwp-flow" +
+ "[mef-global:bw-profile = current()]/" +
+ "mef-global:coupling-enabled = 'false')" {
+ error-message "If an Ingress Envelope's " +
+ "Coupling Flag is Enabled, then " +
+ "the Coupling Flags must be disabled " +
+ "for all Bandwidth Profile Flows " +
+ "mapped to the Envelope.";
+ description
+ "If an Ingress Envelope's Coupling Flag is " +
+ "Enabled, then the Coupling Flags must " +
+ "be disabled for all Bandwidth Profile " +
+ "Flows mapped to the Envelope.";
+ }
+ description
+ "If no Ingress Bandwidth Profile per UNI " +
+ "has been defined (ie. 'No'), then the " +
+ "behavior has been defined at the Service " +
+ "Level of the configuration.";
+ reference "[MEF10.3] Section 9.14, " +
+ "Section 12.1, [R84], [R134]. " +
+ "[MEF6.2] Section 8.2.1,[R3],[R136]. " +
+ "Section 8.2.2, 10.1, [R6]. [MEF7.3] " +
+ "Section 10.2.2.";
+ }
+ }
+ }
+ leaf env-id {
+ type mef-types:identifier45;
+ description
+ "This attribute identifies the Envelope of " +
+ "Bandwidth Profile Parameters.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ leaf coupling-enabled {
+ type boolean;
+ must "not(../bwp-flows) or " +
+ "(../bwp-flows/bwp-flow[2]) or " +
+ "(. = 'false')" {
+ error-message "When only one Bandwidth Profile " +
+ "Flow is mapped to an envelope, Envelope " +
+ "Coupling must be Disabled.";
+ description
+ "When only one Bandwidth Profile Flow is " +
+ "mapped to an envelope, Envelope " +
+ "Coupling must be Disabled.";
+ }
+ default "false";
+ description
+ "The Envelope Coupling Flag (CF) attribute.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ }
+ }
+ container egress-envelopes {
+ presence "Egress Bandwidth Profile Envelopes configured.";
+ description
+ "UNI Bandwidth Profile Flow Envelopes.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1: [R3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ list envelope {
+ key "env-id";
+ description
+ "UNI Bandwidth Profile Flow Envelope List.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1, [R3], " +
+ "Section 8.2.2, [R4]. [MEF7.3] " +
+ "Section 10.2.2.";
+ container bwp-flows {
+ presence "Bandwidth Profile configured for " +
+ "this envelope.";
+ description
+ "UNI Bandwidth Profile Flows per Envelope.";
+ reference "[MEF10.3] Section 12.1. [MEF6.2] " +
+ "Section 10.1.";
+ list bwp-flow {
+ key "bw-profile";
+ ordered-by user;
+ description
+ "UNI Bandwidth Profile Flow List per Envelope. " +
+ "The order of entries in the list is user " +
+ "controlled. The first element of the list " +
+ "has the lowest priority and the last element " +
+ "will have the highest priority.";
+ reference "[MEF10.3] Section 12.1. " +
+ "[MEF6.2] Section 10.1. " +
+ "[MEF6.2] Section 8.2.1, [R3]. ";
+ leaf bw-profile {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:egress-bwp-flows" +
+ "/mef-global:bwp-flow/" +
+ "mef-global:bw-profile";
+ }
+ must "(../../../../../token-share-enabled = " +
+ "'true') or " +
+ "((../../../../../token-share-enabled = " +
+ "'false') and " +
+ "(count(../../bwp-flow) = 1))" {
+ error-message "A UNI with Token Share " +
+ "Disabled must have exactly one " +
+ "Bandwidth Profile Flow per envelope.";
+ description
+ "A UNI with Token Share Disabled must have " +
+ "exactly one Bandwidth Profile Flow per " +
+ "envelope.";
+ }
+ must "(../../../coupling-enabled = 'false') or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:" +
+ "egress-bwp-flows/mef-global:bwp-flow" +
+ "[mef-global:bw-profile = current()]/" +
+ "mef-global:coupling-enabled = 'false')" {
+ error-message "If an Egress Envelope's " +
+ "Coupling Flag is Enabled, then the " +
+ "Coupling Flags must be disabled " +
+ "for all Bandwidth Profile Flows " +
+ "mapped to the Envelope.";
+ description
+ "If an Egress Envelope's Coupling Flag " +
+ "is Enabled, then the Coupling Flags must " +
+ "be disabled for all Bandwidth Profile " +
+ "Flows mapped to the Envelope.";
+ }
+ description
+ "UNI Bandwidth Profile Flow per Envelope.";
+ reference "[MEF10.3] Section 12.1. " +
+ "[MEF6.2] Section 10.1. " +
+ "[MEF6.2] Section 8.2.1, [R3], [R136]. ";
+ }
+ }
+ }
+ leaf env-id {
+ type mef-types:identifier45;
+ description
+ "This attribute identifies the Envelope of " +
+ "Bandwidth Profile Parameters.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ leaf coupling-enabled {
+ type boolean;
+ must "not(../bwp-flows) or " +
+ "(../bwp-flows/bwp-flow[2]) or " +
+ "(. = 'false')" {
+ error-message "When only one Bandwidth Profile " +
+ "Flow is mapped to an envelope, " +
+ "Envelope Coupling must be Disabled.";
+ description
+ "When only one Bandwidth Profile Flow is " +
+ "mapped to an envelope, Envelope Coupling " +
+ "must be Disabled.";
+ }
+ default "false";
+ description
+ "The Envelope Coupling Flag (CF) attribute.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ }
+ }
+ container status {
+ description
+ "This group is related to the MEF 7.3 External " +
+ "Network Interface";
+ leaf oper-state-enabled {
+ type boolean;
+ default "false";
+ config false;
+ description
+ "Operational Status of the Link as " +
+ "Enabled/Disabled.";
+ reference "[MEF15]. [MEF7.3] Section 10.1.1.";
+ }
+ leaf available-status {
+ type mef-types:ext-if-availability-type;
+ default "not-installed";
+ config false;
+ description
+ "Availability Status of the Link.";
+ reference "[MEF15]. [MEF7.3] Section 10.1.1.";
+ }
+ leaf physical-layer {
+ type mef-types:ext-if-physical-layer-type;
+ default "1G";
+ config false;
+ description
+ "Physical Layer Connection Speed.";
+ reference "[MEF15]. [MEF7.3] Section 10.1.1.";
+ }
+ leaf number-of-links {
+ type uint32;
+ default "0";
+ config false;
+ description
+ "A count of the number of physical links in this " +
+ "physical layer.";
+ reference "[MEF15]. [MEF7.3] Section 10.1.1.";
+ }
+ leaf svc-frame-format {
+ type mef-types:svc-frame-format-type;
+ default "ctag";
+ config false;
+ description
+ "The format must be that of a MAC Frame specified " +
+ "in IEEE Std 802.3-2012 Clause 3.";
+ reference "[MEF10.3] Section 9.6. [MEF15]. " +
+ "[MEF7.2]. [MEF7.3] Section 10.1.1.";
+ }
+ }
+ leaf cen-id {
+ when "/mef-global:mef-global/mef-global:cens" {
+ description
+ "Only configure when the Global CENs list " +
+ "has been populated.";
+ }
+ type leafref {
+ path "/mef-global:mef-global/mef-global:cens/" +
+ "mef-global:cen/mef-global:cen-id";
+ }
+ description
+ "A CEN is defined as a network from a Service " +
+ "Provider (SP). The CEN ID must be unique for " +
+ "a specific Service Provider.";
+ reference "[MEF10.3] Section 7.";
+ }
+ leaf uni-id {
+ type mef-types:identifier45;
+ description
+ " The UNI IDs must be be unique within a specific CEN.";
+ reference "[MEF10.3] Section 9.1, [R1], [R57], [R58], " +
+ "[R59]. [MEF7.3] Section 10.2.2.";
+ }
+ leaf uni-type {
+ type mef-types:uni-mode-type;
+ default "uni";
+ description
+ " The UNI Type must be one of {UNI, VUNI}.";
+ reference "[MEF10.3] Section 9.1, [R1], [R57], [R58], " +
+ "[R59]. [MEF7.3] Section 10.2.2.";
+ }
+ leaf subscriber {
+ when "/mef-global:mef-global/mef-global:subscribers" {
+ description
+ "UNI Subscriber Attribute is only configurable " +
+ "when multiple Global Subscribers have been " +
+ "configured.";
+ }
+ type leafref {
+ path "/mef-global:mef-global/mef-global:subscribers/" +
+ "mef-global:subscriber/mef-global:sub-id";
+ }
+ description
+ "A UNI MUST be dedicated to a single Subscriber. " +
+ "This value can only be configured if the " +
+ "'/mef-global/subscribers/subscriber' list " +
+ "has been populated.";
+ reference "[MEF10.3] Section 7.";
+ }
+ leaf admin-state-enabled {
+ type boolean;
+ default "true";
+ description
+ "Locked/Unlocked is inconsistent with Oper Status " +
+ "and will be confusing.";
+ reference "MEF 15. MEF 7.3 Section 10.1.1.";
+ }
+ leaf mac-address {
+ type yang:mac-address;
+ description
+ "MAC Address.";
+ reference "[MEF15]. [MEF7.3] Section 10.1.1.";
+ }
+ leaf uni-resiliency {
+ type mef-types:uni-resiliency-type;
+ must "(. != 'none') or ((. = 'none') and " +
+ "(../physical-layers/number-of-links = 1))" {
+ error-message "If uni-resiliency is 'none', " +
+ "number-of-links must be 1.";
+ description
+ "If uni-resiliency is 'none', number-of-links " +
+ "must be 1.";
+ }
+ must "(. != 'dual-link-aggregation') or " +
+ "((. = 'dual-link-aggregation') and " +
+ "(../physical-layers/number-of-links = 2))" {
+ error-message "If uni-resiliency is " +
+ "'dual-link-aggregation', " +
+ "number-of-links must be 2.";
+ description
+ "If uni-resiliency is 'dual-link-aggregation', " +
+ "number-of-links must be 2.";
+ }
+ must "(. != 'other') or " +
+ "((. = 'other') and " +
+ "(../physical-layers/number-of-links > 2))" {
+ error-message "If uni-resiliency is 'other', " +
+ "number-of-links must be 3 or greater.";
+ description
+ "If uni-resiliency is 'other', number-of-links " +
+ "must be 3 or greater.";
+ }
+ default "none";
+ description
+ "UNI Resiliency.";
+ reference "[MEF10.3] Section 9.5 [R64], [R65], [R66], " +
+ "[R67]. [MEF6.2] Section 8.2.2.";
+ }
+ leaf max-svc-frame-size {
+ type mef-types:max-svc-frame-size-type;
+ default "1600";
+ description
+ "This attribute describes the maximum service frame " +
+ "size for the UNI.";
+ reference "[MEF10.3] Section 9.7, [R71], MEF 6.2 " +
+ "Section 8.2.2 and MEF 22.1: [D2]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf svc-mux-enabled {
+ type boolean;
+ default "false";
+ description
+ "Service Multiplexing Enable - Enable if to support " +
+ "multiple EVCs per UNI.";
+ reference "[MEF10.3] Section 9.8. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf bundling-enabled {
+ type boolean;
+ default "false";
+ description
+ "When a UNI has Bundling Enabled, it MUST be able to " +
+ "support more than one CE-VLAN ID mapping to a " +
+ "particular EVC at the UNI. When more than one " +
+ "CE-VLAN-ID is mapped to an EVC at a UNI, the " +
+ "EVC have CE-VLAN ID Preservation enabled";
+ reference "[MEF10.3] Section 9.12, [R25], [R77], " +
+ "[R78], [R80]. [MEF7.3] Section 10.2.2.";
+ }
+ leaf all-to-one-bundling-enabled {
+ type boolean;
+ default "false";
+ description
+ "When all-to-one-bundling-enabled = true, all " +
+ "CE-VLAN IDs MUST map to a single EVC at the " +
+ "UNI. This also means that the UNI cannot " +
+ "have svc-mux-enabled = true. When " +
+ "all-to-one-bundling-enabled = true, " +
+ "all other UNIs in the EVC associating this UNI " +
+ "must have all-to-one-bundling-enabled = true. " +
+ "If this values is true, the value of " +
+ "ce-vlan-id-for-untagged-and-priority is not " +
+ "applicable.";
+ reference "[MEF10.3] Section 9.13, Table 12 " +
+ "(5 valid combinations), [R82], [R83]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf ce-vlan-id-for-untagged-and-priority {
+ type mef-types:vlan-id-type;
+ default "1";
+ description
+ "The ce-vlan-id-for-untagged-and-priority is " +
+ "equivalent to the Layer 2 PVID (Port VLAN ID) " +
+ "with the Q-BRIDGE-MIB option for frame admitance set " +
+ "to admitAll. With AdmitAll set, all Untagged and " +
+ "Priority Tagged Service Frames are treated with " +
+ "the CE-VLAN-ID tag on ingress. It is not applicable " +
+ "if All in One Bundling is enabled.";
+ reference "[MEF10.3] Section 9.9, [R73], [R74], " +
+ "[R75]. [MEF7.3] Section 10.2.2.";
+ }
+ leaf max-evc-count {
+ type uint32 {
+ range "1..max";
+ }
+ default "1";
+ description
+ "The Maximum Number of EVCs that can be supported " +
+ "by this UNI (Default 1).";
+ reference "[MEF10.3] Section 9.11, [R79]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf token-share-enabled {
+ type boolean;
+ default "false";
+ description
+ "Token Share Enabled/Disabled is used to indicate " +
+ "whether a given UNI is capable of sharing tokens " +
+ "across Bandwidth Profile Flows in an envelope.";
+ reference "[MEF6.2] Section 8.2.1, [R2], [D1], [R3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf ingress-bw-profile-per-uni {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/mef-global:" +
+ "bwp-flow/mef-global:bw-profile";
+ }
+ description
+ "Ingress Bandwidth Profile for this UNI.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1: [R3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf egress-bw-profile-per-uni {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:egress-bwp-flows/mef-global:" +
+ "bwp-flow/mef-global:bw-profile";
+ }
+ description
+ "Egress Bandwidth Profile Flow for this UNI.";
+ reference "[MEF10.3] Section 9.15, Section 12.1. " +
+ "[MEF6.2] Section 8.2.1: [R3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf link-oam-enabled {
+ type boolean;
+ default "false";
+ description
+ "Link OAM Enabled/Disabled.";
+ reference "[MEF10.3] Section 9.16, [R86]. " +
+ "[MEF6.2] Section 8.2.2, [D3]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf uni-meg-enabled {
+ type boolean;
+ default "false";
+ description
+ "Enables / Disables the Maintenance Entity Group (MEG).";
+ reference "[MEF10.3] Section 9.17, [R87]. " +
+ "[MEF30.1] Section 7.9. [MEF6.2] Section 8.2.2, " +
+ "[D4]. [MEF7.3] Section 10.2.2.";
+ }
+ leaf elmi-enabled {
+ type boolean;
+ must "(. = 'false') or " +
+ "(. = 'true' and " +
+ "(../elmi-profile))" {
+ error-message "ELMI Profile must be set if " +
+ "ELMI is Enabled.";
+ description
+ "Ethernet Local Management Interface(ELMI) " +
+ "Profile ID must be set if ELMI is Enabled.";
+ }
+ default "false";
+ description
+ "Ethernet Local Management Interface(ELMI) " +
+ "Enabled / Disabled.";
+ reference "[MEF10.3] Section 9.18, [R88]. " +
+ "[MEF16]. [MEF6.2] Section 8.2.2, [D5]. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf elmi-profile {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:elmi/mef-global:elmi-profile/" +
+ "mef-global:id";
+ }
+ description
+ "The ELMI Profile is only applicable when ELMI " +
+ "is enabled. The E-LMI protocol is based on " +
+ "ITU-T Q.933, X.36 and other relevant " +
+ "recommendations as well as Frame Relay " +
+ "Local Management Interface (FR-LMI) " +
+ "Implementation Agreement document defined " +
+ "by the Frame Relay Forum and related " +
+ "ITU-T recommendations.";
+ reference "[MEF10.3] Section 9.18. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf l2cp-address-set {
+ type mef-types:l2cp-address-set-type;
+ default "aware-cta";
+ description
+ "The L2CP Address Set Service Attribute specifies " +
+ "the subset of the Bridge Reserved Addresses " +
+ "that are filtered (i.e. L2CP Frames with " +
+ "this destination address are Peered or " +
+ "Discarded but not Passed) at a L2CP Decision Point.";
+ reference "[MEF10.3] Section 9.19. " +
+ "[MEF45] Section 8.1, [R2] through [R9]. " +
+ "[MEF6.2] Section 8.2.2, [R1]. " +
+ "[MEF45] Section 8.1.";
+ }
+ leaf l2cp-peering-profile {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:l2cp-peering/mef-global:" +
+ "l2cp-profile/mef-global:id";
+ }
+ description
+ "L2CP Peering Profile for this UNI. This profile " +
+ "may contain groups of L2CP Destination " +
+ "MAC Addresses and protocols to be peered at " +
+ "the UNI (as opposed to being passed or discarded).";
+ reference "[MEF10.3] Section 9.19. " +
+ "[MEF45] Section 8.2. " +
+ "[MEF7.3] Section 10.2.2.";
+ }
+ leaf tenant-id {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:tenants-instances/mef-global:tenant-list/mef-global:name";
+ }
+ }
+ }
+ }
+
+ container subnets {
+ list subnet {
+ key "uni-id ip-uni-id subnet";
+ leaf uni-id {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/mef-interfaces:unis/mef-interfaces:uni/mef-interfaces:uni-id";
+ }
+ }
+ leaf ip-uni-id {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/mef-interfaces:unis/mef-interfaces:uni/" +
+ "mef-interfaces:ip-unis/mef-interfaces:ip-uni/mef-interfaces:ip-uni-id";
+ }
+ }
+ leaf subnet {type inet:ip-prefix;}
+ leaf gateway {type inet:ip-address;}
+ }
+ }
+
+ }
+
+ augment "/mef-interfaces:mef-interfaces/mef-interfaces:unis/mef-interfaces:uni" {
+ ext:augment-identifier "port-vlan-mapping";
+ list vlan-to-port {
+ key "vlan";
+ leaf vlan {
+ type mef-types:vlan-id-or-none-type;
+ }
+ leaf vlan-port-id {
+ type string;
+ }
+ }
+ }
+
+}
-module mef-services {\r
- namespace "http://metroethernetforum.org/ns/yang/mef-services";\r
- prefix mef-services;\r
- import ietf-yang-types { prefix yang; }\r
- import ietf-inet-types { prefix inet; }\r
- import mef-types { prefix mef-types; }\r
- import mef-global { prefix mef-global; }\r
- import mef-interfaces { prefix mef-interfaces; }\r
- organization "Metro Ethernet Forum";\r
- contact\r
- "Web URL: http://metroethernetforum.org/ E-mail: mibs@metroethernetforum.org\r
- Postal: Metro Ethernet Forum 6033 W. Century Boulevard, Suite\r
- 1107 Los Angeles, CA 90045 U.S.A. Phone: +1 310-642-2800 Fax:\r
- +1 310-642-2808";\r
- description\r
- "This module implements the Carrier Ethernet Services as defined\r
- in MEF 10.3, MEF 6.2, and MEF 7.2. Reference Overview: A number\r
- of base documents have been used to create the MEF Services YANG\r
- Module. The following are the abbreviations for the baseline documents:\r
- [RFC 6991] refers to IETF RFC 6991 'Common YANG Data Types', 2013-07-15\r
- [RFC 6643] refers to IETF RFC 6643 'Translation of Structure of\r
- Management Information Version 2 (SMIv2) MIB Modules to YANG Modules',\r
- 2011-11-25 [802.1AB] refers to 'Station and Media Access Control\r
- Connectivity Discovery', IEEE 802.1AB-2009, September 2009 [802.1q]\r
- refers to IEEE 802.1Q-2011 'IEEE Standard for Local and metropolitan\r
- area networks --Media Access Control (MAC) Bridges and Virtual\r
- Bridged Local Area Networks, August 2011 [802-2001] refers to\r
- 'IEEE Standard for Local and Metropolitan Area Networks: Overview\r
- and Architecture', IEEE 802-2001, February 2002 [MEF10.3] refers\r
- to MEF 10.3 'Ethernet Services Attributes Phase 3', October 2013\r
- [MEF6.2] refers to MEF 6.2 'EVC Ethernet Services Defintions Phase\r
- 3', August 2014 [MEF40] refers to MEF 40 'UNI and EVC Definition\r
- of Managed Objects', April 2013 [MEF45] refers to MEF 45 'Multi-CEN\r
- L2CP', August 2014 [MEF7.2] refers to MEF 7.2 'Carrier Ethernet\r
- Management Information Model', April 2013 [MEF7.3] refers to MEF\r
- 7.3 'Carrier Ethernet Management Information Model', Working Draft\r
- #1 2015 [RFC 2737] refers to IETF RFC 2737 'Entity MIB (Version\r
- 2)', December 1999 [RFC 2863] refers to IETF RFC 2863 'The Interfaces\r
- Group MIB', June 2000 [RFC 3419] refers to IETF RFC 3419 'Textual\r
- Conventions for Transport Addresses', December 2002 [Y.1731] refers\r
- to ITU-T Y.1731 'OAM functions and mechanisms for Ethernet based\r
- networks', July 2011 [Q.840.1] refers to ITU-T Q.840.1 'Requirements\r
- and analysis for NMS-EMS management interface of Ethernet over\r
- Transport and Metro Ethernet Network(EoT/MEN)' March 2007";\r
- revision 2015-05-26 {\r
- description\r
- "Formal Project Review Draft 1.";\r
- reference "EVC Ethernet Services Definitions YANG Modules " +\r
- "(MEF XX), TBD";\r
- }\r
-\r
- container mef-services {\r
- description\r
- "MEF Services";\r
- list mef-service {\r
- must "(not(/mef-global:mef-global/mef-global:svc-providers)" +\r
- " and " +\r
- "not(./sp-id)) or " +\r
- "(/mef-global:mef-global/mef-global:svc-providers and " +\r
- "./sp-id)" {\r
- error-message "If the Service Providers list has been " +\r
- "populated, a Service Provider ID must be " +\r
- "configured for a Service.";\r
- description\r
- "A Service sees a single Service Provider. This must " +\r
- "statement is effectively a 'mandatory true' when " +\r
- "the Global Service Providers list is being used.";\r
- }\r
- key "svc-id";\r
- unique "evc/evc-id";\r
- unique "ipvc/ipvc-id";\r
- description\r
- "Metro Ethernet Forum's Ethernet Services.";\r
- choice mef-service-choice {\r
- case ipvc-choice {\r
- container ipvc {\r
- container unis {\r
- list uni {\r
- key "uni-id";\r
- leaf uni-id {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni/" +\r
- "mef-interfaces:uni-id";\r
- }\r
- }\r
- leaf ip-uni-id {\r
- type mef-types:identifier45;\r
- }\r
-\r
- container evc-uni-ce-vlans {\r
- description\r
- "EVC Per UNI CE-VLAN IDs.";\r
- list evc-uni-ce-vlan {\r
- key "vid";\r
- description\r
- "A list of the CE-VLAN IDs mapped to this UNI " +\r
- "for this EVC.";\r
- reference "[MEF10.3] Section 8.6.1, [R24] " +\r
- "[R25], Section 9.10.2, Section 9.12, " +\r
- "[R76], [R81].";\r
- leaf vid {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../../../uni-id]" +\r
- "/mef-interfaces:ce-vlans/" +\r
- "mef-interfaces:ce-vlan/" +\r
- "mef-interfaces:vid";\r
- }\r
- description\r
- "VLAN Identifier.";\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- leaf ipvc-id {\r
- type mef-types:evc-id-type;\r
- mandatory true;\r
- }\r
- leaf ipvc-type {\r
- type mef-types:ipvc-type;\r
-\r
- mandatory true;\r
- description\r
- "This IPVC attribute describes the IPVC as either " +\r
- "Cloud-access, Multipoint, or " +\r
- "Rooted-Multipoint.";\r
- }\r
- }\r
- }\r
- case evc-choice {\r
- container evc {\r
-\r
- must "not(sls-uni-inclusions) or " +\r
- "(sls-uni-inclusions and not(sls-uni-exclusions))" {\r
- error-message "The EVC Performance SLS Exclusions and " +\r
- "Inclusions List cannot both be configured for " +\r
- "an EVC.";\r
- description\r
- "The EVC Performance SLS Exclusions and Inclusions " +\r
- "List cannot both be configured for an EVC.";\r
- }\r
- must "(evc-type != 'rooted-multipoint') or " +\r
- "((evc-type = 'rooted-multipoint') and " +\r
- "not(sls-uni-exclusions) )" {\r
- error-message "If EVC Type is Rooted-Multipoint, " +\r
- "sls-uni-inclusions must be used instead of " +\r
- "sls-uni-exclusions.";\r
- description\r
- "If EVC Type is Rooted-Multipoint, " +\r
- "sls-uni-inclusions must be used instead of " +\r
- "sls-uni-exclusions.";\r
- }\r
- description\r
- "Ethernet Virtual Circuit(EVC) Configuration and Status.";\r
- container unis {\r
- description\r
- "EVC Per Universal Network Interface(UNI) " +\r
- "Configuration and Status.";\r
- list uni {\r
- must "not(evc-uni-ce-vlans/evc-uni-ce-vlan[2]) or " +\r
- "../../preserve-ce-vlan-id = 'true'" {\r
- error-message "When more than one CE-VLAN-ID is " +\r
- "mapped to an EVC at a UNI, the EVC must have " +\r
- "CE-VLAN ID Preservation Enabled.";\r
- description\r
- "When more than one CE-VLAN-ID is mapped to " +\r
- "an EVC at a UNI, the EVC must have CE-VLAN ID " +\r
- "Preservation Enabled.";\r
- }\r
- must "/mef-interfaces:mef-interfaces/mef-interfaces:" +\r
- "unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "max-svc-frame-size >= current()/../../" +\r
- "mef-services:max-svc-frame-size]" {\r
- error-message "The value of the EVC Maximum " +\r
- "Service Frame Size must be less than " +\r
- "or equal to all the UNI Maximum Service " +\r
- "Frame Sizes.";\r
- description\r
- "The value of the EVC Maximum Service Frame " +\r
- "Size must be less than or equal to all the " +\r
- "UNI Maximum Service Frame Sizes.";\r
- }\r
- must "(/mef-interfaces:mef-interfaces/mef-interfaces:" +\r
- "unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "bundling-enabled = 'true']) or " +\r
- "(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'true']) or " +\r
- "not(evc-uni-ce-vlans/evc-uni-ce-vlan[2])" {\r
- error-message "If both Bundling and All-to-One " +\r
- "Bundling are disabled for a UNI, only one " +\r
- "CE VLAN ID can be configured for a specific " +\r
- "EVC on that UNI.";\r
- description\r
- "If both Bundling and All-to-One Bundling are " +\r
- "disabled for a UNI, only one CE VLAN ID can be " +\r
- "configured for a specific EVC on that UNI.";\r
- }\r
- must "(/mef-interfaces:mef-interfaces/mef-interfaces:" +\r
- "unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'false']) or " +\r
- "(count(/mef-services:mef-services/" +\r
- "mef-service/evc/unis/uni[uni-id = " +\r
- "current()/uni-id]) = 1)" {\r
- error-message "If All-to-One Bundling is enabled " +\r
- "for any UNI in an EVC, all CE-VLAN IDs " +\r
- "mapped to any EVC for that UNI must map " +\r
- "to the same EVC ID.";\r
- description\r
- "If All-to-One Bundling is enabled for any UNI " +\r
- "in an EVC, all CE-VLAN IDs mapped to any EVC " +\r
- "for that UNI must map to the same EVC ID.";\r
- }\r
- must "((/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "ingress-bw-profile-per-uni]) or " +\r
- "(/mef-services:mef-services/mef-service/" +\r
- "evc/unis/uni" +\r
- "[uni-id = current()/mef-services:uni-id]" +\r
- "/ingress-bwp-flows-per-cos) or " +\r
- "(/mef-services:mef-services/mef-service/" +\r
- "evc/unis/uni" +\r
- "[uni-id = current()/mef-services:uni-id]" +\r
- "/ingress-bw-profile-per-evc)) or " +\r
- "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes)" {\r
- error-message "If no Ingress Bandwidth Profiles " +\r
- "are specied for this UNI (BW Profile " +\r
- "Per UNI, BWP Flows Per CoS, nor BW Profile " +\r
- "Per EVC), then the UNI Ingress Envelopes " +\r
- "list must be empty.";\r
- description\r
- "If no Ingress Bandwidth Profiles are specied " +\r
- "for this UNI (BW Profile Per UNI, BWP Flows " +\r
- "Per CoS, nor BW Profile Per EVC), then the " +\r
- "UNI Ingress Envelopes list must be empty.";\r
- }\r
- must "((/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "egress-bw-profile-per-uni]) or " +\r
- "(/mef-services:mef-services/mef-service/" +\r
- "evc/unis/uni" +\r
- "[uni-id = current()/mef-services:uni-id]" +\r
- "/egress-bwp-flows-per-eec) or " +\r
- "(/mef-services:mef-services/mef-service/" +\r
- "evc/unis/uni" +\r
- "[uni-id = current()/mef-services:uni-id]" +\r
- "/egress-bw-profile-per-evc)) or " +\r
- "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes)" {\r
- error-message "If no Egress Bandwidth Profiles are " +\r
- "specied for this UNI (BW Profile Per UNI, " +\r
- "BWP Flows Per EEC, nor BW Profile Per EVC), " +\r
- "then the UNI Egress Envelopes list must be " +\r
- "empty.";\r
- description\r
- "If no Egress Bandwidth Profiles are specied " +\r
- "for this UNI (BW Profile Per UNI, BWP Flows " +\r
- "Per EEC, nor BW Profile Per EVC), then the UNI " +\r
- "Egress Envelopes list must be empty.";\r
- }\r
- must "not(./ingress-bw-profile-per-evc) or " +\r
- "((./ingress-bw-profile-per-evc) and " +\r
- "not(./ingress-bwp-flows-per-cos))" {\r
- error-message "If there is a per EVC Ingress " +\r
- "Bandwidth Profile on an EVC, then there " +\r
- "cannot be any per Class of Service Ingress " +\r
- "Bandwidth Profiles on that EVC.";\r
- description\r
- "If there is a per EVC Ingress Bandwidth Profile " +\r
- "on an EVC, then there cannot be any per " +\r
- "Class of Service Ingress Bandwidth Profiles " +\r
- "on that EVC.";\r
- }\r
- must "not(./egress-bw-profile-per-evc) or " +\r
- "((./egress-bw-profile-per-evc) and " +\r
- "not(./egress-bwp-flows-per-eec))" {\r
- error-message "If there is a per EVC Egress " +\r
- "Bandwidth Profile on an EVC, then there " +\r
- "cannot be any per Egress Equivalence " +\r
- "Class Identifier Bandwidth Profiles on " +\r
- "that EVC.";\r
- description\r
- "If there is a per EVC Egress Bandwidth " +\r
- "Profile on an EVC, then there cannot be " +\r
- "any per Egress Equivalence Class Identifier " +\r
- "Bandwidth Profiles on that EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-bw-profile-" +\r
- "per-uni) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-bw-profile-per-uni]" +\r
- "[mef-global:cir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-bw-profile-per-uni]" +\r
- "[mef-global:cbs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Ingress Bandwidth Profile Per UNI: " +\r
- "If CIR > 0, CBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Ingress Bandwidth Profile Per UNI: If CIR > 0, " +\r
- "CBS must be greater than or equal to the " +\r
- "EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-bw-profile-per-uni) " +\r
- "or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:egress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-bw-profile-per-uni]" +\r
- "[mef-global:cir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-bw-profile-per-uni]" +\r
- "[mef-global:cbs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Egress Bandwidth Profile Per UNI: " +\r
- "If CIR > 0, CBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Egress Bandwidth Profile Per UNI: If CIR > 0, " +\r
- "CBS must be greater than or equal to the " +\r
- "EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:cir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:cbs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Ingress Bandwidth Profile Envelope: " +\r
- "If CIR > 0, CBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Ingress Bandwidth Profile Envelope: " +\r
- "If CIR > 0, CBS must be greater than " +\r
- "or equal to the EVC Max Service Frame " +\r
- "Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:egress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = " +\r
- "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:cir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:egress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:cbs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Egress Bandwidth Profile " +\r
- "Envelope: If CIR > 0, CBS must be greater " +\r
- "than or equal to the EVC Max Service Frame " +\r
- "Size for the EVC.";\r
- description\r
- "Egress Bandwidth Profile Envelope: If CIR > 0, " +\r
- "CBS must be greater than or equal to the " +\r
- "EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-bw-profile-per-uni) " +\r
- "or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]/mef-interfaces:" +\r
- "ingress-bw-profile-per-uni]" +\r
- "[mef-global:eir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-bw-profile-per-uni]" +\r
- "[mef-global:ebs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Ingress Bandwidth Profile Per UNI: " +\r
- "If EIR > 0, EBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Ingress Bandwidth Profile Per UNI: If EIR > 0, " +\r
- "EBS must be greater than or equal to the " +\r
- "EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-bw-profile-" +\r
- "per-uni) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:egress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]/mef-interfaces:" +\r
- "egress-bw-profile-per-uni]" +\r
- "[mef-global:eir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:ingress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]/mef-interfaces:" +\r
- "egress-bw-profile-per-uni]" +\r
- "[mef-global:ebs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Egress Bandwidth Profile Per UNI: " +\r
- "If EIR > 0, EBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Egress Bandwidth Profile Per UNI: If EIR > 0, " +\r
- "EBS must be greater than or equal to the " +\r
- "EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:" +\r
- "unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes) or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:eir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:ingress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:ebs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Ingress Bandwidth Profile Envelope: " +\r
- "If EIR > 0, EBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Ingress Bandwidth Profile Envelope: " +\r
- "If EIR > 0, EBS must be greater than or equal " +\r
- "to the EVC Max Service Frame Size for the EVC.";\r
- }\r
- must "not(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes) or " +\r
- "(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:egress-bwp-flows/" +\r
- "mef-global:bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:eir = 0]) or " +\r
- "(/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:egress-bwp-flows/mef-global:" +\r
- "bwp-flow" +\r
- "[mef-global:bw-profile = /mef-interfaces:" +\r
- "mef-interfaces/mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/" +\r
- "mef-services:uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "bwp-flows/mef-interfaces:bwp-flow/" +\r
- "mef-interfaces:bw-profile]" +\r
- "[mef-global:ebs >= current()/../../" +\r
- "max-svc-frame-size])" {\r
- error-message "Egress Bandwidth Profile Envelope: " +\r
- "If EIR > 0, EBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- description\r
- "Egress Bandwidth Profile Envelope: " +\r
- "If EIR > 0, EBS must be greater than or " +\r
- "equal to the EVC Max Service Frame Size " +\r
- "for the EVC.";\r
- }\r
- key "uni-id";\r
- description\r
- "EVC Flow Points and EVC-UNI List defines the " +\r
- "roles of each UNI in the Service. One UNI can " +\r
- "be used by 0 or more EVCs.";\r
- reference "[MEF10.3] Section 8.3. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- container evc-uni-ce-vlans {\r
- description\r
- "EVC Per UNI CE-VLAN IDs.";\r
- list evc-uni-ce-vlan {\r
- key "vid";\r
- description\r
- "A list of the CE-VLAN IDs mapped to this UNI " +\r
- "for this EVC.";\r
- reference "[MEF10.3] Section 8.6.1, [R24] " +\r
- "[R25], Section 9.10.2, Section 9.12, " +\r
- "[R76], [R81].";\r
- leaf vid {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../../../uni-id]" +\r
- "/mef-interfaces:ce-vlans/" +\r
- "mef-interfaces:ce-vlan/" +\r
- "mef-interfaces:vid";\r
- }\r
- must "not(current()/../../" +\r
- "evc-uni-ce-vlan[2]) or " +\r
- "(count(../../../../uni/evc-uni-ce-vlans/" +\r
- "evc-uni-ce-vlan" +\r
- "[vid = current()]) = " +\r
- "count(../../../../uni))" {\r
- error-message "If more than one CE-VLAN ID " +\r
- "is configured for a UNI as part of " +\r
- "an EVC, every CE VLAN-ID mapped to " +\r
- "that EVC must be configured for all " +\r
- "UNIs within that EVC.";\r
- description\r
- "If more than one CE-VLAN ID is configured " +\r
- "for a UNI as part of an EVC, every " +\r
- "CE VLAN-ID mapped to that EVC must be " +\r
- "configured for all UNIs within that EVC.";\r
- }\r
- description\r
- "VLAN Identifier.";\r
- }\r
- }\r
- }\r
- container ingress-bwp-flows-per-cos {\r
- presence "Use Ingress Bandwidth Profiles Per CoS";\r
- description\r
- "EVC Per UNI Class of Service Identifiers " +\r
- "corresponding to this EVC's Ingress Bandwidth " +\r
- "Profile Flows.";\r
- leaf coupling-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC Per UNI Envelope Coupling Flag (CF) " +\r
- "attribute.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- list bwp-flow-per-cos {\r
- key "cos-name";\r
- description\r
- "EVC Per UNI: The list of Class of Service " +\r
- "Identifiers corresponding to this UNI's " +\r
- "Ingress Bandwidth Profile Flow.";\r
- leaf cos-name {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:cos-names/" +\r
- "mef-global:cos-name/mef-global:name";\r
- }\r
- description\r
- "EVC Per UNI: Class of Service Identifier " +\r
- "for this Bandwidth Profile Flow.";\r
- reference "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf bw-profile {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../../../uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/" +\r
- "mef-interfaces:env-id";\r
- }\r
- mandatory true;\r
- description\r
- "EVC Per UNI: Ingress Bandwidth Profile " +\r
- "Envelope Per CoS ID. If this parameter " +\r
- "is not configured (ie. 'No') this " +\r
- "setting is configured else at the " +\r
- "UNI Level.";\r
- reference "[MEF10.3] Section 10.6, Table 28. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- }\r
- }\r
- container egress-bwp-flows-per-eec {\r
- presence "Using Egress Bandwidth Profiles Per " +\r
- "Egress Equivalence Class";\r
- description\r
- "EVC Per UNI: The Egress Equivalence Class " +\r
- "Identifiers corresponding to this EVC's Egress " +\r
- "Bandwidth Profile Flows.";\r
- leaf coupling-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC Per UNI: The Envelope Coupling Flag (CF) " +\r
- "attribute.";\r
- reference "[MEF10.3] Section 12.1.";\r
- }\r
- list bwp-flow-per-eec {\r
- key "eec-name";\r
- description\r
- "EVC Per UNI: The list of Egress Equivalence " +\r
- "Class Identifiers corresponding to this " +\r
- "EVC's Egress Bandwidth Profile Flow.";\r
- leaf eec-name {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec-names/" +\r
- "mef-global:eec-name/mef-global:name";\r
- }\r
- description\r
- "EVC Per UNI: Egress Equivalence Class " +\r
- "Identifier for this Bandwidth Profile Flow.";\r
- reference "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf bw-profile {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../../../uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/" +\r
- "mef-interfaces:env-id";\r
- }\r
- mandatory true;\r
- description\r
- "EVC Per UNI: Egress Bandwidth Profile " +\r
- "Envelope Per Equivance Class. If this " +\r
- "parameter is not configured (ie. 'No') " +\r
- "this setting is configured else at the " +\r
- "UNI Level.";\r
- reference "[MEF10.3] Section 10.6, Table 28. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- }\r
- }\r
- container status {\r
- description\r
- "EVC Per UNI: This status group is related to " +\r
- "the MEF 7.3 Service Endpoint";\r
- leaf oper-state-enabled {\r
- type boolean;\r
- default "false";\r
- config false;\r
- description\r
- "EVC Per UNI: Operational Status of the " +\r
- "Virtual Connection as Enabled/Disabled.";\r
- reference "[MEF15]. [MEF7.3] Section 11.2.1.";\r
- }\r
- leaf available-status {\r
- type mef-types:svc-endpoint-availability-type;\r
- default "not-installed";\r
- config false;\r
- description\r
- "EVC Per UNI: Availability Status of the " +\r
- "Virtual Connection.";\r
- reference "[MEF15]. [MEF7.3] Section 11.2.1.";\r
- }\r
- }\r
- leaf uni-id {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni/" +\r
- "mef-interfaces:uni-id";\r
- }\r
- description\r
- "EVC Per UNI: The UNI ID paired with the EVC ID " +\r
- "in the containing list.";\r
- reference "[MEF10.3] Section 8.3, Section 10.1. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf role {\r
- type mef-types:evc-uni-role-type;\r
- mandatory true;\r
- description\r
- "EVC Per UNI: The UNI Role MUST have the value " +\r
- "of either 'root' or 'leaf'.";\r
- reference "[MEF10.3] [R4], [R5], [R10], [R11], " +\r
- "[R12]. [MEF7.3] Section 12.2.2.";\r
- }\r
- leaf admin-state-enabled {\r
- type boolean;\r
- default "true";\r
- description\r
- "EVC Per UNI: Locked/Unlocked is inconsistent " +\r
- "with Oper Status and will be confusing.";\r
- reference "[MEF15]. [MEF7.3] Section 11.2.1.";\r
- }\r
- leaf color-id {\r
- type mef-types:cos-color-identifier-type;\r
- description\r
- "EVC Per UNI: The Color Identifier for " +\r
- "Service Frames.";\r
- reference "[MEF10.3] Section 10.3. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf data-svc-frm-cos {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:cos/mef-global:cos-profile/" +\r
- "mef-global:id";\r
- }\r
- must "not(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:cos/" +\r
- "mef-global:cos-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:cos-pcp) or " +\r
- "((/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:cos/" +\r
- "mef-global:cos-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:cos-pcp) and " +\r
- "((../color-id = 'pcp') or " +\r
- "(../color-id = 'dei')) )" {\r
- error-message "When the Class of Service " +\r
- "Identifier is based on PCP for a " +\r
- "given EVC at a given UNI, the Color " +\r
- "Identifier must be based on either " +\r
- "DEI or PCP.";\r
- description\r
- "When the Class of Service Identifier is " +\r
- "based on PCP for a given EVC at a given UNI, " +\r
- "the Color Identifier must be based on either " +\r
- "DEI or PCP.";\r
- }\r
- must "not(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:cos/mef-global:" +\r
- "cos-profile" +\r
- "[mef-global:id = current()]/mef-global:" +\r
- "cos-dscp) or " +\r
- "((/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:cos/mef-global:" +\r
- "cos-profile" +\r
- "[mef-global:id = current()]/mef-global:" +\r
- "cos-dscp) and " +\r
- "(../color-id = 'dscp'))" {\r
- error-message "When the Class of Service " +\r
- "Identifier is based on DSCP for a " +\r
- "given EVC at a given UNI, the Color " +\r
- "Identifier must be based DSCP.";\r
- description\r
- "When the Class of Service Identifier is based " +\r
- "on DSCP for a given EVC at a given UNI, the " +\r
- "Color Identifier must be based DSCP.";\r
- }\r
- description\r
- "EVC Per UNI: Ingress Data Service Frame " +\r
- "CoS Profile.";\r
- reference "[MEF10.3] Section 8.8, Section 10.2. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf l2cp-svc-frm-cos {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:l2cp-cos/mef-global:" +\r
- "l2cp-profile/mef-global:id";\r
- }\r
- description\r
- "EVC Per UNI: Ingress Layer 2 Control Protocol " +\r
- "Processing.";\r
- reference "[MEF10.3] Section 8.8, Section 10.2. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf soam-svc-frm-cos {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:cos/mef-global:cos-profile/" +\r
- "mef-global:id";\r
- }\r
- must "(not(.) and not(../data-svc-frm-cos)) or " +\r
- "(. = ../data-svc-frm-cos)" {\r
- error-message "For a given EVC at a given UNI, " +\r
- "the basis for the Class of Service " +\r
- "Identifier for ingress SOAM Service " +\r
- "Frames must be the same as that for " +\r
- "ingress Data Service Frames.";\r
- description\r
- "For a given EVC at a given UNI, the basis " +\r
- "for the Class of Service Identifier for " +\r
- "ingress SOAM Service Frames must be the " +\r
- "same as that for ingress Data Service Frames.";\r
- }\r
- description\r
- "EVC Per UNI: Ingress SOAM Service Frames.";\r
- reference "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf data-svc-frm-eec {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:eec/mef-global:eec-profile/" +\r
- "mef-global:id";\r
- }\r
- must "not(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec/mef-global:" +\r
- "eec-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:eec-pcp) or " +\r
- "((/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec/mef-global:" +\r
- "eec-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:eec-pcp) and " +\r
- "((../color-id = 'pcp') or " +\r
- "(../color-id = 'dei')) )" {\r
- error-message "When the Egress Equivalence " +\r
- "Class Identifier is based on PCP " +\r
- "for a given EVC at a given UNI, " +\r
- "the Color Identifier must be based " +\r
- "on either DEI or PCP.";\r
- description\r
- "When the Egress Equivalence Class Identifier " +\r
- "is based on PCP for a given EVC at a " +\r
- "given UNI, the Color Identifier must " +\r
- "be based on either DEI or PCP.";\r
- }\r
- must "not(/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec/mef-global:" +\r
- "eec-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:eec-dscp) or " +\r
- "((/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec/mef-global:" +\r
- "eec-profile" +\r
- "[mef-global:id = current()]" +\r
- "/mef-global:eec-dscp) and " +\r
- "(../color-id = 'dscp'))" {\r
- error-message "When the Egress Equivalence " +\r
- "Class Identifier is based on DSCP for " +\r
- "a given EVC at a given UNI, the Color " +\r
- "Identifier must be based DSCP.";\r
- description\r
- "When the Egress Equivalence Class Identifier " +\r
- "is based on DSCP for a given EVC at a given " +\r
- "UNI, the Color Identifier must be based DSCP.";\r
- }\r
- description\r
- "EVC Per UNI: Egress Data Service Frame Processing.";\r
- reference "[MEF10.3] Section 10.4. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf l2cp-svc-frm-eec {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:l2cp-eec/mef-global:" +\r
- "l2cp-profile/mef-global:id";\r
- }\r
- description\r
- "EVC Per UNI: Egress Layer 2 Control Protocol " +\r
- "Processing.";\r
- reference "[MEF10.3] Section 10.4. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf soam-svc-frm-eec {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "profiles/mef-global:eec/mef-global:" +\r
- "eec-profile/mef-global:id";\r
- }\r
- must "(not(.) and not(../data-svc-frm-eec)) or " +\r
- "(. = ../data-svc-frm-eec)" {\r
- error-message "For a given EVC at a given UNI, " +\r
- "the basis for the Egress Equivalence " +\r
- "Class Identifier for egress SOAM " +\r
- "Service Frames must be the same as " +\r
- "that for egress Data Service Frames.";\r
- description\r
- "For a given EVC at a given UNI, the basis " +\r
- "for the Egress Equivalence Class Identifier " +\r
- "for egress SOAM Service Frames must be " +\r
- "the same as that for egress Data " +\r
- "Service Frames.";\r
- }\r
- description\r
- "EVC Per UNI: Egress SOAM Service Frames.";\r
- reference "[MEF10.3] Section 10.4. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf ingress-bw-profile-per-evc {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../uni-id]" +\r
- "/mef-interfaces:ingress-envelopes/" +\r
- "mef-interfaces:envelope/" +\r
- "mef-interfaces:env-id";\r
- }\r
- description\r
- "EVC Per UNI: Ingress Bandwidth Profile " +\r
- "Envelope Per EVC. If this parameter is " +\r
- "not configured (ie. 'No') this setting " +\r
- "is configured else at the UNI Level.";\r
- reference "[MEF10.3] Section 10.5. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf egress-bw-profile-per-evc {\r
- type leafref {\r
- path "/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/" +\r
- "mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = " +\r
- "current()/../uni-id]" +\r
- "/mef-interfaces:egress-envelopes/" +\r
- "mef-interfaces:envelope/mef-interfaces:" +\r
- "env-id";\r
- }\r
- description\r
- "EVC Per UNI: Egress Bandwidth Profile Envelope " +\r
- "Per EVC. If this parameter is not configured " +\r
- "(ie. 'No') this setting is configured else at " +\r
- "the UNI Level.";\r
- reference "[MEF10.3] Section 10.7. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf src-mac-addr-limit-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC Per UNI: Source MAC Address Limit " +\r
- "Enable / Disable. If Enabled, the values " +\r
- "for the Source MAC Address Limit and Source " +\r
- "MAC Address Interval must be set.";\r
- reference "[MEF10.3] Section 10.9. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf src-mac-addr-limit {\r
- type uint32 {\r
- range "1..max";\r
- }\r
- description\r
- "EVC Per UNI: Source MAC Address Limit. " +\r
- "This value is used when the Source MAC Address " +\r
- "Limit Enabled is true.";\r
- reference "[MEF10.3] Section 10.9.";\r
- }\r
- leaf src-mac-addr-limit-interval {\r
- type yang:timeticks;\r
- default "0";\r
- description\r
- "EVC Per UNI: Source MAC Address Limit " +\r
- "Interval. This value is used when the " +\r
- "Source MAC Address Limit Enabled is true.";\r
- reference "[MEF10.3] Section 10.9.";\r
- }\r
- leaf test-meg-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC Per UNI: Test MEG Enabled / Disabled.";\r
- reference "[MEF10.3] Section 10.10. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf test-meg {\r
- type mef-types:identifier45;\r
- description\r
- "EVC Per UNI: Test MEG Identifier.";\r
- reference "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf subscriber-meg-mip-enabled {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC Per UNI: Subscriber MEG MIP " +\r
- "Enabled / Disabled.";\r
- reference "[MEF10.3] Section 10.11. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf subscriber-meg-mip {\r
- type mef-types:identifier45;\r
- description\r
- "EVC Per UNI: Subscriber MEG MIP Identifier.";\r
- reference "[MEF7.3] Section 12.1.2.";\r
- }\r
- }\r
- }\r
- container status {\r
- description\r
- "This status group is related to the MEF 7.3 Virtual " +\r
- "Connection";\r
- leaf oper-state-enabled {\r
- type boolean;\r
- default "false";\r
- config false;\r
- description\r
- "EVC Operational Status of the Virtual Connection " +\r
- "as Enabled/Disabled.";\r
- reference "[MEF7.3] Section 11.1.1.";\r
- }\r
- leaf available-status {\r
- type mef-types:virt-cx-availability-type;\r
- default "not-installed";\r
- config false;\r
- description\r
- "EVC Availability Status of the Virtual Connection.";\r
- reference "[MEF7.3] Section 11.1.1.";\r
- }\r
- }\r
- container sls-inclusions-by-cos {\r
- description\r
- "SLS Inclusions by CoS: For this EVC, the following " +\r
- "CoS Names/Labels are applicable.";\r
- list sls-inclusion-by-cos {\r
- key "cos-name";\r
- description\r
- "CoS Name.";\r
- leaf cos-name {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:profiles/" +\r
- "mef-global:cos-names/mef-global:" +\r
- "cos-name/mef-global:name";\r
- }\r
- description\r
- "EVC: This attribute identifies the name of " +\r
- "a class of service (CoS) instance to be used " +\r
- "for EVC Performance.";\r
- }\r
- }\r
- }\r
- container sls-uni-inclusions {\r
- presence "EVC: Defines the EVC Flow Points (UNI) Pairs " +\r
- "that must conform to the EVC's SLS Performance " +\r
- "Metrics.";\r
- description\r
- "SLS UNI Inclusions List. The following pairs of UNI " +\r
- "Interconnections are to required to meet the " +\r
- "SLS Performance Objectives. Configing both SLS " +\r
- "UNI Inclusions and SLS UNI Exclusions is not " +\r
- "permitted.";\r
- list sls-uni-inclusion-set {\r
- must "uni-id1 != uni-id2" {\r
- error-message "The two UNI IDs for a given " +\r
- "inclusion cannot be the same.";\r
- description\r
- "The two UNI IDs for a given inclusion " +\r
- "cannot be the same.";\r
- }\r
- must "(../../evc-type != 'rooted-multipoint') or " +\r
- "((../../evc-type = 'rooted-multipoint') " +\r
- "and " +\r
- "not((../../unis/uni[uni-id = " +\r
- "current()/uni-id1]/role = 'leaf') and " +\r
- "(../../unis/uni[uni-id = current()/uni-id2]" +\r
- "/role = 'leaf')))" {\r
- error-message "If EVC Type is Rooted-Multipoint, " +\r
- "sls-uni-inclusion UNI Pairs cannot both " +\r
- "be role 'leaf'.";\r
- description\r
- "If EVC Type is Rooted-Multipoint, " +\r
- "sls-uni-inclusion UNI Pairs cannot " +\r
- "both be role 'leaf'.";\r
- }\r
- key "pm-type pm-id uni-id1 uni-id2";\r
- description\r
- "EVC: Defines the EVC Flow Points (UNI) Pairs that " +\r
- "must conform to the EVC's SLS Performance " +\r
- "Metrics. Use of this list indicates that a " +\r
- "complete set of UNI Pairs has been specified " +\r
- "for the Performance Metrics defined in the " +\r
- "selected SLS.";\r
- leaf pm-type {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:slss/" +\r
- "mef-global:sls" +\r
- "[mef-global:sls-id = current()/../../../" +\r
- "evc-performance-sls]" +\r
- "/mef-global:perf-objs/mef-global:" +\r
- "perf-obj/mef-global:pm-type";\r
- }\r
- description\r
- "EVC: Performance Metric.";\r
- reference "[MEF10.3] Section 8.8.";\r
- }\r
- leaf pm-id {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:slss/" +\r
- "mef-global:sls" +\r
- "[mef-global:sls-id = current()/../../../" +\r
- "evc-performance-sls]" +\r
- "/mef-global:perf-objs/mef-global:perf-obj" +\r
- "[mef-global:pm-type = current()/../" +\r
- "pm-type]" +\r
- "/mef-global:pm-id";\r
- }\r
- description\r
- "EVC: This is a friendly name for specific " +\r
- "performance profile.";\r
- }\r
- leaf uni-id1 {\r
- type leafref {\r
- path "../../../unis/uni/uni-id";\r
- }\r
- description\r
- "EVC: The UNI ID paired with the EVC ID in the " +\r
- "containing list.";\r
- reference "[MEF10.3] Section 8.3, Section 10.1. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf uni-id2 {\r
- type leafref {\r
- path "../../../unis/uni/uni-id";\r
- }\r
- description\r
- "EVC: The UNI ID paired with the EVC ID in the " +\r
- "containing list.";\r
- reference "[MEF10.3] Section 8.3, Section 10.1. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- }\r
- }\r
- container sls-uni-exclusions {\r
- presence "Not all EVC Flow Points (UNI) must conform " +\r
- "to the EVC SLS Performance Metrics.";\r
- description\r
- "EVC: Not all EVC Flow Points (UNI) must conform to " +\r
- "the EVC SLS Performance Metrics. Use of this " +\r
- "list indicates that all UNI Pairs EXCEPT for " +\r
- "the ones indicated (per Performance Metric) must " +\r
- "conform to the SLS.";\r
- list sls-uni-exclusion-set {\r
- must "uni-id1 != uni-id2" {\r
- error-message "The two UNI IDs for a given " +\r
- "exclusion cannot be the same.";\r
- description\r
- "The two UNI IDs for a given exclusion cannot " +\r
- "be the same as these pairs are invalid as " +\r
- "defined in MEF 10.3.";\r
- }\r
- key "pm-type pm-id uni-id1 uni-id2";\r
- description\r
- "SLS UNI Exclusions List. The following pairs " +\r
- "of UNI Interconnections are not required " +\r
- "meet the SLS Performance Objectives. " +\r
- "Configing both SLS UNI Inclusions and SLS " +\r
- "UNI Exclusions is not permitted.";\r
- leaf pm-type {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:" +\r
- "slss/mef-global:sls" +\r
- "[mef-global:sls-id = current()/../../../" +\r
- "evc-performance-sls]" +\r
- "/mef-global:perf-objs/mef-global:" +\r
- "perf-obj/mef-global:pm-type";\r
- }\r
- description\r
- "EVC: Performance Metric.";\r
- reference "[MEF10.3] Section 8.8.";\r
- }\r
- leaf pm-id {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:slss/" +\r
- "mef-global:sls" +\r
- "[mef-global:sls-id = current()/../../../" +\r
- "evc-performance-sls]" +\r
- "/mef-global:perf-objs/mef-global:perf-obj" +\r
- "[mef-global:pm-type = current()/../" +\r
- "pm-type]" +\r
- "/mef-global:pm-id";\r
- }\r
- description\r
- "EVC: This is a friendly name for specific " +\r
- "performance profile.";\r
- }\r
- leaf uni-id1 {\r
- type leafref {\r
- path "../../../unis/uni/uni-id";\r
- }\r
- description\r
- "EVC: The UNI ID paired with the EVC ID in the " +\r
- "containing list.";\r
- reference "[MEF10.3] Section 8.3, Section 10.1. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- leaf uni-id2 {\r
- type leafref {\r
- path "../../../unis/uni/uni-id";\r
- }\r
- description\r
- "EVC: The UNI ID paired with the EVC ID in the " +\r
- "containing list.";\r
- reference "[MEF10.3] Section 8.3, Section 10.1. " +\r
- "[MEF7.3] Section 12.1.2.";\r
- }\r
- }\r
- }\r
- leaf evc-id {\r
- type mef-types:evc-id-type;\r
- mandatory true;\r
- description\r
- "The EVC ID must be unique across all EVCs in the CEN." +\r
- " The EVC ID must be non-NULL.";\r
- reference "[MEF10.3] Section 8.2 [R7]. " +\r
- "[MEF7.3] Section 11.1.1, Section 12.2.2.";\r
- }\r
- leaf evc-status {\r
- type mef-types:evc-status-type;\r
- config false;\r
- description\r
- "EVC Operational Status.";\r
- reference "[MEF16] Section 5.3.";\r
- }\r
- leaf evc-type {\r
- type mef-types:evc-type;\r
- must "(. != 'point-to-point') or " +\r
- "((. = 'point-to-point') and " +\r
- "(count(../unis/uni[role = 'leaf']) = 0))" {\r
- error-message "If EVC Type is Point-to-Point, all " +\r
- "UNI Roles must be root.";\r
- description\r
- "If EVC Type is Point-to-Point, all UNI Roles must " +\r
- "be root.";\r
- }\r
- must "(. != 'multipoint-to-multipoint') or " +\r
- "((. = 'multipoint-to-multipoint') and " +\r
- "(count(../unis/uni[role = 'leaf']) = 0))" {\r
- error-message "If EVC Type is " +\r
- "Multipoint-to-Multipoint, all UNI Roles " +\r
- "must be root.";\r
- description\r
- "If EVC Type is Multipoint-to-Multipoint, all UNI " +\r
- "Roles must be root.";\r
- }\r
- must "(. != 'rooted-multipoint') or " +\r
- "((. = 'rooted-multipoint') and " +\r
- "(count(../unis/uni[role = 'root']) > 0) )" {\r
- error-message "If EVC Type is Rooted-Multipoint, one " +\r
- "or more UNI Roles must be root.";\r
- description\r
- "If EVC Type is Rooted-Multipoint, one or more " +\r
- "UNI Roles must be root.";\r
- }\r
- must "(. != 'point-to-point') or " +\r
- "((. = 'point-to-point') and " +\r
- "(count(../unis/uni) = 2))" {\r
- error-message "If EVC Type is Point-to-Point, there " +\r
- "must be exactly 2 UNI configured for the EVC.";\r
- description\r
- "If EVC Type is Point-to-Point, there must be " +\r
- "exactly 2 UNI configured for the EVC.";\r
- }\r
- must "(. != 'multipoint-to-multipoint') or " +\r
- "((. = 'multipoint-to-multipoint') and " +\r
- "(count(../unis/uni) > 1) and " +\r
- "(count(../unis/uni) <= ../max-uni-count))" {\r
- error-message "If EVC Type is " +\r
- "Multipoint-to-Multipoint, " +\r
- "there must be 2 or more UNI configured " +\r
- "for the EVC.";\r
- description\r
- "If EVC Type is Multipoint-to-Multipoint, " +\r
- "there must be 2 or more UNI configured for " +\r
- "the EVC.";\r
- }\r
- must "(. != 'rooted-multipoint') or " +\r
- "((. = 'rooted-multipoint') and " +\r
- "(count(../unis/uni) > 1) and " +\r
- "(count(../unis/uni) <= ../max-uni-count))" {\r
- error-message "If EVC Type is Rooted-Multipoint, " +\r
- "there must be 2 or more UNI configured for the EVC.";\r
- description\r
- "If EVC Type is Rooted-Multipoint, there must " +\r
- "be 2 or more UNI configured for the EVC.";\r
- }\r
- must "(. != 'point-to-point') or " +\r
- "((. = 'point-to-point') and " +\r
- "(../max-uni-count = 2))" {\r
- error-message "If EVC Type is Point-to-Point, " +\r
- "the value of max-uni-count must be 2.";\r
- description\r
- "If EVC Type is Point-to-Point, the value of " +\r
- "max-uni-count must be 2.";\r
- }\r
- must "(. != 'multipoint-to-multipoint') or " +\r
- "((. = 'multipoint-to-multipoint') and " +\r
- "(../max-uni-count > 2))" {\r
- error-message "If EVC Type is " +\r
- "Multipoint-to-Multipoint, the value of " +\r
- "max-uni-count must be at least 3.";\r
- description\r
- "If EVC Type is Multipoint-to-Multipoint, the " +\r
- "value of max-uni-count must be at least 3.";\r
- }\r
- must "(. != 'rooted-multipoint') or " +\r
- "((. = 'rooted-multipoint') and " +\r
- "(../max-uni-count > 2))" {\r
- error-message "If EVC Type is Rooted-Multipoint, " +\r
- "the value of max-uni-count must be at " +\r
- "least 3.";\r
- description\r
- "If EVC Type is Rooted-Multipoint, the value " +\r
- "of max-uni-count must be at least 3.";\r
- }\r
- // mandatory true;\r
- description\r
- "This EVC attribute describes the EVC as either " +\r
- "Multipoint-To-Multipoint, Point-To-Point, or " +\r
- "Rooted-Multipoint.";\r
- reference "[MEF10.3] Section 8.1, [R4], [R5], " +\r
- "[R10], [R11], [R12], [R13] and [R14]. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- }\r
- leaf admin-state-enabled {\r
- type boolean;\r
- default "true";\r
- description\r
- "EVC: Locked/Unlocked is inconsistent with " +\r
- "Oper Status and will be confusing.";\r
- reference "[MEF15]. [MEF7.3] Section 11.1.1.";\r
- }\r
- leaf elastic-enabled {\r
- type boolean;\r
- default "true";\r
- description\r
- "EVC: Elastic Enabled/Disabled.";\r
- reference "[MEF7.3] Section 11.1.1.";\r
- }\r
- leaf elastic-service {\r
- type mef-types:identifier45;\r
- description\r
- "EVC: Related to CE4Cloud Information Model.";\r
- reference "[MEF7.3] Section 11.1.1.";\r
- }\r
- leaf max-uni-count {\r
- type uint32 {\r
- range "2..max";\r
- }\r
- must "(. > 2) or ((. = 2) and " +\r
- "(../evc-type = 'point-to-point'))" {\r
- error-message "If EVC Type is Point-to-Point, the " +\r
- "max-uni-count value must be 2.";\r
- description\r
- "If EVC Type is Point-to-Point, the max-uni-count " +\r
- "value must be 2.";\r
- }\r
- must "(. = 2) or ((. > 2) and " +\r
- "((../evc-type = 'multipoint-to-multipoint') or " +\r
- "(../evc-type = 'rooted-multipoint')))" {\r
- error-message "If EVC Type is " +\r
- "Multipoint-to-Multipoint or " +\r
- "Rooted-Multipoint, the max-uni-count value " +\r
- "must be at least 3.";\r
- description\r
- "If EVC Type is Multipoint-to-Multipoint or " +\r
- "Rooted-Multipoint, the max-uni-count value " +\r
- "must be at least 3.";\r
- }\r
- default "2";\r
- description\r
- "EVC:The Maximum Number of UNIs this EVC can be " +\r
- "configured for (Default 2).If EVC Type is " +\r
- "Multipoint-to-Multipoint or Rooted-Multipoint, " +\r
- "the max-uni-count value must be at least 3. " +\r
- "This value must be 2 for point-to-point mode.";\r
- reference "[MEF10.3] [R14]. [MEF7.3] Section 12.2.2.";\r
- }\r
- leaf preserved-vlan {\r
- type uint32;\r
- }\r
- leaf preserve-ce-vlan-id {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC:An EVC with more than one CE-VLAN ID mapping " +\r
- "to it must have the same list of CE-VLAN IDs " +\r
- "mapping to the EVC at each UNI in the EVC.";\r
- reference "[MEF10.3] Section 8.6.1, [R24] [R25], " +\r
- "Section 9.10.2, Section 9.12, [R81], Figure 20. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- }\r
- leaf cos-preserve-ce-vlan-id {\r
- type boolean;\r
- default "false";\r
- description\r
- "EVC: Preserve CE-VLAN ID for CoS.";\r
- reference "[MEF10.3] Section 8.6.2, [R26]. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- }\r
- leaf evc-performance-sls {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:slss/" +\r
- "mef-global:sls/mef-global:sls-id";\r
- }\r
- description\r
- "EVC: EVC-specific performance objectives and " +\r
- "parameters. Note that an SLS can also specify " +\r
- "performance objectives spanning more than one EVC. " +\r
- "By default, all the UNI associated with the EVC " +\r
- "have this SLS applied for them.";\r
- reference "[MEF10.3] Section 8.8, Section 10. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- }\r
- leaf unicast-svc-frm-delivery {\r
- type mef-types:data-svc-frame-delivery-type;\r
- default "unconditional";\r
- description\r
- "EVC: Unicast Data Service Frame Delivery Mode " +\r
- "(unconditional[default], conditional, or discard).";\r
- reference "[MEF10.3] Section 8.5.2,[R16], [R17], " +\r
- "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";\r
- }\r
- leaf multicast-svc-frm-delivery {\r
- type mef-types:data-svc-frame-delivery-type;\r
- default "unconditional";\r
- description\r
- "EVC: Multicast Data Service Frame Delivery Mode " +\r
- "(unconditional[default], conditional, or discard).";\r
- reference "[MEF10.3] Section 8.5.2, [R16], [R18], " +\r
- "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";\r
- }\r
- leaf broadcast-svc-frm-delivery {\r
- type mef-types:data-svc-frame-delivery-type;\r
- default "unconditional";\r
- description\r
- "EVC: Broadcast Data Service Frame Delivery Mode " +\r
- "(unconditional[default], conditional, or discard).";\r
- reference "[MEF10.3] Section 8.5.2, [R16], [R19], " +\r
- "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";\r
- }\r
- leaf evc-meg-id {\r
- type mef-types:identifier45;\r
- description\r
- "EVC: Identifies the Maintenance Entity Group (MEG) " +\r
- "for this EVC.";\r
- reference "[MEF7.3] Section 12.2.2. MEF 35.1.";\r
- }\r
- leaf max-svc-frame-size {\r
- type mef-types:max-svc-frame-size-type;\r
- default "1600";\r
- description\r
- "EVC: This attribute describes the maximum service " +\r
- "frame size for the EVC.";\r
- reference "[MEF10.3] Section 8.9, Section 9.7, [R71], " +\r
- "[MEF6.2] Section 8.2.2 and MEF 22.1: [D2]. " +\r
- "[MEF7.3] Section 12.2.2.";\r
- }\r
- }\r
- }\r
- }\r
- leaf svc-id {\r
- type mef-types:retail-svc-id-type;\r
- description\r
- "The MEF Service ID is a simple key used to " +\r
- "distinguish MEF Service Configuration Groups.";\r
- reference "[MEF10.3] Section 7.";\r
- }\r
- leaf sp-id {\r
- when "/mef-global:mef-global/mef-global:svc-providers" {\r
- description\r
- "Only configure when the Global Service Providers " +\r
- "list has been populated.";\r
- }\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:svc-providers/" +\r
- "mef-global:svc-provider/mef-global:sp-id";\r
- }\r
- description\r
- "The MEF Service Provider ID must be globally unique " +\r
- "as all CENs and Subscribers must be supported by a " +\r
- "specific Service Provider(SP). A SP can support " +\r
- "multiple CENs.";\r
- reference "[MEF10.3] Section 7.";\r
- }\r
- leaf svc-type {\r
- type mef-types:mef-service-type;\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "svc-mux-enabled = 'true']) = 0))" {\r
- error-message "For EPL, Service Multiplexing must be " +\r
- "disabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EPL, Service Multiplexing must be disabled for " +\r
- "all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "bundling-enabled = 'true']) = 0))" {\r
- error-message "For EPL, Bundling must be disabled for " +\r
- "all UNIs in the EVC UNI List.";\r
- description\r
- "For EPL, Bundling must be disabled for all UNIs in " +\r
- "the EVC UNI List.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/" +\r
- "mef-services:uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'false']) = 0))" {\r
- error-message "For EPL, All-to-One Bundling must be " +\r
- "enabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EPL, All-to-One Bundling must be enabled for " +\r
- "all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "max-evc-count != 1]) = 0))" {\r
- error-message "For EPL, Max EVC Count must be 1 for " +\r
- "all UNIs in the EVC UNI List.";\r
- description\r
- "For EPL, Max EVC Count must be 1 for all UNIs " +\r
- "in the EVC UNI List.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(../evc/unis/uni/egress-bwp-flows-per-eec/" +\r
- "bwp-flow-per-eec) = 0))" {\r
- error-message "For EPL, Egress Bandwidth Profile per " +\r
- "Egress Equivalence Class cannot be set for " +\r
- "all UNIs in the EVC per UNI List.";\r
- description\r
- "For EPL, Egress Bandwidth Profile per Egress " +\r
- "Equivalence Class cannot be set for all UNIs in the " +\r
- "EVC per UNI List.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(count(../evc/unis/uni" +\r
- "[src-mac-addr-limit-enabled = 'true']) = 0) )" {\r
- error-message "For EPL, Source MAC Address Limit must " +\r
- "be disabled.";\r
- description\r
- "For EPL, Source MAC Address Limit must be disabled.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/evc-type = 'point-to-point'))" {\r
- error-message "For EPL, EVC Type must be Point-to-Point.";\r
- description\r
- "For EPL, EVC Type must be Point-to-Point.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/unicast-svc-frm-delivery = " +\r
- "'unconditional'))" {\r
- error-message "For EPL, unicast-svc-frm-delivery " +\r
- "must be unconditional.";\r
- description\r
- "For EPL, unicast-svc-frm-delivery must be " +\r
- "unconditional.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/multicast-svc-frm-delivery = " +\r
- "'unconditional'))" {\r
- error-message "For EPL, multicast-svc-frm-delivery " +\r
- "must be unconditional.";\r
- description\r
- "For EPL, multicast-svc-frm-delivery must be " +\r
- "unconditional.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/broadcast-svc-frm-delivery = " +\r
- "'unconditional'))" {\r
- error-message "For EPL, broadcast-svc-frm-delivery " +\r
- "must be unconditional.";\r
- description\r
- "For EPL, broadcast-svc-frm-delivery must be " +\r
- "unconditional.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EPL, CE-VLAN ID Preservation " +\r
- "must be enabled.";\r
- description\r
- "For EPL, CE-VLAN ID Preservation must be enabled.";\r
- }\r
- must "(. != 'epl') or ((. = 'epl') and " +\r
- "(../evc/cos-preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EPL, CE-VLAN ID CoS Preservation " +\r
- "must be enabled.";\r
- description\r
- "For EPL, CE-VLAN ID CoS Preservation must be enabled.";\r
- }\r
- must "(. != 'evpl') or ((. = 'evpl') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'true']) = 0))" {\r
- error-message "For EVPL, All-to-One Bundling must be " +\r
- "disabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EVPL, All-to-One Bundling must be disabled for " +\r
- "all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'evpl') or ((. = 'evpl') and " +\r
- "((../evc/unicast-svc-frm-delivery != " +\r
- "'unconditional') or " +\r
- "(../evc/multicast-svc-frm-delivery != " +\r
- "'unconditional') or " +\r
- "(../evc/broadcast-svc-frm-delivery != " +\r
- "'unconditional') or " +\r
- "count(../evc/unis/uni" +\r
- "[src-mac-addr-limit-enabled = 'true']) = 0))" {\r
- error-message "For EVPL, Source MAC Address Limit must " +\r
- "be disabled for all UNIs in the EVC per " +\r
- "UNI List if all 3 -svc-frm-delivery values " +\r
- "are unconditional.";\r
- description\r
- "For EVPL, Source MAC Address Limit must be disabled " +\r
- "for all UNIs in the EVC per UNI List if all " +\r
- "3 -svc-frm-delivery values are unconditional.";\r
- }\r
- must "(. != 'evpl') or ((. = 'evpl') and " +\r
- "(../evc/evc-type = 'point-to-point'))" {\r
- error-message "For EVPL, EVC Type must be Point-to-Point.";\r
- description\r
- "For EVPL, EVC Type must be Point-to-Point.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "svc-mux-enabled = 'true']) = 0))" {\r
- error-message "For EP-LAN, Service Multiplexing must " +\r
- "be disabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-LAN, Service Multiplexing must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "bundling-enabled = 'true']) = 0))" {\r
- error-message "For EP-LAN, Bundling must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-LAN, Bundling must be disabled for all UNIs " +\r
- "in the EVC UNI List.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/" +\r
- "mef-services:uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'false']) = 0))" {\r
- error-message "For EP-LAN, All-to-One Bundling " +\r
- "must be enabled for all UNIs in the " +\r
- "EVC UNI List.";\r
- description\r
- "For EP-LAN, All-to-One Bundling must be enabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/" +\r
- "mef-services:uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "max-evc-count != 1]) = 0))" {\r
- error-message "For EP-LAN, Max EVC Count must be 1 " +\r
- "for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-LAN, Max EVC Count must be 1 for all UNIs in " +\r
- "the EVC UNI List.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(../evc/evc-type = 'multipoint-to-multipoint'))" {\r
- error-message "For EP-LAN, EVC Type must be " +\r
- "Multipoint-to-Multipoint.";\r
- description\r
- "For EP-LAN, EVC Type must be " +\r
- "Multipoint-to-Multipoint.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(../evc/preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EP-LAN, CE-VLAN ID Preservation " +\r
- "must be enabled.";\r
- description\r
- "For EP-LAN, CE-VLAN ID Preservation must be enabled.";\r
- }\r
- must "(. != 'eplan') or ((. = 'eplan') and " +\r
- "(../evc/cos-preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EP-LAN, CE-VLAN ID CoS Preservation " +\r
- "must be enabled.";\r
- description\r
- "For EP-LAN, CE-VLAN ID CoS Preservation must be " +\r
- "enabled.";\r
- }\r
- must "(. != 'evplan') or ((. = 'evplan') and " +\r
- "(../evc/evc-type = 'multipoint-to-multipoint'))" {\r
- error-message "For EVP-LAN, EVC Type must be " +\r
- "Multipoint-to-Multipoint.";\r
- description\r
- "For EVP-LAN, EVC Type must be " +\r
- "Multipoint-to-Multipoint.";\r
- }\r
- must "(. != 'evplan') or ((. = 'evplan') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'true']) = 0))" {\r
- error-message "For EVP-LAN, All-to-One Bundling must " +\r
- "be disabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EVP-LAN, All-to-One Bundling must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "svc-mux-enabled = 'true']) = 0))" {\r
- error-message "For EP-TREE, Service Multiplexing " +\r
- "must be disabled for all UNIs in the " +\r
- "EVC UNI List.";\r
- description\r
- "For EP-TREE, Service Multiplexing must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "bundling-enabled = 'true']) = 0))" {\r
- error-message "For EP-TREE, Bundling must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-TREE, Bundling must be disabled for all UNIs " +\r
- "in the EVC UNI List.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/" +\r
- "mef-services:uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'false']) = 0))" {\r
- error-message "For EP-TREE, All-to-One Bundling must " +\r
- "be enabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-TREE, All-to-One Bundling must be enabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/" +\r
- "mef-services:uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "max-evc-count != 1]) = 0))" {\r
- error-message "For EP-TREE, Max EVC Count must be 1 " +\r
- "for all UNIs in the EVC UNI List.";\r
- description\r
- "For EP-TREE, Max EVC Count must be 1 for all UNIs " +\r
- "in the EVC UNI List.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(../evc/evc-type = 'rooted-multipoint'))" {\r
- error-message "For EP-TREE, EVC Type must be " +\r
- "Rooted-Multipoint.";\r
- description\r
- "For EP-TREE, EVC Type must be Rooted-Multipoint.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(../evc/preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EP-TREE, CE-VLAN ID Preservation " +\r
- "must be enabled.";\r
- description\r
- "For EP-TREE, CE-VLAN ID Preservation must be enabled.";\r
- }\r
- must "(. != 'eptree') or ((. = 'eptree') and " +\r
- "(../evc/cos-preserve-ce-vlan-id = 'true'))" {\r
- error-message "For EP-TREE, CE-VLAN ID " +\r
- "CoS Preservation must be enabled.";\r
- description\r
- "For EP-TREE, CE-VLAN ID CoS Preservation must be " +\r
- "enabled.";\r
- }\r
- must "(. != 'evptree') or ((. = 'evptree') and " +\r
- "(count(/mef-interfaces:mef-interfaces/" +\r
- "mef-interfaces:unis/mef-interfaces:uni" +\r
- "[mef-interfaces:uni-id = current()/../" +\r
- "mef-services:evc/mef-services:unis/mef-services:" +\r
- "uni/mef-services:uni-id]" +\r
- "[mef-interfaces:uni-id/../mef-interfaces:" +\r
- "all-to-one-bundling-enabled = 'true']) = 0))" {\r
- error-message "For EVP-TREE, All-to-One Bundling " +\r
- "must be disabled for all UNIs in the EVC UNI List.";\r
- description\r
- "For EVP-TREE, All-to-One Bundling must be disabled " +\r
- "for all UNIs in the EVC UNI List.";\r
- }\r
- must "(. != 'evptree') or ((. = 'evptree') and " +\r
- "(../evc/evc-type = 'rooted-multipoint'))" {\r
- error-message "For EVP-TREE, EVC Type must be " +\r
- "Rooted-Multipoint.";\r
- description\r
- "For EVP-TREE, EVC Type must be Rooted-Multipoint.";\r
- }\r
- description\r
- "The MEF Service Type.";\r
- }\r
- leaf user-label {\r
- type mef-types:identifier45;\r
- description\r
- "This MEF user label is set by the user to a value " +\r
- "that is easier to identify than the Service ID.";\r
- }\r
- leaf svc-entity {\r
- type mef-types:service-entity-type;\r
- default "evc";\r
- description\r
- "MEF Service Entity.";\r
- reference "[MEF12.2] Table 3.";\r
- }\r
- leaf tenant-id {\r
- type leafref {\r
- path "/mef-global:mef-global/mef-global:tenants-instances/mef-global:tenant-list/mef-global:name";\r
- }\r
- }\r
- }\r
- }\r
-}\r
+module mef-services {
+ namespace "http://metroethernetforum.org/ns/yang/mef-services";
+ prefix mef-services;
+ import ietf-yang-types { prefix yang; }
+ import ietf-inet-types { prefix inet; }
+ import mef-types { prefix mef-types; }
+ import mef-global { prefix mef-global; }
+ import mef-interfaces { prefix mef-interfaces; }
+ import yang-ext {prefix ext; revision-date "2013-07-09";}
+
+ organization "Metro Ethernet Forum";
+ contact
+ "Web URL: http://metroethernetforum.org/ E-mail: mibs@metroethernetforum.org
+ Postal: Metro Ethernet Forum 6033 W. Century Boulevard, Suite
+ 1107 Los Angeles, CA 90045 U.S.A. Phone: +1 310-642-2800 Fax:
+ +1 310-642-2808";
+ description
+ "This module implements the Carrier Ethernet Services as defined
+ in MEF 10.3, MEF 6.2, and MEF 7.2. Reference Overview: A number
+ of base documents have been used to create the MEF Services YANG
+ Module. The following are the abbreviations for the baseline documents:
+ [RFC 6991] refers to IETF RFC 6991 'Common YANG Data Types', 2013-07-15
+ [RFC 6643] refers to IETF RFC 6643 'Translation of Structure of
+ Management Information Version 2 (SMIv2) MIB Modules to YANG Modules',
+ 2011-11-25 [802.1AB] refers to 'Station and Media Access Control
+ Connectivity Discovery', IEEE 802.1AB-2009, September 2009 [802.1q]
+ refers to IEEE 802.1Q-2011 'IEEE Standard for Local and metropolitan
+ area networks --Media Access Control (MAC) Bridges and Virtual
+ Bridged Local Area Networks, August 2011 [802-2001] refers to
+ 'IEEE Standard for Local and Metropolitan Area Networks: Overview
+ and Architecture', IEEE 802-2001, February 2002 [MEF10.3] refers
+ to MEF 10.3 'Ethernet Services Attributes Phase 3', October 2013
+ [MEF6.2] refers to MEF 6.2 'EVC Ethernet Services Defintions Phase
+ 3', August 2014 [MEF40] refers to MEF 40 'UNI and EVC Definition
+ of Managed Objects', April 2013 [MEF45] refers to MEF 45 'Multi-CEN
+ L2CP', August 2014 [MEF7.2] refers to MEF 7.2 'Carrier Ethernet
+ Management Information Model', April 2013 [MEF7.3] refers to MEF
+ 7.3 'Carrier Ethernet Management Information Model', Working Draft
+ #1 2015 [RFC 2737] refers to IETF RFC 2737 'Entity MIB (Version
+ 2)', December 1999 [RFC 2863] refers to IETF RFC 2863 'The Interfaces
+ Group MIB', June 2000 [RFC 3419] refers to IETF RFC 3419 'Textual
+ Conventions for Transport Addresses', December 2002 [Y.1731] refers
+ to ITU-T Y.1731 'OAM functions and mechanisms for Ethernet based
+ networks', July 2011 [Q.840.1] refers to ITU-T Q.840.1 'Requirements
+ and analysis for NMS-EMS management interface of Ethernet over
+ Transport and Metro Ethernet Network(EoT/MEN)' March 2007";
+ revision 2015-05-26 {
+ description
+ "Formal Project Review Draft 1.";
+ reference "EVC Ethernet Services Definitions YANG Modules " +
+ "(MEF XX), TBD";
+ }
+
+ container mef-services {
+ description
+ "MEF Services";
+ list mef-service {
+ must "(not(/mef-global:mef-global/mef-global:svc-providers)" +
+ " and " +
+ "not(./sp-id)) or " +
+ "(/mef-global:mef-global/mef-global:svc-providers and " +
+ "./sp-id)" {
+ error-message "If the Service Providers list has been " +
+ "populated, a Service Provider ID must be " +
+ "configured for a Service.";
+ description
+ "A Service sees a single Service Provider. This must " +
+ "statement is effectively a 'mandatory true' when " +
+ "the Global Service Providers list is being used.";
+ }
+ key "svc-id";
+ unique "evc/evc-id";
+ unique "ipvc/ipvc-id";
+ description
+ "Metro Ethernet Forum's Ethernet Services.";
+ choice mef-service-choice {
+ case ipvc-choice {
+ container ipvc {
+ container unis {
+ list uni {
+ key "uni-id ip-uni-id";
+ leaf uni-id {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni/" +
+ "mef-interfaces:uni-id";
+ }
+ }
+ leaf ip-uni-id {
+ type mef-types:identifier45;
+ }
+
+ container evc-uni-ce-vlans {
+ description
+ "EVC Per UNI CE-VLAN IDs.";
+ list evc-uni-ce-vlan {
+ key "vid";
+ description
+ "A list of the CE-VLAN IDs mapped to this UNI " +
+ "for this EVC.";
+ reference "[MEF10.3] Section 8.6.1, [R24] " +
+ "[R25], Section 9.10.2, Section 9.12, " +
+ "[R76], [R81].";
+ leaf vid {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../../../uni-id]" +
+ "/mef-interfaces:ce-vlans/" +
+ "mef-interfaces:ce-vlan/" +
+ "mef-interfaces:vid";
+ }
+ description
+ "VLAN Identifier.";
+ }
+ }
+ }
+ }
+ }
+
+ leaf ipvc-id {
+ type mef-types:evc-id-type;
+ mandatory true;
+ }
+ leaf ipvc-type {
+ type mef-types:ipvc-type;
+
+ mandatory true;
+ description
+ "This IPVC attribute describes the IPVC as either " +
+ "Cloud-access, Multipoint, or " +
+ "Rooted-Multipoint.";
+ }
+ }
+ }
+ case evc-choice {
+ container evc {
+
+ must "not(sls-uni-inclusions) or " +
+ "(sls-uni-inclusions and not(sls-uni-exclusions))" {
+ error-message "The EVC Performance SLS Exclusions and " +
+ "Inclusions List cannot both be configured for " +
+ "an EVC.";
+ description
+ "The EVC Performance SLS Exclusions and Inclusions " +
+ "List cannot both be configured for an EVC.";
+ }
+ must "(evc-type != 'rooted-multipoint') or " +
+ "((evc-type = 'rooted-multipoint') and " +
+ "not(sls-uni-exclusions) )" {
+ error-message "If EVC Type is Rooted-Multipoint, " +
+ "sls-uni-inclusions must be used instead of " +
+ "sls-uni-exclusions.";
+ description
+ "If EVC Type is Rooted-Multipoint, " +
+ "sls-uni-inclusions must be used instead of " +
+ "sls-uni-exclusions.";
+ }
+ description
+ "Ethernet Virtual Circuit(EVC) Configuration and Status.";
+ container unis {
+ description
+ "EVC Per Universal Network Interface(UNI) " +
+ "Configuration and Status.";
+ list uni {
+ must "not(evc-uni-ce-vlans/evc-uni-ce-vlan[2]) or " +
+ "../../preserve-ce-vlan-id = 'true'" {
+ error-message "When more than one CE-VLAN-ID is " +
+ "mapped to an EVC at a UNI, the EVC must have " +
+ "CE-VLAN ID Preservation Enabled.";
+ description
+ "When more than one CE-VLAN-ID is mapped to " +
+ "an EVC at a UNI, the EVC must have CE-VLAN ID " +
+ "Preservation Enabled.";
+ }
+ must "/mef-interfaces:mef-interfaces/mef-interfaces:" +
+ "unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "max-svc-frame-size >= current()/../../" +
+ "mef-services:max-svc-frame-size]" {
+ error-message "The value of the EVC Maximum " +
+ "Service Frame Size must be less than " +
+ "or equal to all the UNI Maximum Service " +
+ "Frame Sizes.";
+ description
+ "The value of the EVC Maximum Service Frame " +
+ "Size must be less than or equal to all the " +
+ "UNI Maximum Service Frame Sizes.";
+ }
+ must "(/mef-interfaces:mef-interfaces/mef-interfaces:" +
+ "unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "bundling-enabled = 'true']) or " +
+ "(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'true']) or " +
+ "not(evc-uni-ce-vlans/evc-uni-ce-vlan[2])" {
+ error-message "If both Bundling and All-to-One " +
+ "Bundling are disabled for a UNI, only one " +
+ "CE VLAN ID can be configured for a specific " +
+ "EVC on that UNI.";
+ description
+ "If both Bundling and All-to-One Bundling are " +
+ "disabled for a UNI, only one CE VLAN ID can be " +
+ "configured for a specific EVC on that UNI.";
+ }
+ must "(/mef-interfaces:mef-interfaces/mef-interfaces:" +
+ "unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'false']) or " +
+ "(count(/mef-services:mef-services/" +
+ "mef-service/evc/unis/uni[uni-id = " +
+ "current()/uni-id]) = 1)" {
+ error-message "If All-to-One Bundling is enabled " +
+ "for any UNI in an EVC, all CE-VLAN IDs " +
+ "mapped to any EVC for that UNI must map " +
+ "to the same EVC ID.";
+ description
+ "If All-to-One Bundling is enabled for any UNI " +
+ "in an EVC, all CE-VLAN IDs mapped to any EVC " +
+ "for that UNI must map to the same EVC ID.";
+ }
+ must "((/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "ingress-bw-profile-per-uni]) or " +
+ "(/mef-services:mef-services/mef-service/" +
+ "evc/unis/uni" +
+ "[uni-id = current()/mef-services:uni-id]" +
+ "/ingress-bwp-flows-per-cos) or " +
+ "(/mef-services:mef-services/mef-service/" +
+ "evc/unis/uni" +
+ "[uni-id = current()/mef-services:uni-id]" +
+ "/ingress-bw-profile-per-evc)) or " +
+ "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes)" {
+ error-message "If no Ingress Bandwidth Profiles " +
+ "are specied for this UNI (BW Profile " +
+ "Per UNI, BWP Flows Per CoS, nor BW Profile " +
+ "Per EVC), then the UNI Ingress Envelopes " +
+ "list must be empty.";
+ description
+ "If no Ingress Bandwidth Profiles are specied " +
+ "for this UNI (BW Profile Per UNI, BWP Flows " +
+ "Per CoS, nor BW Profile Per EVC), then the " +
+ "UNI Ingress Envelopes list must be empty.";
+ }
+ must "((/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "egress-bw-profile-per-uni]) or " +
+ "(/mef-services:mef-services/mef-service/" +
+ "evc/unis/uni" +
+ "[uni-id = current()/mef-services:uni-id]" +
+ "/egress-bwp-flows-per-eec) or " +
+ "(/mef-services:mef-services/mef-service/" +
+ "evc/unis/uni" +
+ "[uni-id = current()/mef-services:uni-id]" +
+ "/egress-bw-profile-per-evc)) or " +
+ "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes)" {
+ error-message "If no Egress Bandwidth Profiles are " +
+ "specied for this UNI (BW Profile Per UNI, " +
+ "BWP Flows Per EEC, nor BW Profile Per EVC), " +
+ "then the UNI Egress Envelopes list must be " +
+ "empty.";
+ description
+ "If no Egress Bandwidth Profiles are specied " +
+ "for this UNI (BW Profile Per UNI, BWP Flows " +
+ "Per EEC, nor BW Profile Per EVC), then the UNI " +
+ "Egress Envelopes list must be empty.";
+ }
+ must "not(./ingress-bw-profile-per-evc) or " +
+ "((./ingress-bw-profile-per-evc) and " +
+ "not(./ingress-bwp-flows-per-cos))" {
+ error-message "If there is a per EVC Ingress " +
+ "Bandwidth Profile on an EVC, then there " +
+ "cannot be any per Class of Service Ingress " +
+ "Bandwidth Profiles on that EVC.";
+ description
+ "If there is a per EVC Ingress Bandwidth Profile " +
+ "on an EVC, then there cannot be any per " +
+ "Class of Service Ingress Bandwidth Profiles " +
+ "on that EVC.";
+ }
+ must "not(./egress-bw-profile-per-evc) or " +
+ "((./egress-bw-profile-per-evc) and " +
+ "not(./egress-bwp-flows-per-eec))" {
+ error-message "If there is a per EVC Egress " +
+ "Bandwidth Profile on an EVC, then there " +
+ "cannot be any per Egress Equivalence " +
+ "Class Identifier Bandwidth Profiles on " +
+ "that EVC.";
+ description
+ "If there is a per EVC Egress Bandwidth " +
+ "Profile on an EVC, then there cannot be " +
+ "any per Egress Equivalence Class Identifier " +
+ "Bandwidth Profiles on that EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-bw-profile-" +
+ "per-uni) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-bw-profile-per-uni]" +
+ "[mef-global:cir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-bw-profile-per-uni]" +
+ "[mef-global:cbs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Ingress Bandwidth Profile Per UNI: " +
+ "If CIR > 0, CBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Ingress Bandwidth Profile Per UNI: If CIR > 0, " +
+ "CBS must be greater than or equal to the " +
+ "EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-bw-profile-per-uni) " +
+ "or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:egress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-bw-profile-per-uni]" +
+ "[mef-global:cir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-bw-profile-per-uni]" +
+ "[mef-global:cbs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Egress Bandwidth Profile Per UNI: " +
+ "If CIR > 0, CBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Egress Bandwidth Profile Per UNI: If CIR > 0, " +
+ "CBS must be greater than or equal to the " +
+ "EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:cir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:cbs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Ingress Bandwidth Profile Envelope: " +
+ "If CIR > 0, CBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Ingress Bandwidth Profile Envelope: " +
+ "If CIR > 0, CBS must be greater than " +
+ "or equal to the EVC Max Service Frame " +
+ "Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:egress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = " +
+ "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:cir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:egress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:cbs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Egress Bandwidth Profile " +
+ "Envelope: If CIR > 0, CBS must be greater " +
+ "than or equal to the EVC Max Service Frame " +
+ "Size for the EVC.";
+ description
+ "Egress Bandwidth Profile Envelope: If CIR > 0, " +
+ "CBS must be greater than or equal to the " +
+ "EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-bw-profile-per-uni) " +
+ "or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]/mef-interfaces:" +
+ "ingress-bw-profile-per-uni]" +
+ "[mef-global:eir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-bw-profile-per-uni]" +
+ "[mef-global:ebs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Ingress Bandwidth Profile Per UNI: " +
+ "If EIR > 0, EBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Ingress Bandwidth Profile Per UNI: If EIR > 0, " +
+ "EBS must be greater than or equal to the " +
+ "EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-bw-profile-" +
+ "per-uni) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:egress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]/mef-interfaces:" +
+ "egress-bw-profile-per-uni]" +
+ "[mef-global:eir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:ingress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]/mef-interfaces:" +
+ "egress-bw-profile-per-uni]" +
+ "[mef-global:ebs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Egress Bandwidth Profile Per UNI: " +
+ "If EIR > 0, EBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Egress Bandwidth Profile Per UNI: If EIR > 0, " +
+ "EBS must be greater than or equal to the " +
+ "EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:" +
+ "unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes) or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:eir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:ingress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:ebs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Ingress Bandwidth Profile Envelope: " +
+ "If EIR > 0, EBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Ingress Bandwidth Profile Envelope: " +
+ "If EIR > 0, EBS must be greater than or equal " +
+ "to the EVC Max Service Frame Size for the EVC.";
+ }
+ must "not(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes) or " +
+ "(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:egress-bwp-flows/" +
+ "mef-global:bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:eir = 0]) or " +
+ "(/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:egress-bwp-flows/mef-global:" +
+ "bwp-flow" +
+ "[mef-global:bw-profile = /mef-interfaces:" +
+ "mef-interfaces/mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/" +
+ "mef-services:uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "bwp-flows/mef-interfaces:bwp-flow/" +
+ "mef-interfaces:bw-profile]" +
+ "[mef-global:ebs >= current()/../../" +
+ "max-svc-frame-size])" {
+ error-message "Egress Bandwidth Profile Envelope: " +
+ "If EIR > 0, EBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ description
+ "Egress Bandwidth Profile Envelope: " +
+ "If EIR > 0, EBS must be greater than or " +
+ "equal to the EVC Max Service Frame Size " +
+ "for the EVC.";
+ }
+ key "uni-id";
+ description
+ "EVC Flow Points and EVC-UNI List defines the " +
+ "roles of each UNI in the Service. One UNI can " +
+ "be used by 0 or more EVCs.";
+ reference "[MEF10.3] Section 8.3. " +
+ "[MEF7.3] Section 12.2.2.";
+ container evc-uni-ce-vlans {
+ description
+ "EVC Per UNI CE-VLAN IDs.";
+ list evc-uni-ce-vlan {
+ key "vid";
+ description
+ "A list of the CE-VLAN IDs mapped to this UNI " +
+ "for this EVC.";
+ reference "[MEF10.3] Section 8.6.1, [R24] " +
+ "[R25], Section 9.10.2, Section 9.12, " +
+ "[R76], [R81].";
+ leaf vid {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../../../uni-id]" +
+ "/mef-interfaces:ce-vlans/" +
+ "mef-interfaces:ce-vlan/" +
+ "mef-interfaces:vid";
+ }
+ must "not(current()/../../" +
+ "evc-uni-ce-vlan[2]) or " +
+ "(count(../../../../uni/evc-uni-ce-vlans/" +
+ "evc-uni-ce-vlan" +
+ "[vid = current()]) = " +
+ "count(../../../../uni))" {
+ error-message "If more than one CE-VLAN ID " +
+ "is configured for a UNI as part of " +
+ "an EVC, every CE VLAN-ID mapped to " +
+ "that EVC must be configured for all " +
+ "UNIs within that EVC.";
+ description
+ "If more than one CE-VLAN ID is configured " +
+ "for a UNI as part of an EVC, every " +
+ "CE VLAN-ID mapped to that EVC must be " +
+ "configured for all UNIs within that EVC.";
+ }
+ description
+ "VLAN Identifier.";
+ }
+ }
+ }
+ container ingress-bwp-flows-per-cos {
+ presence "Use Ingress Bandwidth Profiles Per CoS";
+ description
+ "EVC Per UNI Class of Service Identifiers " +
+ "corresponding to this EVC's Ingress Bandwidth " +
+ "Profile Flows.";
+ leaf coupling-enabled {
+ type boolean;
+ default "false";
+ description
+ "EVC Per UNI Envelope Coupling Flag (CF) " +
+ "attribute.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ list bwp-flow-per-cos {
+ key "cos-name";
+ description
+ "EVC Per UNI: The list of Class of Service " +
+ "Identifiers corresponding to this UNI's " +
+ "Ingress Bandwidth Profile Flow.";
+ leaf cos-name {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:cos-names/" +
+ "mef-global:cos-name/mef-global:name";
+ }
+ description
+ "EVC Per UNI: Class of Service Identifier " +
+ "for this Bandwidth Profile Flow.";
+ reference "[MEF7.3] Section 12.1.2.";
+ }
+ leaf bw-profile {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../../../uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/" +
+ "mef-interfaces:env-id";
+ }
+ mandatory true;
+ description
+ "EVC Per UNI: Ingress Bandwidth Profile " +
+ "Envelope Per CoS ID. If this parameter " +
+ "is not configured (ie. 'No') this " +
+ "setting is configured else at the " +
+ "UNI Level.";
+ reference "[MEF10.3] Section 10.6, Table 28. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ }
+ }
+ container egress-bwp-flows-per-eec {
+ presence "Using Egress Bandwidth Profiles Per " +
+ "Egress Equivalence Class";
+ description
+ "EVC Per UNI: The Egress Equivalence Class " +
+ "Identifiers corresponding to this EVC's Egress " +
+ "Bandwidth Profile Flows.";
+ leaf coupling-enabled {
+ type boolean;
+ default "false";
+ description
+ "EVC Per UNI: The Envelope Coupling Flag (CF) " +
+ "attribute.";
+ reference "[MEF10.3] Section 12.1.";
+ }
+ list bwp-flow-per-eec {
+ key "eec-name";
+ description
+ "EVC Per UNI: The list of Egress Equivalence " +
+ "Class Identifiers corresponding to this " +
+ "EVC's Egress Bandwidth Profile Flow.";
+ leaf eec-name {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec-names/" +
+ "mef-global:eec-name/mef-global:name";
+ }
+ description
+ "EVC Per UNI: Egress Equivalence Class " +
+ "Identifier for this Bandwidth Profile Flow.";
+ reference "[MEF7.3] Section 12.1.2.";
+ }
+ leaf bw-profile {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../../../uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/" +
+ "mef-interfaces:env-id";
+ }
+ mandatory true;
+ description
+ "EVC Per UNI: Egress Bandwidth Profile " +
+ "Envelope Per Equivance Class. If this " +
+ "parameter is not configured (ie. 'No') " +
+ "this setting is configured else at the " +
+ "UNI Level.";
+ reference "[MEF10.3] Section 10.6, Table 28. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ }
+ }
+ container status {
+ description
+ "EVC Per UNI: This status group is related to " +
+ "the MEF 7.3 Service Endpoint";
+ leaf oper-state-enabled {
+ type boolean;
+ default "false";
+ config false;
+ description
+ "EVC Per UNI: Operational Status of the " +
+ "Virtual Connection as Enabled/Disabled.";
+ reference "[MEF15]. [MEF7.3] Section 11.2.1.";
+ }
+ leaf available-status {
+ type mef-types:svc-endpoint-availability-type;
+ default "not-installed";
+ config false;
+ description
+ "EVC Per UNI: Availability Status of the " +
+ "Virtual Connection.";
+ reference "[MEF15]. [MEF7.3] Section 11.2.1.";
+ }
+ }
+ leaf uni-id {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni/" +
+ "mef-interfaces:uni-id";
+ }
+ description
+ "EVC Per UNI: The UNI ID paired with the EVC ID " +
+ "in the containing list.";
+ reference "[MEF10.3] Section 8.3, Section 10.1. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf role {
+ type mef-types:evc-uni-role-type;
+ mandatory true;
+ description
+ "EVC Per UNI: The UNI Role MUST have the value " +
+ "of either 'root' or 'leaf'.";
+ reference "[MEF10.3] [R4], [R5], [R10], [R11], " +
+ "[R12]. [MEF7.3] Section 12.2.2.";
+ }
+ leaf admin-state-enabled {
+ type boolean;
+ default "true";
+ description
+ "EVC Per UNI: Locked/Unlocked is inconsistent " +
+ "with Oper Status and will be confusing.";
+ reference "[MEF15]. [MEF7.3] Section 11.2.1.";
+ }
+ leaf color-id {
+ type mef-types:cos-color-identifier-type;
+ description
+ "EVC Per UNI: The Color Identifier for " +
+ "Service Frames.";
+ reference "[MEF10.3] Section 10.3. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf data-svc-frm-cos {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:cos/mef-global:cos-profile/" +
+ "mef-global:id";
+ }
+ must "not(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:cos/" +
+ "mef-global:cos-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:cos-pcp) or " +
+ "((/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:cos/" +
+ "mef-global:cos-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:cos-pcp) and " +
+ "((../color-id = 'pcp') or " +
+ "(../color-id = 'dei')) )" {
+ error-message "When the Class of Service " +
+ "Identifier is based on PCP for a " +
+ "given EVC at a given UNI, the Color " +
+ "Identifier must be based on either " +
+ "DEI or PCP.";
+ description
+ "When the Class of Service Identifier is " +
+ "based on PCP for a given EVC at a given UNI, " +
+ "the Color Identifier must be based on either " +
+ "DEI or PCP.";
+ }
+ must "not(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:cos/mef-global:" +
+ "cos-profile" +
+ "[mef-global:id = current()]/mef-global:" +
+ "cos-dscp) or " +
+ "((/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:cos/mef-global:" +
+ "cos-profile" +
+ "[mef-global:id = current()]/mef-global:" +
+ "cos-dscp) and " +
+ "(../color-id = 'dscp'))" {
+ error-message "When the Class of Service " +
+ "Identifier is based on DSCP for a " +
+ "given EVC at a given UNI, the Color " +
+ "Identifier must be based DSCP.";
+ description
+ "When the Class of Service Identifier is based " +
+ "on DSCP for a given EVC at a given UNI, the " +
+ "Color Identifier must be based DSCP.";
+ }
+ description
+ "EVC Per UNI: Ingress Data Service Frame " +
+ "CoS Profile.";
+ reference "[MEF10.3] Section 8.8, Section 10.2. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf l2cp-svc-frm-cos {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:l2cp-cos/mef-global:" +
+ "l2cp-profile/mef-global:id";
+ }
+ description
+ "EVC Per UNI: Ingress Layer 2 Control Protocol " +
+ "Processing.";
+ reference "[MEF10.3] Section 8.8, Section 10.2. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf soam-svc-frm-cos {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:cos/mef-global:cos-profile/" +
+ "mef-global:id";
+ }
+ must "(not(.) and not(../data-svc-frm-cos)) or " +
+ "(. = ../data-svc-frm-cos)" {
+ error-message "For a given EVC at a given UNI, " +
+ "the basis for the Class of Service " +
+ "Identifier for ingress SOAM Service " +
+ "Frames must be the same as that for " +
+ "ingress Data Service Frames.";
+ description
+ "For a given EVC at a given UNI, the basis " +
+ "for the Class of Service Identifier for " +
+ "ingress SOAM Service Frames must be the " +
+ "same as that for ingress Data Service Frames.";
+ }
+ description
+ "EVC Per UNI: Ingress SOAM Service Frames.";
+ reference "[MEF7.3] Section 12.1.2.";
+ }
+ leaf data-svc-frm-eec {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:eec/mef-global:eec-profile/" +
+ "mef-global:id";
+ }
+ must "not(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec/mef-global:" +
+ "eec-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:eec-pcp) or " +
+ "((/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec/mef-global:" +
+ "eec-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:eec-pcp) and " +
+ "((../color-id = 'pcp') or " +
+ "(../color-id = 'dei')) )" {
+ error-message "When the Egress Equivalence " +
+ "Class Identifier is based on PCP " +
+ "for a given EVC at a given UNI, " +
+ "the Color Identifier must be based " +
+ "on either DEI or PCP.";
+ description
+ "When the Egress Equivalence Class Identifier " +
+ "is based on PCP for a given EVC at a " +
+ "given UNI, the Color Identifier must " +
+ "be based on either DEI or PCP.";
+ }
+ must "not(/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec/mef-global:" +
+ "eec-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:eec-dscp) or " +
+ "((/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec/mef-global:" +
+ "eec-profile" +
+ "[mef-global:id = current()]" +
+ "/mef-global:eec-dscp) and " +
+ "(../color-id = 'dscp'))" {
+ error-message "When the Egress Equivalence " +
+ "Class Identifier is based on DSCP for " +
+ "a given EVC at a given UNI, the Color " +
+ "Identifier must be based DSCP.";
+ description
+ "When the Egress Equivalence Class Identifier " +
+ "is based on DSCP for a given EVC at a given " +
+ "UNI, the Color Identifier must be based DSCP.";
+ }
+ description
+ "EVC Per UNI: Egress Data Service Frame Processing.";
+ reference "[MEF10.3] Section 10.4. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf l2cp-svc-frm-eec {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:l2cp-eec/mef-global:" +
+ "l2cp-profile/mef-global:id";
+ }
+ description
+ "EVC Per UNI: Egress Layer 2 Control Protocol " +
+ "Processing.";
+ reference "[MEF10.3] Section 10.4. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf soam-svc-frm-eec {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "profiles/mef-global:eec/mef-global:" +
+ "eec-profile/mef-global:id";
+ }
+ must "(not(.) and not(../data-svc-frm-eec)) or " +
+ "(. = ../data-svc-frm-eec)" {
+ error-message "For a given EVC at a given UNI, " +
+ "the basis for the Egress Equivalence " +
+ "Class Identifier for egress SOAM " +
+ "Service Frames must be the same as " +
+ "that for egress Data Service Frames.";
+ description
+ "For a given EVC at a given UNI, the basis " +
+ "for the Egress Equivalence Class Identifier " +
+ "for egress SOAM Service Frames must be " +
+ "the same as that for egress Data " +
+ "Service Frames.";
+ }
+ description
+ "EVC Per UNI: Egress SOAM Service Frames.";
+ reference "[MEF10.3] Section 10.4. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf ingress-bw-profile-per-evc {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../uni-id]" +
+ "/mef-interfaces:ingress-envelopes/" +
+ "mef-interfaces:envelope/" +
+ "mef-interfaces:env-id";
+ }
+ description
+ "EVC Per UNI: Ingress Bandwidth Profile " +
+ "Envelope Per EVC. If this parameter is " +
+ "not configured (ie. 'No') this setting " +
+ "is configured else at the UNI Level.";
+ reference "[MEF10.3] Section 10.5. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf egress-bw-profile-per-evc {
+ type leafref {
+ path "/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/" +
+ "mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = " +
+ "current()/../uni-id]" +
+ "/mef-interfaces:egress-envelopes/" +
+ "mef-interfaces:envelope/mef-interfaces:" +
+ "env-id";
+ }
+ description
+ "EVC Per UNI: Egress Bandwidth Profile Envelope " +
+ "Per EVC. If this parameter is not configured " +
+ "(ie. 'No') this setting is configured else at " +
+ "the UNI Level.";
+ reference "[MEF10.3] Section 10.7. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf src-mac-addr-limit-enabled {
+ type boolean;
+ default "false";
+ description
+ "EVC Per UNI: Source MAC Address Limit " +
+ "Enable / Disable. If Enabled, the values " +
+ "for the Source MAC Address Limit and Source " +
+ "MAC Address Interval must be set.";
+ reference "[MEF10.3] Section 10.9. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf src-mac-addr-limit {
+ type uint32 {
+ range "1..max";
+ }
+ description
+ "EVC Per UNI: Source MAC Address Limit. " +
+ "This value is used when the Source MAC Address " +
+ "Limit Enabled is true.";
+ reference "[MEF10.3] Section 10.9.";
+ }
+ leaf src-mac-addr-limit-interval {
+ type yang:timeticks;
+ default "0";
+ description
+ "EVC Per UNI: Source MAC Address Limit " +
+ "Interval. This value is used when the " +
+ "Source MAC Address Limit Enabled is true.";
+ reference "[MEF10.3] Section 10.9.";
+ }
+ leaf test-meg-enabled {
+ type boolean;
+ default "false";
+ description
+ "EVC Per UNI: Test MEG Enabled / Disabled.";
+ reference "[MEF10.3] Section 10.10. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf test-meg {
+ type mef-types:identifier45;
+ description
+ "EVC Per UNI: Test MEG Identifier.";
+ reference "[MEF7.3] Section 12.1.2.";
+ }
+ leaf subscriber-meg-mip-enabled {
+ type boolean;
+ default "false";
+ description
+ "EVC Per UNI: Subscriber MEG MIP " +
+ "Enabled / Disabled.";
+ reference "[MEF10.3] Section 10.11. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf subscriber-meg-mip {
+ type mef-types:identifier45;
+ description
+ "EVC Per UNI: Subscriber MEG MIP Identifier.";
+ reference "[MEF7.3] Section 12.1.2.";
+ }
+ }
+ }
+ container status {
+ description
+ "This status group is related to the MEF 7.3 Virtual " +
+ "Connection";
+ leaf oper-state-enabled {
+ type boolean;
+ default "false";
+ config false;
+ description
+ "EVC Operational Status of the Virtual Connection " +
+ "as Enabled/Disabled.";
+ reference "[MEF7.3] Section 11.1.1.";
+ }
+ leaf available-status {
+ type mef-types:virt-cx-availability-type;
+ default "not-installed";
+ config false;
+ description
+ "EVC Availability Status of the Virtual Connection.";
+ reference "[MEF7.3] Section 11.1.1.";
+ }
+ }
+ container sls-inclusions-by-cos {
+ description
+ "SLS Inclusions by CoS: For this EVC, the following " +
+ "CoS Names/Labels are applicable.";
+ list sls-inclusion-by-cos {
+ key "cos-name";
+ description
+ "CoS Name.";
+ leaf cos-name {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:profiles/" +
+ "mef-global:cos-names/mef-global:" +
+ "cos-name/mef-global:name";
+ }
+ description
+ "EVC: This attribute identifies the name of " +
+ "a class of service (CoS) instance to be used " +
+ "for EVC Performance.";
+ }
+ }
+ }
+ container sls-uni-inclusions {
+ presence "EVC: Defines the EVC Flow Points (UNI) Pairs " +
+ "that must conform to the EVC's SLS Performance " +
+ "Metrics.";
+ description
+ "SLS UNI Inclusions List. The following pairs of UNI " +
+ "Interconnections are to required to meet the " +
+ "SLS Performance Objectives. Configing both SLS " +
+ "UNI Inclusions and SLS UNI Exclusions is not " +
+ "permitted.";
+ list sls-uni-inclusion-set {
+ must "uni-id1 != uni-id2" {
+ error-message "The two UNI IDs for a given " +
+ "inclusion cannot be the same.";
+ description
+ "The two UNI IDs for a given inclusion " +
+ "cannot be the same.";
+ }
+ must "(../../evc-type != 'rooted-multipoint') or " +
+ "((../../evc-type = 'rooted-multipoint') " +
+ "and " +
+ "not((../../unis/uni[uni-id = " +
+ "current()/uni-id1]/role = 'leaf') and " +
+ "(../../unis/uni[uni-id = current()/uni-id2]" +
+ "/role = 'leaf')))" {
+ error-message "If EVC Type is Rooted-Multipoint, " +
+ "sls-uni-inclusion UNI Pairs cannot both " +
+ "be role 'leaf'.";
+ description
+ "If EVC Type is Rooted-Multipoint, " +
+ "sls-uni-inclusion UNI Pairs cannot " +
+ "both be role 'leaf'.";
+ }
+ key "pm-type pm-id uni-id1 uni-id2";
+ description
+ "EVC: Defines the EVC Flow Points (UNI) Pairs that " +
+ "must conform to the EVC's SLS Performance " +
+ "Metrics. Use of this list indicates that a " +
+ "complete set of UNI Pairs has been specified " +
+ "for the Performance Metrics defined in the " +
+ "selected SLS.";
+ leaf pm-type {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:slss/" +
+ "mef-global:sls" +
+ "[mef-global:sls-id = current()/../../../" +
+ "evc-performance-sls]" +
+ "/mef-global:perf-objs/mef-global:" +
+ "perf-obj/mef-global:pm-type";
+ }
+ description
+ "EVC: Performance Metric.";
+ reference "[MEF10.3] Section 8.8.";
+ }
+ leaf pm-id {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:slss/" +
+ "mef-global:sls" +
+ "[mef-global:sls-id = current()/../../../" +
+ "evc-performance-sls]" +
+ "/mef-global:perf-objs/mef-global:perf-obj" +
+ "[mef-global:pm-type = current()/../" +
+ "pm-type]" +
+ "/mef-global:pm-id";
+ }
+ description
+ "EVC: This is a friendly name for specific " +
+ "performance profile.";
+ }
+ leaf uni-id1 {
+ type leafref {
+ path "../../../unis/uni/uni-id";
+ }
+ description
+ "EVC: The UNI ID paired with the EVC ID in the " +
+ "containing list.";
+ reference "[MEF10.3] Section 8.3, Section 10.1. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf uni-id2 {
+ type leafref {
+ path "../../../unis/uni/uni-id";
+ }
+ description
+ "EVC: The UNI ID paired with the EVC ID in the " +
+ "containing list.";
+ reference "[MEF10.3] Section 8.3, Section 10.1. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ }
+ }
+ container sls-uni-exclusions {
+ presence "Not all EVC Flow Points (UNI) must conform " +
+ "to the EVC SLS Performance Metrics.";
+ description
+ "EVC: Not all EVC Flow Points (UNI) must conform to " +
+ "the EVC SLS Performance Metrics. Use of this " +
+ "list indicates that all UNI Pairs EXCEPT for " +
+ "the ones indicated (per Performance Metric) must " +
+ "conform to the SLS.";
+ list sls-uni-exclusion-set {
+ must "uni-id1 != uni-id2" {
+ error-message "The two UNI IDs for a given " +
+ "exclusion cannot be the same.";
+ description
+ "The two UNI IDs for a given exclusion cannot " +
+ "be the same as these pairs are invalid as " +
+ "defined in MEF 10.3.";
+ }
+ key "pm-type pm-id uni-id1 uni-id2";
+ description
+ "SLS UNI Exclusions List. The following pairs " +
+ "of UNI Interconnections are not required " +
+ "meet the SLS Performance Objectives. " +
+ "Configing both SLS UNI Inclusions and SLS " +
+ "UNI Exclusions is not permitted.";
+ leaf pm-type {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:" +
+ "slss/mef-global:sls" +
+ "[mef-global:sls-id = current()/../../../" +
+ "evc-performance-sls]" +
+ "/mef-global:perf-objs/mef-global:" +
+ "perf-obj/mef-global:pm-type";
+ }
+ description
+ "EVC: Performance Metric.";
+ reference "[MEF10.3] Section 8.8.";
+ }
+ leaf pm-id {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:slss/" +
+ "mef-global:sls" +
+ "[mef-global:sls-id = current()/../../../" +
+ "evc-performance-sls]" +
+ "/mef-global:perf-objs/mef-global:perf-obj" +
+ "[mef-global:pm-type = current()/../" +
+ "pm-type]" +
+ "/mef-global:pm-id";
+ }
+ description
+ "EVC: This is a friendly name for specific " +
+ "performance profile.";
+ }
+ leaf uni-id1 {
+ type leafref {
+ path "../../../unis/uni/uni-id";
+ }
+ description
+ "EVC: The UNI ID paired with the EVC ID in the " +
+ "containing list.";
+ reference "[MEF10.3] Section 8.3, Section 10.1. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ leaf uni-id2 {
+ type leafref {
+ path "../../../unis/uni/uni-id";
+ }
+ description
+ "EVC: The UNI ID paired with the EVC ID in the " +
+ "containing list.";
+ reference "[MEF10.3] Section 8.3, Section 10.1. " +
+ "[MEF7.3] Section 12.1.2.";
+ }
+ }
+ }
+ leaf evc-id {
+ type mef-types:evc-id-type;
+ mandatory true;
+ description
+ "The EVC ID must be unique across all EVCs in the CEN." +
+ " The EVC ID must be non-NULL.";
+ reference "[MEF10.3] Section 8.2 [R7]. " +
+ "[MEF7.3] Section 11.1.1, Section 12.2.2.";
+ }
+ leaf evc-status {
+ type mef-types:evc-status-type;
+ config false;
+ description
+ "EVC Operational Status.";
+ reference "[MEF16] Section 5.3.";
+ }
+ leaf evc-type {
+ type mef-types:evc-type;
+ must "(. != 'point-to-point') or " +
+ "((. = 'point-to-point') and " +
+ "(count(../unis/uni[role = 'leaf']) = 0))" {
+ error-message "If EVC Type is Point-to-Point, all " +
+ "UNI Roles must be root.";
+ description
+ "If EVC Type is Point-to-Point, all UNI Roles must " +
+ "be root.";
+ }
+ must "(. != 'multipoint-to-multipoint') or " +
+ "((. = 'multipoint-to-multipoint') and " +
+ "(count(../unis/uni[role = 'leaf']) = 0))" {
+ error-message "If EVC Type is " +
+ "Multipoint-to-Multipoint, all UNI Roles " +
+ "must be root.";
+ description
+ "If EVC Type is Multipoint-to-Multipoint, all UNI " +
+ "Roles must be root.";
+ }
+ must "(. != 'rooted-multipoint') or " +
+ "((. = 'rooted-multipoint') and " +
+ "(count(../unis/uni[role = 'root']) > 0) )" {
+ error-message "If EVC Type is Rooted-Multipoint, one " +
+ "or more UNI Roles must be root.";
+ description
+ "If EVC Type is Rooted-Multipoint, one or more " +
+ "UNI Roles must be root.";
+ }
+ must "(. != 'point-to-point') or " +
+ "((. = 'point-to-point') and " +
+ "(count(../unis/uni) = 2))" {
+ error-message "If EVC Type is Point-to-Point, there " +
+ "must be exactly 2 UNI configured for the EVC.";
+ description
+ "If EVC Type is Point-to-Point, there must be " +
+ "exactly 2 UNI configured for the EVC.";
+ }
+ must "(. != 'multipoint-to-multipoint') or " +
+ "((. = 'multipoint-to-multipoint') and " +
+ "(count(../unis/uni) > 1) and " +
+ "(count(../unis/uni) <= ../max-uni-count))" {
+ error-message "If EVC Type is " +
+ "Multipoint-to-Multipoint, " +
+ "there must be 2 or more UNI configured " +
+ "for the EVC.";
+ description
+ "If EVC Type is Multipoint-to-Multipoint, " +
+ "there must be 2 or more UNI configured for " +
+ "the EVC.";
+ }
+ must "(. != 'rooted-multipoint') or " +
+ "((. = 'rooted-multipoint') and " +
+ "(count(../unis/uni) > 1) and " +
+ "(count(../unis/uni) <= ../max-uni-count))" {
+ error-message "If EVC Type is Rooted-Multipoint, " +
+ "there must be 2 or more UNI configured for the EVC.";
+ description
+ "If EVC Type is Rooted-Multipoint, there must " +
+ "be 2 or more UNI configured for the EVC.";
+ }
+ must "(. != 'point-to-point') or " +
+ "((. = 'point-to-point') and " +
+ "(../max-uni-count = 2))" {
+ error-message "If EVC Type is Point-to-Point, " +
+ "the value of max-uni-count must be 2.";
+ description
+ "If EVC Type is Point-to-Point, the value of " +
+ "max-uni-count must be 2.";
+ }
+ must "(. != 'multipoint-to-multipoint') or " +
+ "((. = 'multipoint-to-multipoint') and " +
+ "(../max-uni-count > 2))" {
+ error-message "If EVC Type is " +
+ "Multipoint-to-Multipoint, the value of " +
+ "max-uni-count must be at least 3.";
+ description
+ "If EVC Type is Multipoint-to-Multipoint, the " +
+ "value of max-uni-count must be at least 3.";
+ }
+ must "(. != 'rooted-multipoint') or " +
+ "((. = 'rooted-multipoint') and " +
+ "(../max-uni-count > 2))" {
+ error-message "If EVC Type is Rooted-Multipoint, " +
+ "the value of max-uni-count must be at " +
+ "least 3.";
+ description
+ "If EVC Type is Rooted-Multipoint, the value " +
+ "of max-uni-count must be at least 3.";
+ }
+ // mandatory true;
+ description
+ "This EVC attribute describes the EVC as either " +
+ "Multipoint-To-Multipoint, Point-To-Point, or " +
+ "Rooted-Multipoint.";
+ reference "[MEF10.3] Section 8.1, [R4], [R5], " +
+ "[R10], [R11], [R12], [R13] and [R14]. " +
+ "[MEF7.3] Section 12.2.2.";
+ }
+ leaf admin-state-enabled {
+ type boolean;
+ default "true";
+ description
+ "EVC: Locked/Unlocked is inconsistent with " +
+ "Oper Status and will be confusing.";
+ reference "[MEF15]. [MEF7.3] Section 11.1.1.";
+ }
+ leaf elastic-enabled {
+ type boolean;
+ default "true";
+ description
+ "EVC: Elastic Enabled/Disabled.";
+ reference "[MEF7.3] Section 11.1.1.";
+ }
+ leaf elastic-service {
+ type mef-types:identifier45;
+ description
+ "EVC: Related to CE4Cloud Information Model.";
+ reference "[MEF7.3] Section 11.1.1.";
+ }
+ leaf max-uni-count {
+ type uint32 {
+ range "2..max";
+ }
+ must "(. > 2) or ((. = 2) and " +
+ "(../evc-type = 'point-to-point'))" {
+ error-message "If EVC Type is Point-to-Point, the " +
+ "max-uni-count value must be 2.";
+ description
+ "If EVC Type is Point-to-Point, the max-uni-count " +
+ "value must be 2.";
+ }
+ must "(. = 2) or ((. > 2) and " +
+ "((../evc-type = 'multipoint-to-multipoint') or " +
+ "(../evc-type = 'rooted-multipoint')))" {
+ error-message "If EVC Type is " +
+ "Multipoint-to-Multipoint or " +
+ "Rooted-Multipoint, the max-uni-count value " +
+ "must be at least 3.";
+ description
+ "If EVC Type is Multipoint-to-Multipoint or " +
+ "Rooted-Multipoint, the max-uni-count value " +
+ "must be at least 3.";
+ }
+ default "2";
+ description
+ "EVC:The Maximum Number of UNIs this EVC can be " +
+ "configured for (Default 2).If EVC Type is " +
+ "Multipoint-to-Multipoint or Rooted-Multipoint, " +
+ "the max-uni-count value must be at least 3. " +
+ "This value must be 2 for point-to-point mode.";
+ reference "[MEF10.3] [R14]. [MEF7.3] Section 12.2.2.";
+ }
+ leaf preserved-vlan {
+ type uint32;
+ }
+ leaf preserve-ce-vlan-id {
+ type boolean;
+ default "false";
+ description
+ "EVC:An EVC with more than one CE-VLAN ID mapping " +
+ "to it must have the same list of CE-VLAN IDs " +
+ "mapping to the EVC at each UNI in the EVC.";
+ reference "[MEF10.3] Section 8.6.1, [R24] [R25], " +
+ "Section 9.10.2, Section 9.12, [R81], Figure 20. " +
+ "[MEF7.3] Section 12.2.2.";
+ }
+ leaf cos-preserve-ce-vlan-id {
+ type boolean;
+ default "false";
+ description
+ "EVC: Preserve CE-VLAN ID for CoS.";
+ reference "[MEF10.3] Section 8.6.2, [R26]. " +
+ "[MEF7.3] Section 12.2.2.";
+ }
+ leaf evc-performance-sls {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:slss/" +
+ "mef-global:sls/mef-global:sls-id";
+ }
+ description
+ "EVC: EVC-specific performance objectives and " +
+ "parameters. Note that an SLS can also specify " +
+ "performance objectives spanning more than one EVC. " +
+ "By default, all the UNI associated with the EVC " +
+ "have this SLS applied for them.";
+ reference "[MEF10.3] Section 8.8, Section 10. " +
+ "[MEF7.3] Section 12.2.2.";
+ }
+ leaf unicast-svc-frm-delivery {
+ type mef-types:data-svc-frame-delivery-type;
+ default "unconditional";
+ description
+ "EVC: Unicast Data Service Frame Delivery Mode " +
+ "(unconditional[default], conditional, or discard).";
+ reference "[MEF10.3] Section 8.5.2,[R16], [R17], " +
+ "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";
+ }
+ leaf multicast-svc-frm-delivery {
+ type mef-types:data-svc-frame-delivery-type;
+ default "unconditional";
+ description
+ "EVC: Multicast Data Service Frame Delivery Mode " +
+ "(unconditional[default], conditional, or discard).";
+ reference "[MEF10.3] Section 8.5.2, [R16], [R18], " +
+ "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";
+ }
+ leaf broadcast-svc-frm-delivery {
+ type mef-types:data-svc-frame-delivery-type;
+ default "unconditional";
+ description
+ "EVC: Broadcast Data Service Frame Delivery Mode " +
+ "(unconditional[default], conditional, or discard).";
+ reference "[MEF10.3] Section 8.5.2, [R16], [R19], " +
+ "Section 8.8, Section 11. [MEF7.3] Section 12.2.2.";
+ }
+ leaf evc-meg-id {
+ type mef-types:identifier45;
+ description
+ "EVC: Identifies the Maintenance Entity Group (MEG) " +
+ "for this EVC.";
+ reference "[MEF7.3] Section 12.2.2. MEF 35.1.";
+ }
+ leaf max-svc-frame-size {
+ type mef-types:max-svc-frame-size-type;
+ default "1600";
+ description
+ "EVC: This attribute describes the maximum service " +
+ "frame size for the EVC.";
+ reference "[MEF10.3] Section 8.9, Section 9.7, [R71], " +
+ "[MEF6.2] Section 8.2.2 and MEF 22.1: [D2]. " +
+ "[MEF7.3] Section 12.2.2.";
+ }
+ }
+ }
+ }
+ leaf svc-id {
+ type mef-types:retail-svc-id-type;
+ description
+ "The MEF Service ID is a simple key used to " +
+ "distinguish MEF Service Configuration Groups.";
+ reference "[MEF10.3] Section 7.";
+ }
+ leaf sp-id {
+ when "/mef-global:mef-global/mef-global:svc-providers" {
+ description
+ "Only configure when the Global Service Providers " +
+ "list has been populated.";
+ }
+ type leafref {
+ path "/mef-global:mef-global/mef-global:svc-providers/" +
+ "mef-global:svc-provider/mef-global:sp-id";
+ }
+ description
+ "The MEF Service Provider ID must be globally unique " +
+ "as all CENs and Subscribers must be supported by a " +
+ "specific Service Provider(SP). A SP can support " +
+ "multiple CENs.";
+ reference "[MEF10.3] Section 7.";
+ }
+ leaf svc-type {
+ type mef-types:mef-service-type;
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "svc-mux-enabled = 'true']) = 0))" {
+ error-message "For EPL, Service Multiplexing must be " +
+ "disabled for all UNIs in the EVC UNI List.";
+ description
+ "For EPL, Service Multiplexing must be disabled for " +
+ "all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "bundling-enabled = 'true']) = 0))" {
+ error-message "For EPL, Bundling must be disabled for " +
+ "all UNIs in the EVC UNI List.";
+ description
+ "For EPL, Bundling must be disabled for all UNIs in " +
+ "the EVC UNI List.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/" +
+ "mef-services:uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'false']) = 0))" {
+ error-message "For EPL, All-to-One Bundling must be " +
+ "enabled for all UNIs in the EVC UNI List.";
+ description
+ "For EPL, All-to-One Bundling must be enabled for " +
+ "all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "max-evc-count != 1]) = 0))" {
+ error-message "For EPL, Max EVC Count must be 1 for " +
+ "all UNIs in the EVC UNI List.";
+ description
+ "For EPL, Max EVC Count must be 1 for all UNIs " +
+ "in the EVC UNI List.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(../evc/unis/uni/egress-bwp-flows-per-eec/" +
+ "bwp-flow-per-eec) = 0))" {
+ error-message "For EPL, Egress Bandwidth Profile per " +
+ "Egress Equivalence Class cannot be set for " +
+ "all UNIs in the EVC per UNI List.";
+ description
+ "For EPL, Egress Bandwidth Profile per Egress " +
+ "Equivalence Class cannot be set for all UNIs in the " +
+ "EVC per UNI List.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(count(../evc/unis/uni" +
+ "[src-mac-addr-limit-enabled = 'true']) = 0) )" {
+ error-message "For EPL, Source MAC Address Limit must " +
+ "be disabled.";
+ description
+ "For EPL, Source MAC Address Limit must be disabled.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/evc-type = 'point-to-point'))" {
+ error-message "For EPL, EVC Type must be Point-to-Point.";
+ description
+ "For EPL, EVC Type must be Point-to-Point.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/unicast-svc-frm-delivery = " +
+ "'unconditional'))" {
+ error-message "For EPL, unicast-svc-frm-delivery " +
+ "must be unconditional.";
+ description
+ "For EPL, unicast-svc-frm-delivery must be " +
+ "unconditional.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/multicast-svc-frm-delivery = " +
+ "'unconditional'))" {
+ error-message "For EPL, multicast-svc-frm-delivery " +
+ "must be unconditional.";
+ description
+ "For EPL, multicast-svc-frm-delivery must be " +
+ "unconditional.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/broadcast-svc-frm-delivery = " +
+ "'unconditional'))" {
+ error-message "For EPL, broadcast-svc-frm-delivery " +
+ "must be unconditional.";
+ description
+ "For EPL, broadcast-svc-frm-delivery must be " +
+ "unconditional.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/preserve-ce-vlan-id = 'true'))" {
+ error-message "For EPL, CE-VLAN ID Preservation " +
+ "must be enabled.";
+ description
+ "For EPL, CE-VLAN ID Preservation must be enabled.";
+ }
+ must "(. != 'epl') or ((. = 'epl') and " +
+ "(../evc/cos-preserve-ce-vlan-id = 'true'))" {
+ error-message "For EPL, CE-VLAN ID CoS Preservation " +
+ "must be enabled.";
+ description
+ "For EPL, CE-VLAN ID CoS Preservation must be enabled.";
+ }
+ must "(. != 'evpl') or ((. = 'evpl') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'true']) = 0))" {
+ error-message "For EVPL, All-to-One Bundling must be " +
+ "disabled for all UNIs in the EVC UNI List.";
+ description
+ "For EVPL, All-to-One Bundling must be disabled for " +
+ "all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'evpl') or ((. = 'evpl') and " +
+ "((../evc/unicast-svc-frm-delivery != " +
+ "'unconditional') or " +
+ "(../evc/multicast-svc-frm-delivery != " +
+ "'unconditional') or " +
+ "(../evc/broadcast-svc-frm-delivery != " +
+ "'unconditional') or " +
+ "count(../evc/unis/uni" +
+ "[src-mac-addr-limit-enabled = 'true']) = 0))" {
+ error-message "For EVPL, Source MAC Address Limit must " +
+ "be disabled for all UNIs in the EVC per " +
+ "UNI List if all 3 -svc-frm-delivery values " +
+ "are unconditional.";
+ description
+ "For EVPL, Source MAC Address Limit must be disabled " +
+ "for all UNIs in the EVC per UNI List if all " +
+ "3 -svc-frm-delivery values are unconditional.";
+ }
+ must "(. != 'evpl') or ((. = 'evpl') and " +
+ "(../evc/evc-type = 'point-to-point'))" {
+ error-message "For EVPL, EVC Type must be Point-to-Point.";
+ description
+ "For EVPL, EVC Type must be Point-to-Point.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "svc-mux-enabled = 'true']) = 0))" {
+ error-message "For EP-LAN, Service Multiplexing must " +
+ "be disabled for all UNIs in the EVC UNI List.";
+ description
+ "For EP-LAN, Service Multiplexing must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "bundling-enabled = 'true']) = 0))" {
+ error-message "For EP-LAN, Bundling must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ description
+ "For EP-LAN, Bundling must be disabled for all UNIs " +
+ "in the EVC UNI List.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/" +
+ "mef-services:uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'false']) = 0))" {
+ error-message "For EP-LAN, All-to-One Bundling " +
+ "must be enabled for all UNIs in the " +
+ "EVC UNI List.";
+ description
+ "For EP-LAN, All-to-One Bundling must be enabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/" +
+ "mef-services:uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "max-evc-count != 1]) = 0))" {
+ error-message "For EP-LAN, Max EVC Count must be 1 " +
+ "for all UNIs in the EVC UNI List.";
+ description
+ "For EP-LAN, Max EVC Count must be 1 for all UNIs in " +
+ "the EVC UNI List.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(../evc/evc-type = 'multipoint-to-multipoint'))" {
+ error-message "For EP-LAN, EVC Type must be " +
+ "Multipoint-to-Multipoint.";
+ description
+ "For EP-LAN, EVC Type must be " +
+ "Multipoint-to-Multipoint.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(../evc/preserve-ce-vlan-id = 'true'))" {
+ error-message "For EP-LAN, CE-VLAN ID Preservation " +
+ "must be enabled.";
+ description
+ "For EP-LAN, CE-VLAN ID Preservation must be enabled.";
+ }
+ must "(. != 'eplan') or ((. = 'eplan') and " +
+ "(../evc/cos-preserve-ce-vlan-id = 'true'))" {
+ error-message "For EP-LAN, CE-VLAN ID CoS Preservation " +
+ "must be enabled.";
+ description
+ "For EP-LAN, CE-VLAN ID CoS Preservation must be " +
+ "enabled.";
+ }
+ must "(. != 'evplan') or ((. = 'evplan') and " +
+ "(../evc/evc-type = 'multipoint-to-multipoint'))" {
+ error-message "For EVP-LAN, EVC Type must be " +
+ "Multipoint-to-Multipoint.";
+ description
+ "For EVP-LAN, EVC Type must be " +
+ "Multipoint-to-Multipoint.";
+ }
+ must "(. != 'evplan') or ((. = 'evplan') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'true']) = 0))" {
+ error-message "For EVP-LAN, All-to-One Bundling must " +
+ "be disabled for all UNIs in the EVC UNI List.";
+ description
+ "For EVP-LAN, All-to-One Bundling must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "svc-mux-enabled = 'true']) = 0))" {
+ error-message "For EP-TREE, Service Multiplexing " +
+ "must be disabled for all UNIs in the " +
+ "EVC UNI List.";
+ description
+ "For EP-TREE, Service Multiplexing must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "bundling-enabled = 'true']) = 0))" {
+ error-message "For EP-TREE, Bundling must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ description
+ "For EP-TREE, Bundling must be disabled for all UNIs " +
+ "in the EVC UNI List.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/" +
+ "mef-services:uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'false']) = 0))" {
+ error-message "For EP-TREE, All-to-One Bundling must " +
+ "be enabled for all UNIs in the EVC UNI List.";
+ description
+ "For EP-TREE, All-to-One Bundling must be enabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/" +
+ "mef-services:uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "max-evc-count != 1]) = 0))" {
+ error-message "For EP-TREE, Max EVC Count must be 1 " +
+ "for all UNIs in the EVC UNI List.";
+ description
+ "For EP-TREE, Max EVC Count must be 1 for all UNIs " +
+ "in the EVC UNI List.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(../evc/evc-type = 'rooted-multipoint'))" {
+ error-message "For EP-TREE, EVC Type must be " +
+ "Rooted-Multipoint.";
+ description
+ "For EP-TREE, EVC Type must be Rooted-Multipoint.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(../evc/preserve-ce-vlan-id = 'true'))" {
+ error-message "For EP-TREE, CE-VLAN ID Preservation " +
+ "must be enabled.";
+ description
+ "For EP-TREE, CE-VLAN ID Preservation must be enabled.";
+ }
+ must "(. != 'eptree') or ((. = 'eptree') and " +
+ "(../evc/cos-preserve-ce-vlan-id = 'true'))" {
+ error-message "For EP-TREE, CE-VLAN ID " +
+ "CoS Preservation must be enabled.";
+ description
+ "For EP-TREE, CE-VLAN ID CoS Preservation must be " +
+ "enabled.";
+ }
+ must "(. != 'evptree') or ((. = 'evptree') and " +
+ "(count(/mef-interfaces:mef-interfaces/" +
+ "mef-interfaces:unis/mef-interfaces:uni" +
+ "[mef-interfaces:uni-id = current()/../" +
+ "mef-services:evc/mef-services:unis/mef-services:" +
+ "uni/mef-services:uni-id]" +
+ "[mef-interfaces:uni-id/../mef-interfaces:" +
+ "all-to-one-bundling-enabled = 'true']) = 0))" {
+ error-message "For EVP-TREE, All-to-One Bundling " +
+ "must be disabled for all UNIs in the EVC UNI List.";
+ description
+ "For EVP-TREE, All-to-One Bundling must be disabled " +
+ "for all UNIs in the EVC UNI List.";
+ }
+ must "(. != 'evptree') or ((. = 'evptree') and " +
+ "(../evc/evc-type = 'rooted-multipoint'))" {
+ error-message "For EVP-TREE, EVC Type must be " +
+ "Rooted-Multipoint.";
+ description
+ "For EVP-TREE, EVC Type must be Rooted-Multipoint.";
+ }
+ description
+ "The MEF Service Type.";
+ }
+ leaf user-label {
+ type mef-types:identifier45;
+ description
+ "This MEF user label is set by the user to a value " +
+ "that is easier to identify than the Service ID.";
+ }
+ leaf svc-entity {
+ type mef-types:service-entity-type;
+ default "evc";
+ description
+ "MEF Service Entity.";
+ reference "[MEF12.2] Table 3.";
+ }
+ leaf tenant-id {
+ type leafref {
+ path "/mef-global:mef-global/mef-global:tenants-instances/mef-global:tenant-list/mef-global:name";
+ }
+ }
+ }
+ }
+
+ augment "/mef-services:mef-services/mef-services:mef-service/mef-services:mef-service-choice/mef-services:evc-choice/mef-services:evc" {
+ ext:augment-identifier "evc-elan";
+ leaf elan-id {type string;}
+ list elan-ports {
+ key "port-id";
+ leaf port-id {type string;}
+ }
+ }
+
+ augment "/mef-services:mef-services/mef-services:mef-service/mef-services:mef-service-choice/mef-services:ipvc-choice/mef-services:ipvc" {
+ ext:augment-identifier "ipvc-vpn";
+ leaf vpn-id {type string;}
+ list vpn-elans {
+ key "uni-id ip-uni-id";
+ leaf uni-id {type mef-types:identifier45;}
+ leaf ip-uni-id {type mef-types:identifier45;}
+ leaf elan-id {type string;}
+ leaf elan-port {type string;}
+ list subnets {
+ key "subnet";
+ leaf subnet {type string;}
+ }
+ }
+ }
+}
<version>${vpnservices.version}</version>
</dependency>
<dependency>
- <groupId>${project.groupId}</groupId>
+ <groupId>org.opendaylight.unimgr</groupId>
<artifactId>unimgr-legato-api</artifactId>
<version>${project.version}</version>
</dependency>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
+
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.EvcUniCeVlans;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.EvcElan;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.EvcElanBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.ElanPorts;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.ElanPortsBuilder;
+
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
+import jline.internal.Log;
+
public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
private ListenerRegistration<EvcListener> evcListenerRegistration;
+ private final IUniPortManager uniPortManager;
- public EvcListener(final DataBroker dataBroker) {
+ public EvcListener(final DataBroker dataBroker, final UniPortManager uniPortManager) {
super(dataBroker);
-
+ this.uniPortManager = uniPortManager;
registerListener();
}
public void registerListener() {
try {
final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
- MefUtils.getEvcInstanceIdentifier());
+ MefServicesUtils.getEvcsInstanceIdentifier());
evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
log.info("EvcDataTreeChangeListener created and registered");
} catch (final Exception e) {
Evc data = newDataObject.getRootNode().getDataAfter();
String instanceName = data.getEvcId().getValue();
boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
- if (!data.isAdminStateEnabled()) {
- log.info("add - evc {} AdminStateEnabled false", data.getEvcId().getValue());
- } else {
- log.info("Adding {} instance: {}", isEtree ? "etree" : "elan", instanceName);
+ InstanceIdentifier<Evc> evcId = newDataObject.getRootPath().getRootIdentifier();
+
+ synchronized (instanceName.intern()) {
NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree);
- }
- // Create interfaces
- if (data.getUnis() == null) {
- log.info("No UNI's in service {}, exiting", instanceName);
- return;
- }
- for (Uni uni : data.getUnis().getUni()) {
- if (!uni.isAdminStateEnabled()) {
- log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
- } else {
- createInterface(instanceName, uni, isEtree);
+
+ // Create interfaces
+ if (data.getUnis() == null) {
+ log.info("No UNI's in service {}, exiting", instanceName);
+ return;
+ }
+ for (Uni uni : data.getUnis().getUni()) {
+ createUniElanInterfaces(evcId, instanceName, uni, isEtree);
}
}
} catch (final Exception e) {
}
}
+ private void removeEvc(DataTreeModification<Evc> removedDataObject) {
+ try {
+ Evc data = removedDataObject.getRootNode().getDataBefore();
+ InstanceIdentifier<Evc> evcId = removedDataObject.getRootPath().getRootIdentifier();
+ List<Uni> uniToRemove = data.getUnis() != null && data.getUnis().getUni() != null
+ ? data.getUnis().getUni() : Collections.emptyList();
+
+
+ synchronized (data.getEvcId().getValue().intern()) {
+ EvcElan evcElan = getOperEvcElan(evcId);
+ if (evcElan == null) {
+ log.error("Evc {} has not been created as required. Nothing to remove", data.getEvcId().getValue());
+ }
+
+ String instanceName = evcElan.getElanId();
+
+ for (Uni uni : uniToRemove) {
+ removeUniElanInterfaces(evcId, instanceName, uni);
+ }
+
+ log.info("Removing elan instance: " + instanceName);
+ NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
+ removeOperEvcElan(evcId);
+ }
+ } catch (final Exception e) {
+ log.error("Remove evc failed !", e);
+ }
+ }
+
private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
+ InstanceIdentifier<Evc> evcId = modifiedDataObject.getRootPath().getRootIdentifier();
+
try {
Evc original = modifiedDataObject.getRootNode().getDataBefore();
Evc update = modifiedDataObject.getRootNode().getDataAfter();
- String instanceName = original.getEvcId().getValue();
- boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
+ List<Uni> originalUni = original.getUnis() != null && original.getUnis().getUni() != null
+ ? original.getUnis().getUni() : Collections.emptyList();
+ List<Uni> updateUni = update.getUnis() != null && update.getUnis().getUni() != null
+ ? update.getUnis().getUni() : Collections.emptyList();
- if (!update.isAdminStateEnabled()) {
- log.info("update - evc {} AdminStateEnabled false", update.getEvcId().getValue());
- }
- log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
+ synchronized (original.getEvcId().getValue().intern()) {
- List<Uni> originalUni = original.getUnis() != null ? original.getUnis().getUni() : Collections.emptyList();
- if (update == null || update.getUnis() == null) {
- log.info("update uni is null");
- }
- List<Uni> updateUni = update.getUnis().getUni();
- if (updateUni != null && !updateUni.isEmpty()) {
- List<Uni> existingClonedUni = new ArrayList<>();
- if (originalUni != null && !originalUni.isEmpty()) {
- existingClonedUni.addAll(0, originalUni);
- originalUni.removeAll(updateUni);
- updateUni.removeAll(existingClonedUni);
- // removing the Uni which are not presented in the updated
- // List
- for (Uni uni : originalUni) {
- if (!uni.isAdminStateEnabled()) {
- log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
- } else {
- removeElanInterface(instanceName, uni);
- }
- }
- }
+ String instanceName = original.getEvcId().getValue();
+ boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
+ log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
- // Adding the new Uni which are presented in the updated List
- if (updateUni.size() > 0) {
- for (Uni uni : updateUni) {
- if (!uni.isAdminStateEnabled()) {
- log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
- } else {
- createInterface(instanceName, uni, isEtree);
- }
- }
+ // Changed Uni will be deleted / recreated
+ List<Uni> uniToRemove = new ArrayList<>(originalUni);
+ uniToRemove.removeAll(updateUni);
+ for (Uni uni : uniToRemove) {
+ removeUniElanInterfaces(evcId, instanceName, uni);
}
- } else if (originalUni != null && !originalUni.isEmpty()) {
- for (Uni uni : originalUni) {
- if (!uni.isAdminStateEnabled()) {
- log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
- } else {
- removeElanInterface(instanceName, uni);
- }
+
+ List<Uni> uniToCreate = new ArrayList<>(updateUni);
+ uniToCreate.removeAll(originalUni);
+ for (Uni uni : uniToCreate) {
+ createUniElanInterfaces(evcId, instanceName, uni, isEtree);
}
}
} catch (final Exception e) {
}
}
- private void removeEvc(DataTreeModification<Evc> removedDataObject) {
- try {
- Evc data = removedDataObject.getRootNode().getDataBefore();
- if (!data.isAdminStateEnabled()) {
- log.info("remove - evc {} AdminStateEnabled false", data.getEvcId().getValue());
- }
+ private void createUniElanInterfaces(InstanceIdentifier<Evc> evcId, String instanceName, Uni uni, boolean isEtree) {
+ EvcUniRoleType role = uni.getRole();
+ EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
- String instanceName = data.getEvcId().getValue();
+ List<EvcUniCeVlan> evcUniCeVlan = evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
+ && !evcUniCeVlans.getEvcUniCeVlan().isEmpty() ? evcUniCeVlans.getEvcUniCeVlan()
+ : Collections.emptyList();
- for (Uni uni : data.getUnis().getUni()) {
- if (!uni.isAdminStateEnabled()) {
- log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
- } else {
+ for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
+ Long vlan = safeCastVlan(ceVlan.getVid());
+ uniPortManager.addCeVlan(uni.getUniId().getValue(), vlan);
+ }
- removeElanInterface(instanceName, uni);
+ if (evcUniCeVlan.isEmpty()) {
+ String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), Long.valueOf(0));
+ if (isOperEvcElanPort(evcId, interfaceName)) {
+ log.info("elan interface for elan {} vlan {} interface {} exists already", instanceName, 0,
+ interfaceName);
+ return;
+ }
+ log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
+ NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
+ isEtree);
+ setOperEvcElanPort(evcId, instanceName, interfaceName);
+ } else {
+ for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
+ Long vlan = safeCastVlan(ceVlan.getVid());
+ String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), vlan);
+ if (isOperEvcElanPort(evcId, interfaceName)) {
+ log.info("elan interface for elan {} vlan {} interface {} exists already", instanceName, 0,
+ interfaceName);
+ return;
}
+ log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
+ NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
+ isEtree);
+ setOperEvcElanPort(evcId, instanceName, interfaceName);
}
-
- log.info("Removing elan instance: " + instanceName);
- NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
- } catch (final Exception e) {
- log.error("Remove evc failed !", e);
}
}
- private void createInterface(String instanceName, Uni uni, boolean isEtree) {
- EvcUniUtils.addUni(dataBroker, uni);
- String interfaceName = uni.getUniId().getValue();
- EvcUniRoleType role = uni.getRole();
+ private void removeUniElanInterfaces(InstanceIdentifier<Evc> evcId, String instanceName, Uni uni) {
EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
- if (evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
- && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
- for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
- interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
+ List<EvcUniCeVlan> evcUniCeVlan = evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
+ && !evcUniCeVlans.getEvcUniCeVlan().isEmpty() ? evcUniCeVlans.getEvcUniCeVlan()
+ : Collections.emptyList();
- NetvirtUtils.createInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role),
- isEtree);
+ for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
+ Long vlan = safeCastVlan(ceVlan.getVid());
+ uniPortManager.removeCeVlan(uni.getUniId().getValue(), vlan);
+ }
+
+ if (evcUniCeVlan.isEmpty()) {
+ String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), Long.valueOf(0));
+ if (!isOperEvcElanPort(evcId, interfaceName)) {
+ log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName, 0,
+ interfaceName);
+ return;
}
+ removeElanInterface(evcId, interfaceName);
} else {
- NetvirtUtils.createInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role), isEtree);
+ for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
+ Long vlan = safeCastVlan(ceVlan.getVid());
+ String interfaceName = uniPortManager.getUniVlanInterface(uni.getUniId().getValue(), vlan);
+ if (!isOperEvcElanPort(evcId, interfaceName)) {
+ log.info("elan interface for elan {} vlan {} is not operational, nothing to remove", instanceName,
+ vlan, interfaceName);
+ return;
+ }
+ removeElanInterface(evcId, interfaceName);
+ }
}
}
- private static EtreeInterfaceType RoleToInterfaceType(EvcUniRoleType role) {
+ private void removeElanInterface(InstanceIdentifier<Evc> identifier, String interfaceName) {
+ log.info("Removing elan interface: " + interfaceName);
+ NetvirtUtils.deleteElanInterface(dataBroker, interfaceName);
+
+ EvcElan evcElan = getOperEvcElan(identifier);
+ if (evcElan == null) {
+ log.error("Removing non-operational Elan interface {}", interfaceName);
+ }
+ deleteOperEvcElanPort(identifier, interfaceName);
+ }
+
+ // Expected from API is Long
+ private Long safeCastVlan(Object vid) {
+ if (!(vid instanceof Long)) {
+ String errorMessage = String.format("vlan id %s cannot be cast to Long", vid);
+ log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
+ return (Long) vid;
+ }
+
+ private static EtreeInterfaceType roleToInterfaceType(EvcUniRoleType role) {
if (role == EvcUniRoleType.Root) {
return EtreeInterfaceType.Root;
} else {
}
}
- private void removeElanInterface(String instanceName, Uni uni) {
- EvcUniUtils.removeUni(dataBroker, uni);
+ private EvcElan getOperEvcElan(InstanceIdentifier<Evc> identifier) {
+ InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
+ Optional<EvcElan> evcElan = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+ if (evcElan.isPresent()) {
+ return evcElan.get();
+ } else {
+ return null;
+ }
+ }
- String uniId = uni.getUniId().getValue();
- EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
- String interfaceName = uniId;
+ private void removeOperEvcElan(InstanceIdentifier<Evc> identifier) {
+ InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
+ MdsalUtils.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+ }
+
+ private boolean isOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanPort) {
+ EvcElan evcElan = getOperEvcElan(identifier);
+ if (evcElan == null || evcElan.getElanPorts() == null) {
+ return false;
+ }
+ List<ElanPorts> exPorts = evcElan.getElanPorts();
+ return exPorts.stream().anyMatch(p -> p.getPortId().equals(elanPort));
+ }
- if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
- for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
+ private void setOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanName, String elanPort) {
+ InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
+ EvcElan evcElan = getOperEvcElan(identifier);
+ EvcElanBuilder evcElanBuilder = evcElan != null ? new EvcElanBuilder(evcElan) : new EvcElanBuilder();
+ List<ElanPorts> exPorts = evcElan != null && evcElan.getElanPorts() != null ? evcElan.getElanPorts() : new ArrayList<>();
+
+ ElanPortsBuilder portB = new ElanPortsBuilder();
+ portB.setPortId(elanPort);
+ exPorts.add(portB.build());
+ evcElanBuilder.setElanId(elanName);
+ evcElanBuilder.setElanPorts(exPorts);
+ MdsalUtils.write(dataBroker, LogicalDatastoreType.OPERATIONAL, path, evcElanBuilder.build());
+ }
- interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
- log.info("Removing elan interface: " + interfaceName);
- NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
- }
+ private void deleteOperEvcElanPort(InstanceIdentifier<Evc> identifier, String elanPort) {
+ InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
+ EvcElan evcElan = getOperEvcElan(identifier);
+ EvcElanBuilder evcElanBuilder = null;
+ List<ElanPorts> exPorts = Collections.emptyList();
+ if (evcElan != null) {
+ evcElanBuilder = new EvcElanBuilder(evcElan);
+ exPorts = evcElan.getElanPorts() != null ? evcElan.getElanPorts() : Collections.emptyList();
} else {
- log.info("Removing elan interface: " + uniId);
- NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
+ Log.error("Deleting non-operational Elan port {}", elanPort);
+ return;
}
+ List<ElanPorts> newList = exPorts.stream().filter(p -> !p.getPortId().equals(elanPort))
+ .collect(Collectors.toList());
+ evcElanBuilder.setElanPorts(newList);
+ MdsalUtils.write(dataBroker, LogicalDatastoreType.OPERATIONAL, path, evcElanBuilder.build());
}
+
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.unimgr.mef.netvirt;
-
-import java.util.List;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayers;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.Links;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.EvcUniCeVlans;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-
-public class EvcUniUtils {
-
- private static final Logger logger = LoggerFactory.getLogger(EvcUniUtils.class);
-
- public static Link getLink(DataBroker dataBroker, String uniId) {
- Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni> optional = MdsalUtils
- .read(dataBroker, LogicalDatastoreType.CONFIGURATION, MefUtils.getUniInstanceIdentifier(uniId));
-
- if (!optional.isPresent()) {
- logger.error("A matching Uni doesn't exist for EvcUni {}", uniId);
- return null;
- }
-
- org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = optional
- .get();
-
- PhysicalLayers physicalLayers = uni.getPhysicalLayers();
- if (physicalLayers == null) {
- logger.warn("Uni {} is missing PhysicalLayers", uniId);
- return null;
- }
-
- Links links = physicalLayers.getLinks();
- if (links == null || links.getLink() == null) {
- logger.warn("Uni {} is has no links", uniId);
- return null;
- }
-
- Link link = links.getLink().get(0);
- return link;
- }
-
- public static void removeUni(DataBroker dataBroker, Uni data) {
- try {
- String uniId = data.getUniId().getValue();
- WriteTransaction tx = createTransaction(dataBroker);
-
- logger.info("Removing trunk {}", uniId);
-
- NetvirtUtils.delete(uniId, tx);
-
- Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
- if (!ceVlansOptional.isPresent()) {
- return;
- }
-
- removeTrunkMemberInterfaces(uniId, ceVlansOptional.get(), tx);
- commitTransaction(tx);
- } catch (final Exception e) {
- logger.error("Remove uni failed !", e);
- }
- }
-
- public static void addUni(DataBroker dataBroker, Uni data) {
- try {
- String uniId = data.getUniId().getValue();
- WriteTransaction tx = createTransaction(dataBroker);
- Link link = EvcUniUtils.getLink(dataBroker, uniId);
- String interfaceName = uniId;
- addTrunkInterface(interfaceName, MefUtils.getTrunkParentName(link), tx);
-
- Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
- if (ceVlansOptional.isPresent()) {
- addTrunkMemberInterfaces(interfaceName, ceVlansOptional.get(), tx);
- }
-
- commitTransaction(tx);
- } catch (final Exception e) {
- logger.error("Add uni failed !", e);
- }
- }
-
- private static void addTrunkInterface(String interfaceName, String parentInterfaceName, WriteTransaction tx) {
- logger.info("Adding VLAN trunk {} ParentRef {}", interfaceName, parentInterfaceName);
- Interface trunkInterface = NetvirtUtils.createTrunkInterface(interfaceName, parentInterfaceName);
- NetvirtUtils.write(trunkInterface, tx);
- }
-
- private static void addTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
- WriteTransaction tx) {
- for (EvcUniCeVlan ceVlan : ceVlans) {
- Object vid = ceVlan.getVid();
- if (!(vid instanceof Long)) {
- String errorMessage = String.format("vlan id {} cannot be cast to Long", vid);
- logger.error(errorMessage);
- throw new UnsupportedOperationException(errorMessage);
- }
-
- Long vlanId = (Long) vid;
- String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
- logger.info("Adding VLAN trunk-member {} ParentRef {}", interfaceName, parentInterfaceName);
- Interface trunkMemberInterface = NetvirtUtils.createTrunkMemberInterface(interfaceName, parentInterfaceName,
- vlanId.intValue());
- NetvirtUtils.write(trunkMemberInterface, tx);
- }
- }
-
- private static void removeTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
- WriteTransaction tx) {
- for (EvcUniCeVlan ceVlan : ceVlans) {
- Object vid = ceVlan.getVid();
- if (!(vid instanceof Long)) {
- String errorMessage = String.format("vlan id {} cannot be cast to Long", vid);
- logger.error(errorMessage);
- throw new UnsupportedOperationException(errorMessage);
- }
-
- Long vlanId = (Long) vid;
- String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
- logger.info("Removing VLAN trunk-member {}", interfaceName);
- NetvirtUtils.delete(interfaceName, tx);
- }
- }
-
- private static WriteTransaction createTransaction(DataBroker dataBroker) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- return tx;
- }
-
- private static void commitTransaction(WriteTransaction tx) {
- try {
- CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
- futures.get();
- } catch (Exception e) {
- logger.error("failed to commit transaction due to exception ", e);
- }
- }
-
- private static Optional<List<EvcUniCeVlan>> getCeVlans(Uni uni) {
- EvcUniCeVlans ceVlans = uni.getEvcUniCeVlans();
- if (ceVlans == null) {
- return Optional.absent();
- }
-
- return Optional.fromNullable(ceVlans.getEvcUniCeVlan());
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GwMacListener extends UnimgrDataTreeChangeListener<VpnPortipToPort> implements IGwMacListener {
+ private static final Logger Log = LoggerFactory.getLogger(GwMacListener.class);
+ private ListenerRegistration<GwMacListener> gwMacListenerRegistration;
+ private final OdlArputilService arpUtilService;
+ private final ExecutorService retriesHandler;
+ private final Short sleepInterval;
+
+ private final ConcurrentHashMap<GwMacKey, GwMacValue> gwMacResolver;
+
+ public GwMacListener(final DataBroker dataBroker, final OdlArputilService arputilService, Short sleepInterval) {
+ super(dataBroker);
+ this.arpUtilService = arputilService;
+ this.gwMacResolver = new ConcurrentHashMap<>();
+ this.sleepInterval = sleepInterval;
+ retriesHandler = Executors.newSingleThreadExecutor();
+ registerListener();
+ }
+
+ public void registerListener() {
+ try {
+ final DataTreeIdentifier<VpnPortipToPort> dataTreeIid = new DataTreeIdentifier<>(
+ LogicalDatastoreType.OPERATIONAL, NetvirtVpnUtils.getVpnPortipToPortIdentifier());
+ gwMacListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+ startRetriesThread();
+ Log.info("GwMacListener created and registered");
+ } catch (final Exception e) {
+ Log.error("GwMacListener listener registration failed !", e);
+ throw new IllegalStateException("GwMacListener Listener failed.", e);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ gwMacListenerRegistration.close();
+ retriesHandler.shutdown();
+ if (!retriesHandler.awaitTermination(10, TimeUnit.SECONDS)) {
+ retriesHandler.shutdownNow();
+ }
+ }
+
+ @Override
+ public void add(DataTreeModification<VpnPortipToPort> newDataObject) {
+ if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+ VpnPortipToPort portIpToPort = newDataObject.getRootNode().getDataAfter();
+ updateMac(portIpToPort);
+ }
+ }
+
+ @Override
+ public void remove(DataTreeModification<VpnPortipToPort> removedDataObject) {
+ }
+
+ @Override
+ public void update(DataTreeModification<VpnPortipToPort> modifiedDataObject) {
+ if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+ VpnPortipToPort portIpToPort = modifiedDataObject.getRootNode().getDataAfter();
+ updateMac(portIpToPort);
+ }
+ }
+
+ private void updateMac(VpnPortipToPort portIpToPort) {
+ String portName = portIpToPort.getPortName();
+ String macAddress = portIpToPort.getMacAddress();
+ String vpnName = portIpToPort.getVpnName();
+ String ipAddress = portIpToPort.getPortFixedip();
+ GwMacKey gwMacKey = new GwMacKey(vpnName, portName, ipAddress);
+
+ if (!gwMacResolver.containsKey(gwMacKey)) {
+ Log.debug("Ignoring MAC update for vpn {} port {} ip {}", vpnName, portName, ipAddress);
+ return;
+ }
+
+ if (macAddress != null && vpnName != null) {
+ Log.trace("Updating vpn {} port {} with IP {} MAC {}", vpnName, portName, ipAddress, macAddress);
+ }
+
+ if (gwMacResolver.get(gwMacKey).getGwMac() == null || !gwMacResolver.get(gwMacKey).getGwMac().equals(macAddress)) {
+ Log.info("Creating GW for vpn {} port {} ip {} MAC {}", vpnName, portName, ipAddress, macAddress);
+ NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, portName, gwMacResolver.get(gwMacKey).getSubnet(), macAddress,
+ false, gwMacResolver.get(gwMacKey).getPortIp());
+
+ gwMacResolver.get(gwMacKey).setGwMac(macAddress);
+ }
+ }
+
+ @Override
+ public void resolveGwMac(String vpnName, String portName, IpAddress srcIpAddress, IpAddress dstIpAddress, String subnet) {
+ String dstIpAddressStr = NetvirtVpnUtils.ipAddressToString(dstIpAddress);
+ GwMacKey gwMacKey = new GwMacKey(vpnName, portName, dstIpAddressStr);
+
+ if (!gwMacResolver.containsKey(gwMacKey)) {
+ // check if IP was resolved already
+ gwMacResolver.putIfAbsent(gwMacKey, new GwMacValue(NetvirtVpnUtils.ipAddressToString(srcIpAddress), subnet));
+ VpnPortipToPort portIpToPort = NetvirtVpnUtils.getVpnPortFixedIp(dataBroker, vpnName, dstIpAddressStr);
+ if (portIpToPort != null) {
+ updateMac(portIpToPort);
+ }
+
+ Log.info("Starting GW mac resolution for vpn {} port {} GW ip {}", vpnName, portName, dstIpAddress);
+ NetvirtVpnUtils.sendArpRequest(arpUtilService, srcIpAddress, dstIpAddress, portName);
+ }
+ }
+
+ @Override
+ public void unResolveGwMac(String vpnName, String portName, IpAddress srcIpAddress, IpAddress dstIpAddress) {
+ String dstIpAddressStr = NetvirtVpnUtils.ipAddressToString(dstIpAddress);
+ GwMacKey gwMacKey = new GwMacKey(vpnName, portName, dstIpAddressStr);
+ if (gwMacResolver.containsKey(gwMacKey)) {
+ Log.info("Stopping GW mac resolution for vpn {} port {} GW ip {}", vpnName, portName, dstIpAddress);
+ gwMacResolver.remove(gwMacKey);
+ }
+ }
+
+ private void resolveRetry() {
+ gwMacResolver.forEach((k, v) -> {
+ if (v.getGwMac() == null) {
+ IpAddress dstIpAddress = new IpAddress(k.gwIp.toCharArray());
+ IpAddress srcIpAddress = new IpAddress(v.portIp.toCharArray());
+ Log.debug("Resending ARP for IP {} port {}", dstIpAddress, k.getGwIp());
+
+ NetvirtVpnUtils.sendArpRequest(arpUtilService, srcIpAddress, dstIpAddress, k.portId);
+ }
+ });
+ }
+
+ void startRetriesThread() {
+ retriesHandler.submit(() -> {
+ Thread t = Thread.currentThread();
+ t.setName("ResolveSubnetGW");
+ Log.info("ResolveSubnetGW: started {}", t.getName());
+ while (true) {
+ NetvirtUtils.safeSleep(sleepInterval);
+ resolveRetry();
+ }
+ });
+ Log.debug("Subnet GW Arp Retries");
+ }
+
+ public static class GwMacKey {
+ private final String vpId;
+ private final String portId;
+ private final String gwIp;
+
+ public GwMacKey(String vpId, String portId, String gwIp) {
+ this.vpId = vpId;
+ this.portId = portId;
+ this.gwIp = gwIp;
+ }
+
+ public String getGwIp() {
+ return gwIp;
+ }
+
+ public String getVpId() {
+ return vpId;
+ }
+
+ public String getPortId() {
+ return portId;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (gwIp == null ? 0 : gwIp.hashCode());
+ result = prime * result + (portId == null ? 0 : portId.hashCode());
+ result = prime * result + (vpId == null ? 0 : vpId.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ GwMacKey other = (GwMacKey) obj;
+ if (gwIp == null) {
+ if (other.gwIp != null) {
+ return false;
+ }
+ } else if (!gwIp.equals(other.gwIp)) {
+ return false;
+ }
+ if (portId == null) {
+ if (other.portId != null) {
+ return false;
+ }
+ } else if (!portId.equals(other.portId)) {
+ return false;
+ }
+ if (vpId == null) {
+ if (other.vpId != null) {
+ return false;
+ }
+ } else if (!vpId.equals(other.vpId)) {
+ return false;
+ }
+ return true;
+ }
+
+
+ }
+
+ public static class GwMacValue {
+ String portIp;
+ String subnet;
+ String gwMac;
+
+ public GwMacValue(String portIp, String subnet) {
+ this.portIp = portIp;
+ this.subnet = subnet;
+ }
+
+ public String getGwMac() {
+ return gwMac;
+ }
+
+ public void setGwMac(String gwMac) {
+ this.gwMac = gwMac;
+ }
+
+ public String getPortIp() {
+ return portIp;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+
+public interface IGwMacListener {
+ // IpPrefix srcIpPrefix, IpAddress dstIpAddress, String interf
+ public void resolveGwMac (String vpnName, String portName, IpAddress srcIpAddress, IpAddress dstIpAddress, String subnet);
+
+ public void unResolveGwMac (String vpnName, String portName, IpAddress srcIpAddress, IpAddress dstIpAddress);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface ISubnetManager {
+ public void assignIpUniNetworks(Identifier45 uniId, Identifier45 ipUniId, InstanceIdentifier<Ipvc> ipvcId);
+
+ public void unAssignIpUniNetworks(Identifier45 uniId, Identifier45 ipUniId, InstanceIdentifier<Ipvc> ipvcId);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import java.util.List;
+
+public interface IUniPortManager {
+
+ void updateOperUni(String uniId);
+
+ void removeUniPorts(String uniId);
+
+ void addCeVlan(String uniId, Long vlanId);
+
+ void removeCeVlan(String uniId, Long vlanId);
+
+ List<String> getUniVlanInterfaces(String uniId);
+
+ String getUniVlanInterface(String uniId, Long vlanId);
+
+}
package org.opendaylight.unimgr.mef.netvirt;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.SubnetBuilder;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.ip.uni.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpn;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
+ private final IUniPortManager uniPortManager;
+ private final ISubnetManager subnetManager;
private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
- private final NotificationPublishService notificationPublishService;
- private final OdlArputilService arpUtilService;
- public IpvcListener(final DataBroker dataBroker, final NotificationPublishService notPublishService,
- final OdlArputilService arputilService) {
+ public IpvcListener(final DataBroker dataBroker, final IUniPortManager uniPortManager,
+ final ISubnetManager subnetManager) {
super(dataBroker);
- this.notificationPublishService = notPublishService;
- this.arpUtilService = arputilService;
+ this.uniPortManager = uniPortManager;
+ this.subnetManager = subnetManager;
+
registerListener();
}
public void registerListener() {
try {
final DataTreeIdentifier<Ipvc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
- MefUtils.getIpvcInstanceIdentifier());
+ MefServicesUtils.getIpvcsInstanceIdentifier());
ipvcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
Log.info("IpvcDataTreeChangeListener created and registered");
} catch (final Exception e) {
private void addIpvc(DataTreeModification<Ipvc> newDataObject) {
try {
- Ipvc data = newDataObject.getRootNode().getDataAfter();
- String instanceName = data.getIpvcId().getValue();
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ Ipvc ipvc = newDataObject.getRootNode().getDataAfter();
+ String instanceName = ipvc.getIpvcId().getValue();
final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
+ InstanceIdentifier<Ipvc> ipvcId = newDataObject.getRootPath().getRootIdentifier();
+ List<Uni> unis = new ArrayList<>();
+ synchronized (vpnName.intern()) {
+ Log.info("Adding vpn instance: " + instanceName);
+ NetvirtVpnUtils.createVpnInstance(vpnName, tx);
+ MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, tx);
+ if (ipvc.getUnis() != null && ipvc.getUnis() != null) {
+ unis = ipvc.getUnis().getUni();
+ }
+ Log.info("Number of UNI's: " + unis.size());
- Log.info("Adding vpn instance: " + instanceName);
- NetvirtVpnUtils.createVpnInstance(dataBroker, vpnName);
- Log.info("Number of UNI's: " + data.getUnis().getUni().size());
-
-
- // Create elan interfaces
- for (Uni uni : data.getUnis().getUni()) {
- createInterfaces(vpnName, uni);
+ // Create elan/vpn interfaces
+ for (Uni uni : unis) {
+ createInterfaces(vpnName, uni, ipvcId, tx);
+ }
+ MdsalUtils.commitTransaction(tx);
+ }
+ for (Uni uni : unis) {
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
+ LogicalDatastoreType.CONFIGURATION);
+ createDirectSubnet(uni, ipUni);
+ subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
}
} catch (final Exception e) {
Log.error("Add ipvc failed !", e);
}
}
- private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
+ private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
try {
- Ipvc original = modifiedDataObject.getRootNode().getDataBefore();
- Ipvc update = modifiedDataObject.getRootNode().getDataAfter();
+ Ipvc ipvc = removedDataObject.getRootNode().getDataBefore();
+ InstanceIdentifier<Ipvc> ipvcId = removedDataObject.getRootPath().getRootIdentifier();
+ IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+ if (operIpvcVpn == null) {
+ Log.error("Ipvc {} hasn't been created as required", ipvc.getIpvcId());
+ return;
+ }
+ String vpnName = operIpvcVpn.getVpnId();
+
+ synchronized (vpnName.intern()) {
+ // remove elan/vpn interfaces
+ // must be in different transactios
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ removeUni(ipvcId, operIpvcVpn, ipvc.getUnis().getUni(), tx);
+ MdsalUtils.commitTransaction(tx);
+ // Let to work for listeners
+ // TODO : change to listener
+ NetvirtUtils.safeSleep();
+
+ WriteTransaction txvpn = MdsalUtils.createTransaction(dataBroker);
+ NetvirtVpnUtils.removeVpnInstance(operIpvcVpn.getVpnId(), txvpn);
+ MefServicesUtils.removeOperIpvcVpn(ipvcId, txvpn);
+ MdsalUtils.commitTransaction(txvpn);
+ }
+ } catch (final Exception e) {
+ Log.error("Remove ipvc failed !", e);
+ }
+ }
- String instanceName = original.getIpvcId().getValue();
- final String vpnName = NetvirtVpnUtils.getUUidFromString(instanceName);
+ private void removeUni(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove,
+ WriteTransaction tx) {
+ if (uniToRemove == null) {
+ Log.trace("No UNI's to remove");
+ }
+ for (Uni uni : uniToRemove) {
+ Identifier45 uniId = uni.getUniId();
+ Identifier45 ipUniId = uni.getIpUniId();
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uniId, ipUniId, LogicalDatastoreType.CONFIGURATION);
+ if (ipUni == null) {
+ String errorMessage = String.format("Couldn't find ipuni %s for uni %s", ipUniId, uniId);
+ Log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
- Log.info("Updating elan instance: " + instanceName);
+ removeDirectSubnet(uni, ipUni);
+ subnetManager.unAssignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
+ removeInterfaces(ipvcId, operIpvcVpn, uni, ipUni, tx);
+ }
+ }
- if (original == null || original.getUnis() == null || original.getUnis().getUni() == null) {
- addIpvc(modifiedDataObject);
+ private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
+ try {
+ Ipvc origIpvc = modifiedDataObject.getRootNode().getDataBefore();
+ Ipvc updateIpvc = modifiedDataObject.getRootNode().getDataAfter();
+ InstanceIdentifier<Ipvc> ipvcId = modifiedDataObject.getRootPath().getRootIdentifier();
+ IpvcVpn operIpvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+ if (operIpvcVpn == null) {
+ Log.error("Ipvc {} hasn't been created as required", origIpvc.getIpvcId());
return;
}
-
- List<Uni> originalUni = original.getUnis().getUni();
- List<Uni> updateUni = update.getUnis().getUni();
- if (updateUni != null && !updateUni.isEmpty()) {
- List<Uni> existingClonedUni = new ArrayList<>();
- if (originalUni != null && !originalUni.isEmpty()) {
- existingClonedUni.addAll(0, originalUni);
- originalUni.removeAll(updateUni);
- updateUni.removeAll(existingClonedUni);
- // removing the Uni which are not presented in the updated
- // List
- for (Uni uni : originalUni) {
- removeElanInterface(vpnName, uni);
- }
+ String vpnName = operIpvcVpn.getVpnId();
+
+ List<Uni> originalUni = origIpvc.getUnis() != null && origIpvc.getUnis().getUni() != null
+ ? origIpvc.getUnis().getUni() : Collections.emptyList();
+ List<Uni> updateUni = updateIpvc.getUnis() != null && updateIpvc.getUnis().getUni() != null
+ ? updateIpvc.getUnis().getUni() : Collections.emptyList();
+
+ synchronized (vpnName.intern()) {
+ WriteTransaction txRemove = MdsalUtils.createTransaction(dataBroker);
+ List<Uni> uniToRemove = new ArrayList<>(originalUni);
+ uniToRemove.removeAll(updateUni);
+ removeUni(ipvcId, operIpvcVpn, uniToRemove, txRemove);
+ MdsalUtils.commitTransaction(txRemove);
+
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ List<Uni> uniToCreate = new ArrayList<>(updateUni);
+ uniToCreate.removeAll(originalUni);
+ for (Uni uni : uniToCreate) {
+ createInterfaces(vpnName, uni, ipvcId, tx);
}
+ MdsalUtils.commitTransaction(tx);
- // Adding the new Uni which are presented in the updated List
- if (updateUni.size() > 0) {
- for (Uni uni : updateUni) {
- createInterfaces(vpnName, uni);
- }
- }
- } else if (originalUni != null && !originalUni.isEmpty()) {
- for (Uni uni : originalUni) {
- removeElanInterface(vpnName, uni);
+ for (Uni uni : uniToCreate) {
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
+ LogicalDatastoreType.CONFIGURATION);
+ createDirectSubnet(uni, ipUni);
+ subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
}
}
+
} catch (final Exception e) {
Log.error("Update ipvc failed !", e);
}
}
- private void removeIpvc(DataTreeModification<Ipvc> removedDataObject) {
- try {
- Ipvc data = removedDataObject.getRootNode().getDataBefore();
+ private void createInterfaces(String vpnName, Uni uniInService, InstanceIdentifier<Ipvc> ipvcId,
+ WriteTransaction tx) {
+ String uniId = uniInService.getUniId().getValue();
+ String ipUniId = uniInService.getIpUniId().getValue();
+ org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = MefInterfaceUtils
+ .getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
+ if (uni == null) {
+ String errorMessage = String.format("Couldn't find uni %s for ipvc", uniId);
+ Log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uniInService.getUniId(), uniInService.getIpUniId(),
+ LogicalDatastoreType.CONFIGURATION);
+ if (ipUni == null) {
+ String errorMessage = String.format("Couldn't find ipuni %s for uni %s", ipUniId, uniId);
+ Log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
- String instanceName = data.getIpvcId().getValue();
+ Long vlan = ipUni.getVlan() != null ? Long.valueOf(ipUni.getVlan().getValue()) : null;
+ String elanName = NetvirtVpnUtils.getElanNameForVpnPort(uniId);
+ String interfaceName = createElanInterface(vpnName, ipvcId, uniId, elanName, vlan, tx);
+ createVpnInterface(vpnName, uni, ipUni, interfaceName, tx);
+ MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, uniInService.getUniId(), uniInService.getIpUniId(),
+ elanName, interfaceName, null, tx);
+ }
- for (Uni uni : data.getUnis().getUni()) {
- removeElanInterface(instanceName, uni);
- }
+ private String createElanInterface(String vpnName, InstanceIdentifier<Ipvc> ipvcId, String uniId, String elanName,
+ Long vlan, WriteTransaction tx) {
+ Log.info("Adding elan instance: " + elanName);
+ NetvirtUtils.updateElanInstance(elanName, tx);
- Log.info("Removing elan instance: " + instanceName);
- NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
- } catch (final Exception e) {
- Log.error("Remove ipvc failed !", e);
+ Log.info("Added trunk interface for uni {} vlan: {}", uniId, vlan);
+ if (vlan != null) {
+ uniPortManager.addCeVlan(uniId, vlan);
}
+ String interfaceName = uniPortManager.getUniVlanInterface(uniId, vlan);
+ if (interfaceName == null) {
+ String errorMessage = String.format("Couldn't create uni %s vlan interface %s", uniId, vlan);
+ Log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
+
+ Log.info("Adding elan interface: " + interfaceName);
+ NetvirtUtils.createElanInterface(elanName, interfaceName, EtreeInterfaceType.Root, false, tx);
+ return interfaceName;
+ }
+
+ private void createVpnInterface(String vpnName,
+ org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni,
+ IpUni ipUni, String interfaceName, WriteTransaction tx) {
+
+ Log.info("Adding vpn interface: " + interfaceName);
+ NetvirtVpnUtils.createUpdateVpnInterface(vpnName, interfaceName, ipUni.getIpAddress(),
+ uni.getMacAddress().getValue(), true, null, tx);
+ NetvirtVpnUtils.createVpnPortFixedIp(vpnName, interfaceName, ipUni.getIpAddress(), uni.getMacAddress(), tx);
+ Log.info("Finished working on vpn instance: " + vpnName);
}
- private void createInterfaces(Ipvc ipvc, Uni uni) {
- String instanceName = ipvc.getIpvcId().getValue();
- createInterfaces(instanceName, uni);
+ private void createDirectSubnet(Uni uni, IpUni ipUni) {
+ IpPrefix uniIpPrefix = ipUni.getIpAddress();
+ String subnetIp = NetvirtVpnUtils.getSubnetFromPrefix(uniIpPrefix);
+ IpPrefix subnetPrefix = new IpPrefix(new Ipv4Prefix(subnetIp));
+ InstanceIdentifier<Subnet> path = MefInterfaceUtils.getSubnetInstanceIdentifier(uni.getUniId(),
+ ipUni.getIpUniId(), subnetPrefix);
+ SubnetBuilder subnet = new SubnetBuilder();
+ subnet.setUniId(uni.getUniId());
+ subnet.setIpUniId(ipUni.getIpUniId());
+ subnet.setSubnet(subnetPrefix);
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, subnet.build());
}
- private void createInterfaces(String vpnName, Uni uniInService) {
+ private void removeInterfaces(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn ipvcVpn, Uni uniInService, IpUni ipUni,
+ WriteTransaction tx) {
String uniId = uniInService.getUniId().getValue();
- String ipUniId = uniInService.getIpUniId().getValue();
+ org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = MefInterfaceUtils
+ .getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
+ if (uni == null) {
+ String errorMessage = String.format("Couldn't find uni %s for ipvc", uniId);
+ Log.error(errorMessage);
+ throw new UnsupportedOperationException(errorMessage);
+ }
- Log.info("Adding/updating elan instance: " + uniId);
+ String vpnName = ipvcVpn.getVpnId();
- org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = IpvcUniUtils
- .getUni(dataBroker, uniId);
- if (uni == null) {
- Log.error("Couldn't find uni {} for ipvc-uni", uniId);
- throw new UnsupportedOperationException();
+ VpnElans vpnElans = MefServicesUtils.findVpnElanForNetwork(new Identifier45(uniId), ipUni.getIpUniId(),
+ ipvcVpn);
+ if (vpnElans == null) {
+ Log.error("Trying to remome non-operational vpn/elan for Uni {} Ip-UNi {}", uniId, ipUni.getIpUniId());
}
- IpUni ipUni = IpvcUniUtils.getIpUni(dataBroker, uniId, ipUniId);
- Integer vlan = ipUni.getVlan() != null ? ipUni.getVlan().getValue() : null;
- String elanName = NetvirtVpnUtils.getElanNameForVpnPort(uniId);
- Log.info("Adding elan instance: " + elanName);
- NetvirtUtils.updateElanInstance(dataBroker, elanName);
+ NetvirtVpnUtils.removeVpnInterfaceAdjacencies(dataBroker, vpnName, vpnElans.getElanPort());
+ // TODO : change to listener
+ NetvirtUtils.safeSleep();
+ removeElan(vpnElans, uniId, ipUni, tx);
+ removeVpnInterface(vpnName, vpnElans, uniId, ipUni, tx);
+ MefServicesUtils.removeOperIpvcElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), uniInService.getUniId(),
+ uniInService.getIpUniId(), vpnElans.getElanId(), vpnElans.getElanPort());
+ }
- String interfaceName = NetvirtVpnUtils.getInterfaceNameForVlan(ipUniId, vlan);
- Log.info("Adding trunk interface: " + interfaceName);
- IpvcUniUtils.addUni(dataBroker, uniInService, interfaceName, vlan);
+ private void removeElan(VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
+ Long vlan = ipUni.getVlan() != null ? Long.valueOf(ipUni.getVlan().getValue()) : 0;
+ Log.info("Removing trunk interface for uni {} vlan: {}", uniId, vlan);
+ uniPortManager.removeCeVlan(uniId, vlan);
- Log.info("Adding elan interface: " + interfaceName);
- NetvirtUtils.createInterface(dataBroker, elanName, interfaceName, EtreeInterfaceType.Root, false);
+ String elanName = vpnElans.getElanId();
+ String interfaceName = vpnElans.getElanPort();
- Log.info("Adding vpn interface: " + interfaceName);
- NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
- uni.getMacAddress(), true, null);
- NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
- uni.getMacAddress());
-
- Log.info("Adding connected network for interface : " + interfaceName);
- NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, vpnName, elanName,
- ipUni.getIpAddress(), interfaceName);
-
- if (ipUni != null && ipUni.getSubnets() != null && ipUni.getSubnets().getSubnet() != null) {
- for (Subnet subnet : ipUni.getSubnets().getSubnet()) {
- Log.info("Resolving MAC address for gateway: " + subnet.getGateway());
- MacAddress gwMacAddress = NetvirtVpnUtils.resolveGwMac(dataBroker, arpUtilService, vpnName,
- ipUni.getIpAddress(), subnet.getGateway(), interfaceName); // trunk
- if (gwMacAddress == null) {
- continue;
- }
- Log.info("update vpn interface: " + interfaceName);
- NetvirtVpnUtils.createUpdateVpnInterface(dataBroker, vpnName, interfaceName, subnet.getSubnet(),
- gwMacAddress, false, ipUni.getIpAddress());
- }
- }
- Log.info("Finished working on elan instance: " + uniId);
+ Log.info("Removing elan instance {} and interface {}: ", elanName, interfaceName);
+ NetvirtUtils.deleteElanInterface(interfaceName, tx);
+ NetvirtUtils.deleteElanInstance(elanName, tx);
+ }
+
+ private void removeVpnInterface(String vpnName, VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
+ String interfaceName = vpnElans.getElanPort();
+ Log.info("Removing vpn interface: " + interfaceName);
+ NetvirtVpnUtils.removeVpnInterface(interfaceName, tx);
+ NetvirtVpnUtils.removeVpnPortFixedIp(vpnName, ipUni.getIpAddress(), tx);
+ Log.info("Finished working on vpn instance: " + vpnName);
}
- private void removeElanInterface(String instanceName, Uni uni) {
- String uniId = uni.getIpUniId().getValue();
- String interfaceName = uniId;
- Log.info("Removing elan interface: " + uniId);
- NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
+ private void removeDirectSubnet(Uni uni, IpUni ipUni) {
+ IpPrefix uniIpPrefix = ipUni.getIpAddress();
+ String subnetIp = NetvirtVpnUtils.getSubnetFromPrefix(uniIpPrefix);
+ IpPrefix subnetPrefix = new IpPrefix(new Ipv4Prefix(subnetIp));
+ InstanceIdentifier<Subnet> path = MefInterfaceUtils.getSubnetInstanceIdentifier(uni.getUniId(),
+ ipUni.getIpUniId(), subnetPrefix);
+ MdsalUtils.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
}
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.unimgr.mef.netvirt;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.unis.Uni;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-
-public class IpvcUniUtils {
-
- private static final Logger logger = LoggerFactory.getLogger(IpvcUniUtils.class);
-
- public static void addUni(DataBroker dataBroker, Uni data, String interfaceName, Integer vlanId) {
- try {
- String uniId = data.getUniId().getValue();
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- Link link = EvcUniUtils.getLink(dataBroker, uniId);
- addTrunkInterface(interfaceName, MefUtils.getTrunkParentName(link), vlanId, tx);
- commitTransaction(tx);
- } catch (final Exception e) {
- logger.error("Add uni failed !", e);
- }
- }
-
- private static void addTrunkInterface(String interfaceName, String parentInterfaceName, Integer vlanId,
- WriteTransaction tx) {
- logger.info("Adding VLAN trunk {} ParentRef {}", interfaceName, parentInterfaceName);
- Interface trunkInterface = null;
- if (vlanId != null) {
- trunkInterface = NetvirtUtils.createTrunkMemberInterface(interfaceName, parentInterfaceName, vlanId);
- } else {
- trunkInterface = NetvirtUtils.createTrunkInterface(interfaceName, parentInterfaceName);
- }
- NetvirtUtils.writeInterface(trunkInterface, tx);
- }
-
- public static org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni getUni(
- DataBroker dataBroker, String uniId) {
- Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni> optional = MdsalUtils
- .read(dataBroker, LogicalDatastoreType.CONFIGURATION, MefUtils.getUniInstanceIdentifier(uniId));
- if (!optional.isPresent()) {
- logger.error("Couldn't find uni {} for ipvc-uni", uniId);
- return null;
- }
- return optional.get();
- }
-
- public static IpUni getIpUni(DataBroker dataBroker, String uniId, String ipUniId) {
- Optional<IpUni> optional = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getIpUniInstanceIdentifier(uniId, ipUniId));
-
- if (!optional.isPresent()) {
- logger.error("A matching IpUni doesn't exist Uni {} IpUni {}", uniId, ipUniId);
- return null;
- }
-
- return optional.get();
- }
-
- private static void commitTransaction(WriteTransaction tx) {
- try {
- CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
- futures.get();
- } catch (Exception e) {
- logger.error("failed to commit transaction due to exception ", e);
- }
- }
-}
return result;
}
+
+
+ public static WriteTransaction createTransaction(DataBroker dataBroker) {
+ WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ return tx;
+ }
+
+ public static void commitTransaction(WriteTransaction tx) {
+ try {
+ CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+ futures.get();
+ } catch (Exception e) {
+ logger.error("failed to commit transaction due to exception ", e);
+ }
+ }
+
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.MefInterfaces;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.Subnets;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.Unis;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.SubnetKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.IpUnis;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayers;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUniKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.Links;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.LinkKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.MefTopology;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.Devices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.Device;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.DeviceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.Interfaces;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public final class MefInterfaceUtils {
+ private static final Logger logger = LoggerFactory.getLogger(MefInterfaceUtils.class);
+ public final static String VLAN_SEPARATOR = ".";
+ private final static String TRUNK_SUFFIX = "-trunk";
+
+ public static InstanceIdentifier<Interface> getDeviceInterfaceInstanceIdentifier(String deviceId,
+ String interfaceId) {
+ return InstanceIdentifier.builder(MefTopology.class).child(Devices.class)
+ .child(Device.class, new DeviceKey(new Identifier45(deviceId))).child(Interfaces.class)
+ .child(Interface.class, new InterfaceKey(new Identifier45(interfaceId))).build();
+ }
+
+ public static InstanceIdentifier<Uni> getUniInstanceIdentifier(String uniId) {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
+ .child(Uni.class, new UniKey(new Identifier45(uniId))).build();
+ }
+
+ public static InstanceIdentifier<Uni> getUniListInstanceIdentifier() {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class).child(Uni.class).build();
+ }
+
+ public static InstanceIdentifier<Link> getUniLinkInstanceIdentifier(String uniId, String deviceId,
+ String interfaceId) {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
+ .child(Uni.class, new UniKey(new Identifier45(uniId))).child(PhysicalLayers.class).child(Links.class)
+ .child(Link.class, new LinkKey(new Identifier45(deviceId), interfaceId)).build();
+ }
+
+ private static InstanceIdentifier<IpUni> getIpUniInstanceIdentifier(Identifier45 uniId, Identifier45 ipUniId) {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
+ .child(Uni.class, new UniKey(uniId)).child(IpUnis.class)
+ .child(IpUni.class, new IpUniKey(ipUniId)).build();
+ }
+
+ public static InstanceIdentifier<Subnets> getSubnetListInstanceIdentifier() {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Subnets.class).build();
+ }
+
+ public static InstanceIdentifier<Subnet> getSubnetsInstanceIdentifier() {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Subnets.class).child(Subnet.class).build();
+ }
+
+ public static InstanceIdentifier<Subnet> getSubnetInstanceIdentifier(Identifier45 uniId, Identifier45 ipUniId,
+ IpPrefix subnet) {
+ return InstanceIdentifier.builder(MefInterfaces.class).child(Subnets.class)
+
+ .child(Subnet.class, new SubnetKey(ipUniId, subnet, uniId)).build();
+ }
+
+ public static Link getLink(DataBroker dataBroker, String uniId, LogicalDatastoreType datastoreType) {
+ Uni uni = getUni(dataBroker, uniId, datastoreType);
+
+ if (uni == null) {
+ logger.error("A matching Uni doesn't exist for EvcUni {}", uniId);
+ return null;
+ }
+
+ PhysicalLayers physicalLayers = uni.getPhysicalLayers();
+ if (physicalLayers == null) {
+ logger.warn("Uni {} is missing PhysicalLayers", uniId);
+ return null;
+ }
+
+ Links links = physicalLayers.getLinks();
+ if (links == null || links.getLink() == null) {
+ logger.warn("Uni {} is has no links", uniId);
+ return null;
+ }
+
+ Link link = links.getLink().get(0);
+ return link;
+ }
+
+ public static Uni getUni(DataBroker dataBroker, String uniId, LogicalDatastoreType datastoreType) {
+ Optional<Uni> optional = MdsalUtils.read(dataBroker, datastoreType,
+ MefInterfaceUtils.getUniInstanceIdentifier(uniId));
+
+ if (!optional.isPresent()) {
+ logger.debug("A matching Uni doesn't exist {}", uniId);
+ return null;
+ }
+
+ return optional.get();
+ }
+
+ public static IpUni getIpUni(DataBroker dataBroker, Identifier45 uniId, Identifier45 ipUniId,
+ LogicalDatastoreType datastoreType) {
+ Optional<IpUni> optional = MdsalUtils.read(dataBroker, datastoreType,
+ MefInterfaceUtils.getIpUniInstanceIdentifier(uniId, ipUniId));
+
+ if (!optional.isPresent()) {
+ logger.error("A matching IpUni doesn't exist Uni {} IpUni {}", uniId, ipUniId);
+ return null;
+ }
+
+ return optional.get();
+ }
+
+ public static Interface getInterface(DataBroker dataBroker, String deviceId, String uniId,
+ LogicalDatastoreType datastoreType) {
+ InstanceIdentifier<Interface> interfacePath = MefInterfaceUtils.getDeviceInterfaceInstanceIdentifier(deviceId,
+ uniId);
+ Optional<Interface> optional = MdsalUtils.read(dataBroker, datastoreType, interfacePath);
+
+ if (!optional.isPresent()) {
+ logger.debug("A matching Uni doesn't exist {}", uniId);
+ return null;
+ }
+
+ return optional.get();
+ }
+
+ public static String getInterfaceNameForVlan(String interfaceName, Long vlan) {
+ final StringBuilder s = new StringBuilder();
+ s.append(interfaceName);
+ if (vlan != null) {
+ s.append(VLAN_SEPARATOR).append(vlan);
+ }
+ s.append(TRUNK_SUFFIX);
+
+ return getUUidFromString(s.toString());
+ }
+
+ private static String getUUidFromString(String key) {
+ return java.util.UUID.nameUUIDFromBytes(key.getBytes()).toString();
+ }
+
+ public static String getTrunkParentName(Link link) {
+ String interfaceName = link.getInterface().toString();
+ return interfaceName;
+ }
+
+ public static String getInterfaceName(Link link, String uniId) {
+ String device = link.getDevice().getValue();
+ return getDeviceInterfaceName(device, uniId);
+ }
+
+ public static String getDeviceInterfaceName(String deviceName, String interfaceName) {
+ return deviceName + IfmConstants.OF_URI_SEPARATOR + interfaceName;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpn;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpnBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefServiceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.Unis;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElansBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.vpn.elans.Subnets;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.vpn.elans.SubnetsBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public class MefServicesUtils {
+
+ public static InstanceIdentifier<Unis> getIpvcUnisInstanceIdentifier() {
+ return InstanceIdentifier.builder(MefServices.class).child(MefService.class).child(Ipvc.class).child(Unis.class)
+ .build();
+ }
+
+ public static InstanceIdentifier<Evc> getEvcsInstanceIdentifier() {
+ return getMefServiceInstanceIdentifier().child(Evc.class);
+ }
+
+ public static InstanceIdentifier<MefService> getMefServiceInstanceIdentifier() {
+ return InstanceIdentifier.create(MefServices.class).child(MefService.class);
+ }
+
+ public static InstanceIdentifier<MefServices> getMefServicesInstanceIdentifier() {
+ return InstanceIdentifier.create(MefServices.class);
+ }
+
+ public static InstanceIdentifier<Ipvc> getIpvcsInstanceIdentifier() {
+ return InstanceIdentifier.create(MefServices.class).child(MefService.class).child(Ipvc.class);
+ }
+
+ public static InstanceIdentifier<Ipvc> getIpvcsInstanceIdentifier(RetailSvcIdType svcId) {
+ return InstanceIdentifier.create(MefServices.class).child(MefService.class, new MefServiceKey(svcId))
+ .child(Ipvc.class);
+ }
+
+ public static VpnElans findVpnForNetwork(Subnet newSubnet, IpvcVpn ipvcVpn) {
+ return findVpnElanForNetwork(newSubnet.getUniId(), newSubnet.getIpUniId(), ipvcVpn);
+ }
+
+ public static VpnElans findVpnElanForNetwork(Identifier45 uniId, Identifier45 ipUniId, IpvcVpn ipvcVpn) {
+ List<VpnElans> vpnElans = ipvcVpn != null && ipvcVpn.getVpnElans() != null ? ipvcVpn.getVpnElans()
+ : Collections.emptyList();
+
+ for (VpnElans vpnElan : vpnElans) {
+ if (vpnElan.getUniId().equals(uniId) && vpnElan.getIpUniId().equals(ipUniId)) {
+ return vpnElan;
+ }
+ }
+ return null;
+ }
+
+ public static VpnElans findNetwork(Subnet newSubnet, VpnElans vpnElan) {
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
+ return findNetwork(subnetStr, vpnElan);
+ }
+
+ public static VpnElans findNetwork(String newSubnet, VpnElans vpnElan) {
+ List<Subnets> subnets = vpnElan != null && vpnElan.getSubnets() != null ? vpnElan.getSubnets()
+ : Collections.emptyList();
+ if (subnets.stream().anyMatch((s) -> s.getSubnet().equals(newSubnet))) {
+ return vpnElan;
+ }
+ return null;
+ }
+
+
+ public static IpvcVpn getOperIpvcVpn(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+ Optional<IpvcVpn> ipvcVpn = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+ if (ipvcVpn.isPresent()) {
+ return ipvcVpn.get();
+ } else {
+ return null;
+ }
+ }
+
+ public static void addOperIpvcVpnElan(InstanceIdentifier<Ipvc> identifier, String vpnId, WriteTransaction tx) {
+
+ synchronized (vpnId.intern()) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+
+ IpvcVpnBuilder ipvcVpnBuilder = new IpvcVpnBuilder();
+ ipvcVpnBuilder.setVpnId(vpnId);
+
+ tx.merge(LogicalDatastoreType.OPERATIONAL, path, ipvcVpnBuilder.build(), true);
+ }
+ }
+
+ public static void addOperIpvcVpnElan(InstanceIdentifier<Ipvc> identifier, String vpnId, Identifier45 uniId,
+ Identifier45 ipUniId, String elanId, String elanPortId, List<String> newSubnets, WriteTransaction tx) {
+
+ synchronized (vpnId.intern()) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+
+ IpvcVpnBuilder ipvcVpnBuilder = new IpvcVpnBuilder();
+ ipvcVpnBuilder.setVpnId(vpnId);
+
+ List<VpnElans> vpnElansEx = new ArrayList<>();
+ VpnElansBuilder vpnElans = new VpnElansBuilder();
+ vpnElans.setElanId(elanId);
+ vpnElans.setUniId(uniId);
+ vpnElans.setIpUniId(ipUniId);
+ vpnElans.setElanPort(elanPortId);
+ List<Subnets> subnets = new ArrayList<>();
+ if (newSubnets != null) {
+ newSubnets.forEach(s -> {
+ SubnetsBuilder sb = new SubnetsBuilder();
+ sb.setSubnet(s);
+ subnets.add(sb.build());
+ });
+ }
+ vpnElans.setSubnets(subnets);
+ vpnElansEx.add(vpnElans.build());
+ ipvcVpnBuilder.setVpnElans(vpnElansEx);
+
+ tx.merge(LogicalDatastoreType.OPERATIONAL, path, ipvcVpnBuilder.build(), true);
+ }
+ }
+
+ public static void addOperIpvcVpnElan(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier, String vpnId,
+ Identifier45 uniId, Identifier45 ipUniId, String elanId, String elanPortId, List<String> newSubnets) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ addOperIpvcVpnElan(identifier, vpnId, uniId, ipUniId, elanId, elanPortId, newSubnets, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ public static void removeOperIpvcVpn(InstanceIdentifier<Ipvc> identifier, WriteTransaction tx) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, path);
+ }
+
+ public static void removeOperIpvcSubnet(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier, String vpnId,
+ Identifier45 uniId, Identifier45 ipUniId, String elanId, String elanPortId, String deleteSubnet) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+ IpvcVpn ipvcVpn = getOperIpvcVpn(dataBroker, identifier);
+ if (ipvcVpn == null || ipvcVpn.getVpnElans() == null) {
+ return;
+ }
+ IpvcVpnBuilder ipvcVpnBuilder = new IpvcVpnBuilder(ipvcVpn);
+ List<VpnElans> vpnElansEx = ipvcVpnBuilder.getVpnElans();
+
+ VpnElans vpnElans = findVpnElanForNetwork(uniId, ipUniId, ipvcVpn);
+ vpnElans = findNetwork(deleteSubnet, vpnElans);
+
+ if (vpnElans != null) {
+ vpnElansEx.remove(vpnElans);
+ VpnElansBuilder vpnElansB = new VpnElansBuilder(vpnElans);
+ List<Subnets> exSubnets = vpnElansB.getSubnets();
+ List<Subnets> newSubnets = exSubnets.stream().filter(s -> ! s.getSubnet().equals(deleteSubnet)).collect(Collectors.toList());
+ vpnElansB.setSubnets(newSubnets);
+ vpnElansEx.add(vpnElansB.build());
+ }
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, path, ipvcVpnBuilder.build());
+ }
+
+ public static void removeOperIpvcElan(DataBroker dataBroker, InstanceIdentifier<Ipvc> identifier, String vpnId,
+ Identifier45 uniId, Identifier45 ipUniId, String elanId, String elanPortId) {
+ InstanceIdentifier<IpvcVpn> path = identifier.augmentation(IpvcVpn.class);
+ IpvcVpn ipvcVpn = getOperIpvcVpn(dataBroker, identifier);
+ if (ipvcVpn == null || ipvcVpn.getVpnElans() == null) {
+ return;
+ }
+ IpvcVpnBuilder ipvcVpnBuilder = new IpvcVpnBuilder(ipvcVpn);
+ List<VpnElans> vpnElansEx = ipvcVpnBuilder.getVpnElans();
+
+ VpnElans vpnElans = findVpnElanForNetwork(uniId, ipUniId, ipvcVpn);
+ if (vpnElans != null) {
+ vpnElansEx.remove(vpnElans);
+ }
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, path, ipvcVpnBuilder.build());
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.unimgr.mef.netvirt;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.MefInterfaces;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.Unis;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.IpUnis;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayers;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUniKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.Links;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.LinkKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefServiceKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.EvcBuilder;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.MefTopology;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.Devices;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.Device;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.DeviceKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.Interfaces;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceKey;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcIdType;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.RetailSvcIdType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-public final class MefUtils {
- @SuppressWarnings("unused")
- private static final Logger logger = LoggerFactory.getLogger(MefUtils.class);
-
- public static InstanceIdentifier<Interface> getDeviceInterfaceInstanceIdentifier(String deviceId,
- String interfaceId) {
- return InstanceIdentifier.builder(MefTopology.class).child(Devices.class)
- .child(Device.class, new DeviceKey(new Identifier45(deviceId))).child(Interfaces.class)
- .child(Interface.class, new InterfaceKey(new Identifier45(interfaceId))).build();
- }
-
- public static InstanceIdentifier<Uni> getUniInstanceIdentifier(String uniId) {
- return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
- .child(Uni.class, new UniKey(new Identifier45(uniId))).build();
- }
-
- public static InstanceIdentifier<Uni> getUniListInterfaceInstanceIdentifier() {
- return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class).child(Uni.class).build();
- }
-
- public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.Unis> getUnisInstanceIdentifier(
- String evcId) {
- return InstanceIdentifier.builder(MefServices.class)
- .child(MefService.class, new MefServiceKey(RetailSvcIdType.getDefaultInstance(evcId))).child(Evc.class)
- .child(org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.Unis.class)
- .build();
- }
-
- public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni> getEvcUniInstanceIdentifier(
- String uniId) {
- return InstanceIdentifier.builder(MefServices.class).child(MefService.class).child(Evc.class)
- .child(org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.Unis.class)
- .child(org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni.class,
- new org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.UniKey(
- new Identifier45(uniId)))
- .build();
- }
-
- public static InstanceIdentifier<Link> getUniLinkInstanceIdentifier(String uniId, String deviceId,
- String interfaceId) {
- return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
- .child(Uni.class, new UniKey(new Identifier45(uniId))).child(PhysicalLayers.class).child(Links.class)
- .child(Link.class, new LinkKey(new Identifier45(deviceId), interfaceId)).build();
- }
-
- public static InstanceIdentifier<IpUni> getIpUniInstanceIdentifier(String uniId, String ipUniId) {
- return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
- .child(Uni.class, new UniKey(new Identifier45(uniId))).child(IpUnis.class)
- .child(IpUni.class, new IpUniKey(new Identifier45(ipUniId))).build();
- }
-
- public static InstanceIdentifier<Evc> getEvcInstanceIdentifier() {
- return getMefServiceInstanceIdentifier().child(Evc.class);
- }
-
- public static InstanceIdentifier<MefService> getMefServiceInstanceIdentifier() {
- return InstanceIdentifier.create(MefServices.class).child(MefService.class);
- }
-
- public static InstanceIdentifier<MefService> getMefServiceInstanceIdentifier(RetailSvcIdType retailSvcIdType) {
- return InstanceIdentifier.create(MefServices.class).child(MefService.class, new MefServiceKey(retailSvcIdType));
- }
-
- public static InstanceIdentifier<MefServices> getMefServicesInstanceIdentifier() {
- return InstanceIdentifier.create(MefServices.class);
- }
-
- public static void createEvcInstance(DataBroker dataBroker, String instanceName) {
- Evc einst = createEvcInstance(instanceName);
-
- MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getEvcInstanceInstanceIdentifier(instanceName), einst);
- }
-
- private static InstanceIdentifier<Evc> getEvcInstanceInstanceIdentifier(String instanceName) {
- return InstanceIdentifier.builder(MefServices.class)
- .child(MefService.class, new MefServiceKey(RetailSvcIdType.getDefaultInstance(instanceName)))
- .child(Evc.class).build();
- }
-
- private static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni> getEvcUniInstanceIdentifier(
- String serviceName, String uniId) {
- return InstanceIdentifier.builder(MefServices.class)
- .child(MefService.class, new MefServiceKey(RetailSvcIdType.getDefaultInstance(serviceName)))
- .child(Evc.class)
- .child(org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.Unis.class)
- .child(org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni.class, //
- new org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.UniKey(
- Identifier45.getDefaultInstance(uniId)))
- .build();
- }
-
- private static Evc createEvcInstance(String instanceName) {
- EvcBuilder evcBuilder = new EvcBuilder();
- evcBuilder.setAdminStateEnabled(false);
- evcBuilder.setEvcId(EvcIdType.getDefaultInstance(instanceName));
- evcBuilder.setEvcType(EvcType.MultipointToMultipoint);
- return evcBuilder.build();
- }
-
- public static Boolean EvcExists(DataBroker dataBroker, String instanceName) {
- Optional<Evc> evc = getEvc(dataBroker, instanceName);
- return evc.isPresent();
- }
-
- public static Boolean isEvcAdminStateEnabled(DataBroker dataBroker, String instanceName) {
- Optional<Evc> evc = getEvc(dataBroker, instanceName);
- return evc.isPresent() && evc.get().isAdminStateEnabled();
-
- }
-
- public static Optional<Evc> getEvc(DataBroker dataBroker, String instanceName) {
- Optional<Evc> evc = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getEvcInstanceInstanceIdentifier(instanceName));
- return evc;
- }
-
- public static Boolean EvcUniExists(DataBroker dataBroker, String instanceName, String uniId) {
- logger.info("searching for uni id {} in service {}", uniId, instanceName);
- Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni> uni = MdsalUtils
- .read(dataBroker, LogicalDatastoreType.CONFIGURATION, getEvcUniInstanceIdentifier(instanceName, uniId));
- if (uni.isPresent()) {
- logger.info("found uni");
- } else {
- logger.info("no uni");
- }
- return uni.isPresent();
- }
-
- public static String getTrunkParentName(Link link) {
- String interfaceName = link.getInterface().toString();
- return interfaceName;
- }
-
- public static String getInterfaceName(Link link, String uniId) {
- String device = link.getDevice().getValue();
- return NetvirtUtils.getDeviceInterfaceName(device, uniId);
- }
-
- public static InstanceIdentifier<Ipvc> getIpvcInstanceIdentifier() {
- return InstanceIdentifier.create(MefServices.class).child(MefService.class).child(Ipvc.class);
- }
-
- public static String ipPrefixToString(IpPrefix ipAddress) {
- if (ipAddress.getIpv4Prefix() != null) {
- return ipAddress.getIpv4Prefix().getValue();
- }
-
- return ipAddress.getIpv6Prefix().getValue();
- }
-
- public static String ipAddressToString(IpAddress ipAddress) {
- if (ipAddress.getIpv4Address() != null) {
- return ipAddress.getIpv4Address().getValue();
- }
-
- return ipAddress.getIpv6Address().getValue();
- }
-
-}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
import org.slf4j.Logger;
public class NetvirtUtils {
private static final Logger logger = LoggerFactory.getLogger(NetvirtUtils.class);
- public final static String VLAN_SEPARATOR = ".";
-
public static void createElanInstance(DataBroker dataBroker, String instanceName, boolean isEtree) {
ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
}
- public static void createElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
- ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
-
- MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
- }
-
- public static void createEtreeInterface(DataBroker dataBroker, String instanceName, String interfaceName,
- EtreeInterfaceType type) {
- ElanInterfaceBuilder einterfaceBuilder = createEtreeInterface(instanceName, interfaceName, type);
-
- MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
- }
-
public static void updateElanInstance(DataBroker dataBroker, String instanceName) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ updateElanInstance(instanceName, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+ public static void updateElanInstance(String instanceName, WriteTransaction tx) {
ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
- MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
+ tx.merge(LogicalDatastoreType.CONFIGURATION, getElanInstanceInstanceIdentifier(instanceName),
+ einstBuilder.build());
}
public static void updateElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
getElanInstanceInstanceIdentifier(instanceName));
}
- public static void deleteElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
- MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getElanInterfaceInstanceIdentifier(interfaceName));
+ public static void deleteElanInstance(String instanceName, WriteTransaction tx) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION, getElanInstanceInstanceIdentifier(instanceName));
+ }
+
+ public static void deleteElanInterface(DataBroker dataBroker, String interfaceName) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ deleteElanInterface(interfaceName, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ public static void deleteElanInterface(String interfaceName, WriteTransaction tx) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName));
}
public static Interface createTrunkInterface(String interfaceName, String parentIfaceName) {
return interfaceBuilder.build();
}
- public static String getInterfaceNameForVlan(String uniId, String vlanId) {
- return uniId + VLAN_SEPARATOR + vlanId;
- }
-
private static ElanInstanceBuilder createElanInstance(String instanceName) {
ElanInstanceBuilder einstBuilder = new ElanInstanceBuilder();
einstBuilder.setElanInstanceName(instanceName);
einstBuilder.setKey(new ElanInstanceKey(instanceName));
- einstBuilder.setSegmentationId(Math.abs((long) instanceName.hashCode()));
+ einstBuilder.setSegmentationId(Long.valueOf(Math.abs((short) instanceName.hashCode())));
+ einstBuilder.setSegmentType(SegmentTypeVxlan.class);
return einstBuilder;
}
.child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
}
- public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> getStateInterfaceIdentifier(
- String interfaceName) {
- InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder = InstanceIdentifier
- .builder(InterfacesState.class)
- .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
- new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
- interfaceName));
- InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder
- .build();
- return id;
- }
-
public static InstanceIdentifier<Interface> getInterfaceIdentifier(String interfaceName) {
InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier.builder(Interfaces.class)
.child(Interface.class, new InterfaceKey(interfaceName));
return MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
}
- public static String getDeviceInterfaceName(String deviceName, String interfaceName) {
- return deviceName + IfmConstants.OF_URI_SEPARATOR + interfaceName;
- }
-
public static void writeInterface(Interface iface, WriteTransaction tx) {
String interfaceName = iface.getName();
InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
tx.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, iface, true);
}
- public static void write(Interface iface, WriteTransaction tx) {
- String interfaceName = iface.getName();
- InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
- tx.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, iface, true);
- }
-
- public static void delete(String interfaceName, WriteTransaction tx) {
+ public static void deleteInterface(String interfaceName, WriteTransaction tx) {
InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
tx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
}
- public static boolean waitForGeniusToUpdateInterface(DataBroker dataBroker, String interfaceName) {
- int retries = 10;
-
- while (retries > 0) {
- Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> optional = MdsalUtils
- .read(dataBroker, LogicalDatastoreType.OPERATIONAL, getStateInterfaceIdentifier(interfaceName));
-
- if (!optional.isPresent()) {
- logger.info("State interface {} doesn't exist", interfaceName);
- } else {
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateInterface = optional
- .get();
-
- if (stateInterface.getIfIndex() != null) {
- logger.info("State interface configured with ifIndex {}", stateInterface.getIfIndex());
-
- // Wait a bit, because if we continue too soon this will not
- // work.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
-
- return true;
- }
- }
-
- retries -= 1;
- try {
- Thread.sleep(1500);
- } catch (InterruptedException e) {
- }
- }
-
- return false;
- }
-
private static InstanceIdentifier<Interface> createInterfaceIdentifier(String interfaceName) {
return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
.build();
}
- public static void createInterface(DataBroker dataBroker, String instanceName, String interfaceName,
+ public static void createElanInterface(DataBroker dataBroker, String instanceName, String interfaceName,
EtreeInterfaceType etreeInterfaceType, boolean isEtree) {
- boolean result = NetvirtUtils.waitForGeniusToUpdateInterface(dataBroker, interfaceName);
- if (!result) {
- logger.error("State interface {} is not configured (missing ifIndex)", interfaceName);
- return;
- }
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ createElanInterface(instanceName, interfaceName, etreeInterfaceType, isEtree, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+ public static void createElanInterface(String instanceName, String interfaceName,
+ EtreeInterfaceType etreeInterfaceType, boolean isEtree, WriteTransaction tx) {
logger.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
if (isEtree) {
- NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName, etreeInterfaceType);
+ NetvirtUtils.createEtreeInterface(instanceName, interfaceName, etreeInterfaceType, tx);
} else {
- NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+ NetvirtUtils.createElanInterface(instanceName, interfaceName, tx);
}
}
+
+ private static void createEtreeInterface(String instanceName, String interfaceName, EtreeInterfaceType type,
+ WriteTransaction tx) {
+ ElanInterfaceBuilder einterfaceBuilder = createEtreeInterface(instanceName, interfaceName, type);
+
+ tx.put(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName),
+ einterfaceBuilder.build());
+ }
+
+ private static void createElanInterface(String instanceName, String interfaceName, WriteTransaction tx) {
+ ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
+
+ tx.put(LogicalDatastoreType.CONFIGURATION, getElanInterfaceInstanceIdentifier(interfaceName),
+ einterfaceBuilder.build());
+ }
+
+ public static void safeSleep() {
+ try {
+ Thread.yield();
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ public static void safeSleep(short sec) {
+ try {
+ Thread.yield();
+ Thread.sleep(1000*sec);
+ } catch (InterruptedException e) {
+ }
+ }
+
+
}
import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
public class NetvirtVpnUtils {
private static final Logger logger = LoggerFactory.getLogger(NetvirtVpnUtils.class);
private final static String ELAN_PREFIX = "elan.";
- private final static String TRUNK_SUFFIX = "-trunk";
- private final static String VLAN_SEPARATOR = ".";
private final static String IP_ADDR_SUFFIX = "/32";
private final static String IP_MUSK_SEPARATOR = "/";
- private final static int MaxRetries = 10;
public static void createVpnInstance(DataBroker dataBroker, String instanceName) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ createVpnInstance(instanceName, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ public static void createVpnInstance(String instanceName, WriteTransaction tx) {
VpnInstanceBuilder builder = new VpnInstanceBuilder();
builder.setVpnInstanceName(instanceName);
Ipv4FamilyBuilder ipv4FamilyBuilder = new Ipv4FamilyBuilder();
- ipv4FamilyBuilder.setVpnTargets(new VpnTargetsBuilder().build());
+ VpnTargetsBuilder vpnTargetsB = new VpnTargetsBuilder();
+ vpnTargetsB.setVpnTarget(new ArrayList<VpnTarget>());
+ ipv4FamilyBuilder.setVpnTargets(vpnTargetsB.build());
+
// WA till netvirt will allow creation of VPN without RD
UUID vpnId = UUID.fromString(instanceName);
String rd = String.valueOf(Math.abs(vpnId.getLeastSignificantBits()));
ipv4FamilyBuilder.setRouteDistinguisher(rd);
builder.setIpv4Family(ipv4FamilyBuilder.build());
- MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getVpnInstanceInstanceIdentifier(instanceName), builder.build());
+ tx.put(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName), builder.build());
+ }
+
+ public static void removeVpnInstance(String instanceName, WriteTransaction tx) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInstanceInstanceIdentifier(instanceName));
+ }
+
+ private static InstanceIdentifier<VpnInstance> getVpnInstanceInstanceIdentifier(String instanceName) {
+ return InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(instanceName))
+ .build();
}
public static void createUpdateVpnInterface(DataBroker dataBroker, String vpnName, String interfaceName,
- IpPrefix ifPrefix, MacAddress macAddress, boolean primary, IpPrefix gwIpAddress) {
+ String ifAddr, String macAddress, boolean primary, String gwIpAddress) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ createUpdateVpnInterface(vpnName, interfaceName, ifAddr, macAddress, primary, gwIpAddress, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ public static void createUpdateVpnInterface(String vpnName, String interfaceName, IpPrefix ifPrefix,
+ String macAddress, boolean primary, IpPrefix gwIpAddress, WriteTransaction tx) {
synchronized (interfaceName.intern()) {
String ipAddress = null;
String nextHopIp = null;
if (primary) {
- ipAddress = getPrefixFromSubnet(MefUtils.ipPrefixToString(ifPrefix));
+ ipAddress = getAddressFromSubnet(ipPrefixToString(ifPrefix));
} else {
- ipAddress = MefUtils.ipPrefixToString(ifPrefix);
- nextHopIp = getIpAddressFromPrefix(MefUtils.ipPrefixToString(gwIpAddress));
+ ipAddress = ipPrefixToString(ifPrefix);
+ nextHopIp = getIpAddressFromPrefix(ipPrefixToString(gwIpAddress));
}
+ createUpdateVpnInterface(vpnName, interfaceName, ipAddress, macAddress, primary, nextHopIp, tx);
+ }
+ }
+ public static void createUpdateVpnInterface(String vpnName, String interfaceName, String ipAddress,
+ String macAddress, boolean primary, String nextHopIp, WriteTransaction tx) {
+ synchronized (interfaceName.intern()) {
Adjacencies adjancencies = buildInterfaceAdjacency(ipAddress, macAddress, primary, nextHopIp);
VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, adjancencies);
- MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
- getVpnInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+ tx.merge(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName),
+ einterfaceBuilder.build());
}
}
- private static Adjacencies buildInterfaceAdjacency(String ipAddress, MacAddress macAddress, boolean primary,
+ private static VpnInterfaceBuilder createVpnInterface(String instanceName, String interfaceName,
+ Adjacencies adjacencies) {
+ VpnInterfaceBuilder einterfaceBuilder = new VpnInterfaceBuilder();
+ einterfaceBuilder.setVpnInstanceName(instanceName);
+ einterfaceBuilder.setName(interfaceName);
+ einterfaceBuilder.addAugmentation(Adjacencies.class, adjacencies);
+ return einterfaceBuilder;
+ }
+
+ private static Adjacencies buildInterfaceAdjacency(String ipAddress, String macAddress, boolean primary,
String nextHopIp) {
AdjacenciesBuilder builder = new AdjacenciesBuilder();
List<Adjacency> list = new ArrayList<>();
AdjacencyBuilder aBuilder = new AdjacencyBuilder();
aBuilder.setIpAddress(ipAddress);
if (macAddress != null) {
- aBuilder.setMacAddress(macAddress.getValue());
+ aBuilder.setMacAddress(macAddress);
}
aBuilder.setPrimaryAdjacency(primary);
if (nextHopIp != null) {
return builder.build();
}
- private static VpnInterfaceBuilder createVpnInterface(String instanceName, String interfaceName,
- Adjacencies adjacencies) {
- VpnInterfaceBuilder einterfaceBuilder = new VpnInterfaceBuilder();
- einterfaceBuilder.setVpnInstanceName(instanceName);
- einterfaceBuilder.setName(interfaceName);
- einterfaceBuilder.addAugmentation(Adjacencies.class, adjacencies);
- return einterfaceBuilder;
+ public static void removeVpnInterface(String interfaceName, WriteTransaction tx) {
+ synchronized (interfaceName.intern()) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION, getVpnInterfaceInstanceIdentifier(interfaceName));
+ }
}
- private static InstanceIdentifier<VpnInstance> getVpnInstanceInstanceIdentifier(String instanceName) {
- return InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(instanceName))
- .build();
+ public static void removeVpnInterfaceAdjacencies(DataBroker dataBroker, String vpnName, String interfaceName) {
+ AdjacenciesBuilder builder = new AdjacenciesBuilder();
+ List<Adjacency> list = new ArrayList<>();
+ builder.setAdjacency(list);
+ VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, builder.build());
+
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ getVpnInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+
+ }
+
+ public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpPrefix ifPrefix) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ String ipAddress = ipPrefixToString(ifPrefix);
+ removeVpnInterfaceAdjacency(interfaceName, ipAddress, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpAddress ifAddress) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ String ifAddressStr = getAddressFromSubnet(ipAddressToString(ifAddress));
+ removeVpnInterfaceAdjacency(interfaceName, ifAddressStr, tx);
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ private static void removeVpnInterfaceAdjacency(String interfaceName, String ipAddress, WriteTransaction tx) {
+ synchronized (interfaceName.intern()) {
+
+ InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
+ .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).augmentation(Adjacencies.class)
+ .child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
+
+ tx.delete(LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
+ }
}
private static InstanceIdentifier<VpnInterface> getVpnInterfaceInstanceIdentifier(String interfaceName) {
public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, IpPrefix ipAddress,
MacAddress macAddress) {
- String fixedIpPrefix = MefUtils.ipPrefixToString(ipAddress);
+ String fixedIpPrefix = ipPrefixToString(ipAddress);
String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
- createVpnPortFixedIp(dataBroker, vpnName, portName, fixedIp, macAddress);
+
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ createVpnPortFixedIp(vpnName, portName, fixedIp, macAddress, tx);
+ MdsalUtils.commitTransaction(tx);
}
- public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, IpAddress ipAddress,
- MacAddress macAddress) {
- String fixedIp = MefUtils.ipAddressToString(ipAddress);
- createVpnPortFixedIp(dataBroker, vpnName, portName, fixedIp, macAddress);
+ public static void createVpnPortFixedIp(String vpnName, String portName, IpPrefix ipAddress, MacAddress macAddress,
+ WriteTransaction tx) {
+ String fixedIpPrefix = ipPrefixToString(ipAddress);
+ String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
+ createVpnPortFixedIp(vpnName, portName, fixedIp, macAddress, tx);
}
- public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, String fixedIp,
- MacAddress macAddress) {
+ private static void createVpnPortFixedIp(String vpnName, String portName, String fixedIp, MacAddress macAddress,
+ WriteTransaction tx) {
synchronized ((vpnName + fixedIp).intern()) {
- InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
+ InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder()
.setKey(new VpnPortipToPortKey(fixedIp, vpnName)).setVpnName(vpnName).setPortFixedip(fixedIp)
.setPortName(portName).setMacAddress(macAddress.getValue()).setSubnetIp(true).setConfig(true)
.setLearnt(false);
- MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, id, builder.build());
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, builder.build());
logger.debug(
"Interface to fixedIp added: {}, vpn {}, interface {}, mac {} added to " + "VpnPortipToPort DS",
fixedIp, vpnName, portName, macAddress);
}
}
- static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
- InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
- .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
- return id;
- }
-
- private static void createSubnetToNetworkMapping(DataBroker dataBroker, Uuid subnetId, Uuid networkId) {
- InstanceIdentifier<NetworkMap> networkMapIdentifier = buildNetworkMapIdentifier(networkId);
- Optional<NetworkMap> optionalNetworkMap = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- networkMapIdentifier);
- NetworkMapBuilder nwMapBuilder = null;
- if (optionalNetworkMap.isPresent()) {
- nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
- } else {
- nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
- logger.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
- }
- List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
- if (subnetIdList == null) {
- subnetIdList = new ArrayList<>();
- }
- subnetIdList.add(subnetId);
- nwMapBuilder.setSubnetIdList(subnetIdList);
- MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
- logger.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
- networkId.getValue());
+ public static VpnPortipToPort getVpnPortFixedIp(DataBroker dataBroker, String vpnName, String fixedIp) {
+ InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
+ Optional<VpnPortipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ return opt != null && opt.isPresent() ? opt.get() : null;
}
- private static InstanceIdentifier<VpnPortipToPort> buildVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
- InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
- .child(VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
- return id;
+ public static void removeVpnPortFixedIp(String vpnName, IpPrefix ipAddress, WriteTransaction tx) {
+ String fixedIpPrefix = ipPrefixToString(ipAddress);
+ String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
+ InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, id);
}
public static void addDirectSubnetToVpn(DataBroker dataBroker,
IpPrefix subnetIpPrefix, String interfaceName) {
InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
.child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
- Optional<ElanInstance> elanInstance = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
elanIdentifierId);
if (!elanInstance.isPresent()) {
logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
return;
}
- Long elanTag = elanInstance.get().getElanTag();
+ Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
+ : elanInstance.get().getSegmentationId();
Uuid subnetId = new Uuid(subnetName);
- logger.info("Adding subnet {} {} to elan map", subnetId);
+ logger.info("Adding subnet {} {} to elan map", subnetId, subnetId);
createSubnetToNetworkMapping(dataBroker, subnetId, subnetId);
- String subnetIp = getSubnetFromPrefix(MefUtils.ipPrefixToString(subnetIpPrefix));
+ String subnetIp = getSubnetFromPrefix(ipPrefixToString(subnetIpPrefix));
logger.info("Adding subnet {} {} to vpn {}", subnetName, subnetIp, vpnName);
updateSubnetNode(dataBroker, new Uuid(vpnName), subnetId, subnetIp);
logger.info("Adding port {} to subnet {}", interfaceName, subnetName);
- updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName));
+ updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null);
logger.info("Publish subnet {}", subnetName);
publishSubnetAddNotification(notificationPublishService, subnetId, subnetIp, vpnName, elanTag);
}
+ public static void removeDirectSubnetFromVpn(DataBroker dataBroker,
+ final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
+ String interfaceName) {
+ InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
+ .child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
+ Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ elanIdentifierId);
+ if (!elanInstance.isPresent()) {
+ logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
+ return;
+ }
+ Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
+ : elanInstance.get().getSegmentationId();
+ Uuid subnetId = new Uuid(subnetName);
+
+ logger.info("Publish subnet remove {}", subnetName);
+ publishSubnetRemoveNotification(notificationPublishService, subnetId, vpnName, elanTag);
+
+ logger.info("Removing port {} from subnet {}", interfaceName, subnetName);
+ updateSubnetmapNodeWithPorts(dataBroker, subnetId, null, new Uuid(interfaceName));
+
+ logger.info("Removing subnet {} from vpn {}", subnetName, vpnName);
+ removeSubnetNode(dataBroker, new Uuid(vpnName));
+
+ logger.info("Removing subnet {} to elan map", subnetId);
+ removeSubnetToNetworkMapping(dataBroker, subnetId);
+
+ logger.info("Finished Working on subnet {}", subnetName);
+ }
+
+ private static void createSubnetToNetworkMapping(DataBroker dataBroker, Uuid subnetId, Uuid networkId) {
+ InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
+ Optional<NetworkMap> optionalNetworkMap = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ networkMapIdentifier);
+ NetworkMapBuilder nwMapBuilder = null;
+ if (optionalNetworkMap.isPresent()) {
+ nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
+ } else {
+ nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
+ logger.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
+ }
+ List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
+ if (subnetIdList == null) {
+ subnetIdList = new ArrayList<>();
+ }
+ subnetIdList.add(subnetId);
+ nwMapBuilder.setSubnetIdList(subnetIdList);
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
+ logger.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
+ networkId.getValue());
+ }
+
+ private static void removeSubnetToNetworkMapping(DataBroker dataBroker, Uuid networkId) {
+ InstanceIdentifier<NetworkMap> networkMapIdentifier = getNetworkMapIdentifier(networkId);
+ MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier);
+ logger.debug("Deleted subnet-network mapping for network {}", networkId.getValue());
+ }
+
protected static void updateSubnetNode(DataBroker dataBroker, Uuid vpnId, Uuid subnetId, String subnetIp) {
Subnetmap subnetmap = null;
SubnetmapBuilder builder = null;
.child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
synchronized (subnetId.getValue().intern()) {
- Optional<Subnetmap> sn = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (sn.isPresent()) {
builder = new SubnetmapBuilder(sn.get());
logger.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
}
}
- private static void updateSubnetmapNodeWithPorts(DataBroker dataBroker, Uuid subnetId, Uuid portId) {
+ protected static void removeSubnetNode(DataBroker dataBroker, Uuid subnetId) {
+ InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
+ .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+
+ synchronized (subnetId.getValue().intern()) {
+ logger.debug("Deleting subnetMap node: {} ", subnetId.getValue());
+ MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ }
+ }
+
+ private static void updateSubnetmapNodeWithPorts(DataBroker dataBroker, Uuid subnetId, Uuid portIdToAdd,
+ Uuid portIdToRemove) {
Subnetmap subnetmap = null;
InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
.child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
synchronized (subnetId.getValue().intern()) {
- Optional<Subnetmap> sn = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ Optional<Subnetmap> sn = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (sn.isPresent()) {
SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
- if (null != portId) {
+ if (null != portIdToAdd) {
List<Uuid> portList = builder.getPortList();
if (null == portList) {
portList = new ArrayList<>();
}
- portList.add(portId);
+ if (portIdToAdd != null) {
+ portList.add(portIdToAdd);
+ logger.debug("Updating subnetmap node {} with port {}", subnetId.getValue(),
+ portIdToAdd.getValue());
+
+ }
+ if (portIdToRemove != null) {
+ portList.remove(portIdToRemove);
+ logger.debug("Updating subnetmap node {} removing port {}", subnetId.getValue(),
+ portIdToRemove.getValue());
+
+ }
builder.setPortList(portList);
- logger.debug("Updating subnetmap node {} with port {}", subnetId.getValue(), portId.getValue());
}
subnetmap = builder.build();
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
}
}
+ private static InstanceIdentifier<NetworkMap> getNetworkMapIdentifier(Uuid networkId) {
+ InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
+ .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
+ return id;
+ }
+
+ private static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
+ InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
+ .child(VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
+ return id;
+ }
+
+ public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier() {
+ return InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class).build();
+ }
+
private static void publishSubnetAddNotification(final NotificationPublishService notificationPublishService,
Uuid subnetId, String subnetIp, String vpnName, Long elanTag) {
SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
- logger.info("publish notification called");
+ logger.info("publish notification called for network creation");
builder.setSubnetId(subnetId);
builder.setSubnetIp(subnetIp);
}
}
- private static String getIpAddressFromPrefix(String prefix) {
+ private static void publishSubnetRemoveNotification(final NotificationPublishService notificationPublishService,
+ Uuid subnetId, String vpnName, Long elanTag) {
+ SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
+
+ logger.info("publish notification called for network deletion");
+
+ builder.setSubnetId(subnetId);
+ builder.setVpnName(vpnName);
+ builder.setExternalVpn(true);
+ builder.setElanTag(elanTag);
+
+ try {
+ notificationPublishService.putNotification(builder.build());
+ } catch (InterruptedException e) {
+ logger.error("Fail to publish notification {}", builder, e);
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ public static void sendArpRequest(OdlArputilService arpUtilService, IpAddress srcIpAddress, IpAddress dstIpAddress,
+ String interf) {
+ try {
+ List<InterfaceAddress> interfaceAddresses = new ArrayList<>();
+ interfaceAddresses
+ .add(new InterfaceAddressBuilder().setInterface(interf).setIpAddress(srcIpAddress).build());
+
+ SendArpRequestInput sendArpRequestInput = new SendArpRequestInputBuilder().setIpaddress(dstIpAddress)
+ .setInterfaceAddress(interfaceAddresses).build();
+ arpUtilService.sendArpRequest(sendArpRequestInput);
+ } catch (Exception e) {
+ logger.error("Failed to send ARP request to IP {} from interfaces {}",
+ dstIpAddress.getIpv4Address().getValue(), interf, e);
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ public static String getIpAddressFromPrefix(String prefix) {
return prefix.split(IP_MUSK_SEPARATOR)[0];
}
return prefix.split(IP_MUSK_SEPARATOR)[1];
}
- private static String getSubnetFromPrefix(String prefix) {
+ public static String getSubnetFromPrefix(String prefix) {
SubnetInfo subnet = new SubnetUtils(prefix).getInfo();
return subnet.getNetworkAddress() + IP_MUSK_SEPARATOR + getMaskFromPrefix(prefix);
}
- private static String getPrefixFromSubnet(String prefix) {
+ public static String getSubnetFromPrefix(IpPrefix prefix) {
+ String prefixStr = ipPrefixToString(prefix);
+ return getSubnetFromPrefix(prefixStr);
+ }
+
+ private static String getAddressFromSubnet(String prefix) {
String myAddress = getIpAddressFromPrefix(prefix);
return myAddress + IP_ADDR_SUFFIX;
}
return getUUidFromString(ELAN_PREFIX + portName);
}
- public static String getInterfaceNameForVlan(String interfaceName, Integer vlan) {
- final StringBuilder s = new StringBuilder();
- s.append(interfaceName);
- if (vlan != null) {
- s.append(VLAN_SEPARATOR).append(vlan);
- }
- s.append(TRUNK_SUFFIX);
- return getUUidFromString(s.toString());
- }
-
public static String getUUidFromString(String key) {
return java.util.UUID.nameUUIDFromBytes(key.getBytes()).toString();
}
- public static MacAddress resolveGwMac(DataBroker dataBroker, OdlArputilService arpUtilService, String vpnName,
- IpPrefix srcIpPrefix, IpAddress dstIpAddress, String interf) {
-
- String srcTpAddressStr = getIpAddressFromPrefix(MefUtils.ipPrefixToString(srcIpPrefix));
- IpAddress srcIpAddress = new IpAddress(srcTpAddressStr.toCharArray());
-
- if (srcIpAddress == null || dstIpAddress == null) {
- logger.error("Can't send ARP to srcIp {} dstIp {}", srcIpAddress, dstIpAddress);
- throw new RuntimeException("Can't send ARP for dstIp " + dstIpAddress);
+ public static String ipPrefixToString(IpPrefix ipAddress) {
+ if (ipAddress.getIpv4Prefix() != null) {
+ return ipAddress.getIpv4Prefix().getValue();
}
- MacAddress macAddress = null;
- int retries = MaxRetries;
- while (retries > 0 && macAddress == null) {
- logger.info("Sending ARP request to dstIp {} take {}", dstIpAddress, MaxRetries - retries + 1);
- sendArpRequest(arpUtilService, srcIpAddress, dstIpAddress, interf);
- macAddress = waitForArpReplyProcessing(dataBroker, vpnName, dstIpAddress, MaxRetries);
- retries--;
- }
- return macAddress;
+ return ipAddress.getIpv6Prefix().getValue();
}
- private static void sendArpRequest(OdlArputilService arpUtilService, IpAddress srcIpAddress, IpAddress dstIpAddress,
- String interf) {
- try {
- List<InterfaceAddress> interfaceAddresses = new ArrayList<>();
- interfaceAddresses
- .add(new InterfaceAddressBuilder().setInterface(interf).setIpAddress(srcIpAddress).build());
-
- SendArpRequestInput sendArpRequestInput = new SendArpRequestInputBuilder().setIpaddress(dstIpAddress)
- .setInterfaceAddress(interfaceAddresses).build();
- arpUtilService.sendArpRequest(sendArpRequestInput);
- } catch (Exception e) {
- logger.error("Failed to send ARP request to IP {} from interfaces {}",
- dstIpAddress.getIpv4Address().getValue(), interf, e);
- throw new RuntimeException(e.getMessage());
- }
- }
-
- public static MacAddress waitForArpReplyProcessing(DataBroker dataBroker, String vpnName, IpAddress dstIpAddress,
- int retries) {
- while (retries > 0) {
- logger.info("Waiting for ARP reply from dstIp {} take {}", dstIpAddress, MaxRetries - retries + 1);
- InstanceIdentifier<VpnPortipToPort> optionalPortIpId = buildVpnPortipToPortIdentifier(vpnName,
- MefUtils.ipAddressToString(dstIpAddress));
- Optional<VpnPortipToPort> optionalPortIp = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
- optionalPortIpId);
-
- if (optionalPortIp.isPresent()) {
- return new MacAddress(optionalPortIp.get().getMacAddress());
- } else {
- sleep();
- }
- retries--;
+ public static String ipAddressToString(IpAddress ipAddress) {
+ if (ipAddress.getIpv4Address() != null) {
+ return ipAddress.getIpv4Address().getValue();
}
- return null;
- }
- private static void sleep() {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
+ return ipAddress.getIpv6Address().getValue();
}
}
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniBuilder;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayersBuilder;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.LinksBuilder;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.LinkBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.Interface;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceBuilder;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfigBuilder;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger log = LoggerFactory.getLogger(NodeConnectorListener.class);
private static boolean generateMac = false;
- private static boolean handleRemovedNodeConnectors = false;
- private ListenerRegistration<NodeConnectorListener> evcListenerRegistration;
+ private final UniPortManager uniPortManager;
+ private ListenerRegistration<NodeConnectorListener> nodeConnectorListenerRegistration;
- public NodeConnectorListener(final DataBroker dataBroker, boolean generateMac) {
+ public NodeConnectorListener(final DataBroker dataBroker, final UniPortManager uniPortManager, final boolean generateMac) {
super(dataBroker);
+ this.uniPortManager = uniPortManager;
NodeConnectorListener.generateMac = generateMac;
registerListener();
}
try {
final DataTreeIdentifier<FlowCapableNodeConnector> dataTreeIid = new DataTreeIdentifier<>(
LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
- evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+ nodeConnectorListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
log.info("NodeConnectorListener created and registered");
configIntegrationBridge();
}
}
+ @SuppressWarnings("deprecation")
private InstanceIdentifier<FlowCapableNodeConnector> getInstanceIdentifier() {
return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
.augmentation(FlowCapableNodeConnector.class);
@Override
public void close() throws Exception {
- evcListenerRegistration.close();
+ nodeConnectorListenerRegistration.close();
}
@Override
}
}
+ @SuppressWarnings("deprecation")
private String getDpnIdFromNodeConnector(DataTreeModification<FlowCapableNodeConnector> newDataObject) {
InstanceIdentifier<FlowCapableNodeConnector> key = newDataObject.getRootPath().getRootIdentifier();
NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
return dpnFromNodeConnectorId;
}
+ @SuppressWarnings("deprecation")
private static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
/*
* NodeConnectorId is of form 'openflow:dpnid:portnum'
log.info("Adding mef uni/device interface {} with device {}", nodeConnector.getName(), dpnId);
- String uniName = NetvirtUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
- InstanceIdentifier interfacePath = MefUtils.getDeviceInterfaceInstanceIdentifier(dpnId, uniName);
+ String uniName = MefInterfaceUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
+ InstanceIdentifier<Interface> interfacePath = MefInterfaceUtils.getDeviceInterfaceInstanceIdentifier(dpnId,
+ uniName);
InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
interfaceBuilder.setPhy(new Identifier45(uniName));
- DataObject deviceInterface = interfaceBuilder.build();
+ Interface deviceInterface = interfaceBuilder.build();
+ tx.merge(LogicalDatastoreType.OPERATIONAL, interfacePath, deviceInterface, true);
- tx.merge(LogicalDatastoreType.CONFIGURATION, interfacePath, deviceInterface, true);
-
- InstanceIdentifier uniPath = MefUtils.getUniInstanceIdentifier(uniName);
+ InstanceIdentifier<Uni> uniPath = MefInterfaceUtils.getUniInstanceIdentifier(uniName);
UniBuilder uniBuilder = new UniBuilder();
uniBuilder.setUniId(new Identifier45(uniName));
uniBuilder.setMacAddress(nodeConnector.getHardwareAddress());
PhysicalLayersBuilder physicalLayersBuilder = new PhysicalLayersBuilder();
LinksBuilder linksBuilder = new LinksBuilder();
- List<Link> links = new ArrayList();
+ List<Link> links = new ArrayList<>();
LinkBuilder linkBuilder = new LinkBuilder();
linkBuilder.setDevice(new Identifier45(dpnId));
linkBuilder.setInterface(uniName);
linksBuilder.setLink(links);
physicalLayersBuilder.setLinks(linksBuilder.build());
uniBuilder.setPhysicalLayers(physicalLayersBuilder.build());
- DataObject uni = uniBuilder.build();
+ Uni uni = uniBuilder.build();
+ tx.merge(LogicalDatastoreType.OPERATIONAL, uniPath, uni, true);
- tx.merge(LogicalDatastoreType.CONFIGURATION, uniPath, uni, true);
CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
-
try {
futures.get();
} catch (InterruptedException | ExecutionException e) {
uniPath, uni);
throw new RuntimeException(e.getMessage());
}
+
+ // Reply UNI port configuration
+ uniPortManager.updateOperUni(uni.getUniId().getValue());
}
private void handleNodeConnectorRemoved(DataBroker dataBroker, String dpnId,
FlowCapableNodeConnector nodeConnector) {
- String uniName = NetvirtUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
-
- if (!handleRemovedNodeConnectors) {
- return;
+ String uniName = MefInterfaceUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
+ InstanceIdentifier<Interface> interfacePath = MefInterfaceUtils.getDeviceInterfaceInstanceIdentifier(dpnId,
+ uniName);
+ if (MefInterfaceUtils.getInterface(dataBroker, dpnId, uniName, LogicalDatastoreType.OPERATIONAL) != null) {
+ MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, interfacePath);
}
- MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getDeviceInterfaceInstanceIdentifier(dpnId, uniName));
-
- MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getUniLinkInstanceIdentifier(nodeConnector.getName(), dpnId, uniName));
+ // Reply UNI port configuration
+ uniPortManager.removeUniPorts(uniName);
+ InstanceIdentifier<Uni> uniPath = MefInterfaceUtils.getUniInstanceIdentifier(uniName);
+ if (MefInterfaceUtils.getUni(dataBroker, uniName, LogicalDatastoreType.OPERATIONAL) != null) {
+ MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, uniPath);
+ }
}
private void handleNodeConnectorUpdated(DataBroker dataBroker, String dpnFromNodeConnectorId,
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.Subnets;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ip.unis.IpUni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.IpvcVpn;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.IpvcChoice;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.Ipvc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.VpnElans;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.ipvc.choice.ipvc.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> implements ISubnetManager {
+ private static final Logger Log = LoggerFactory.getLogger(SubnetListener.class);
+ private ListenerRegistration<SubnetListener> subnetListenerRegistration;
+ private final NotificationPublishService notificationPublishService;
+ private final IGwMacListener gwMacListener;
+
+
+ public SubnetListener(final DataBroker dataBroker, final NotificationPublishService notPublishService,
+ final IGwMacListener gwMacListener ) {
+ super(dataBroker);
+ this.notificationPublishService = notPublishService;
+ this.gwMacListener = gwMacListener;
+ registerListener();
+ }
+
+ public void registerListener() {
+ try {
+ final DataTreeIdentifier<Subnet> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ MefInterfaceUtils.getSubnetsInstanceIdentifier());
+ subnetListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+ Log.info("IpvcDataTreeChangeListener created and registered");
+ } catch (final Exception e) {
+ Log.error("Ipvc DataChange listener registration failed !", e);
+ throw new IllegalStateException("Ipvc registration Listener failed.", e);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ subnetListenerRegistration.close();
+ }
+
+ @Override
+ public void add(DataTreeModification<Subnet> newDataObject) {
+ if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+ Log.info("subnet {} created", newDataObject.getRootNode().getIdentifier());
+ }
+
+ createNetwork(newDataObject);
+ }
+
+ @Override
+ public void remove(DataTreeModification<Subnet> removedDataObject) {
+ if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+ Log.info("subnet {} deleted", removedDataObject.getRootNode().getIdentifier());
+ }
+ removeNetwork(removedDataObject);
+ }
+
+ @Override
+ public void update(DataTreeModification<Subnet> modifiedDataObject) {
+ if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+ Log.info("subnet {} updated", modifiedDataObject.getRootNode().getIdentifier());
+ Log.info("process as delete / create");
+ removeNetwork(modifiedDataObject);
+ createNetwork(modifiedDataObject);
+ }
+ }
+
+ @Override
+ public void assignIpUniNetworks(Identifier45 uniId, Identifier45 ipUniId, InstanceIdentifier<Ipvc> ipvcId) {
+ InstanceIdentifier<Subnets> id = MefInterfaceUtils.getSubnetListInstanceIdentifier();
+ Optional<Subnets> allList = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ Subnets allSubnets = allList.isPresent() ? allList.get() : null;
+ List<Subnet> allSubnet = allSubnets != null && allSubnets.getSubnet() != null ? allSubnets.getSubnet()
+ : Collections.emptyList();
+ List<Subnet> ipUniSubnets = allSubnet.stream()
+ .filter(s -> s.getUniId().equals(uniId) && s.getIpUniId().equals(ipUniId)).collect(Collectors.toList());
+ // recreate networks on restart
+ ipUniSubnets.forEach(s -> createNetwork(s, uniId, ipUniId));
+ }
+
+ @Override
+ public void unAssignIpUniNetworks(Identifier45 uniId, Identifier45 ipUniId, InstanceIdentifier<Ipvc> ipvcId) {
+ InstanceIdentifier<Subnets> id = MefInterfaceUtils.getSubnetListInstanceIdentifier();
+ Optional<Subnets> allList = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ Subnets allSubnets = allList.isPresent() ? allList.get() : null;
+ List<Subnet> allSubnet = allSubnets != null && allSubnets.getSubnet() != null ? allSubnets.getSubnet()
+ : Collections.emptyList();
+ List<Subnet> ipUniSubnets = allSubnet.stream()
+ .filter(s -> s.getUniId().equals(uniId) && s.getIpUniId().equals(ipUniId)).collect(Collectors.toList());
+ ipUniSubnets.forEach(s -> removeNetwork(s, uniId, ipUniId, ipvcId));
+ }
+
+
+ private void createNetwork(DataTreeModification<Subnet> newDataObject) {
+ Subnet newSubnet = newDataObject.getRootNode().getDataAfter();
+
+ Identifier45 nwUniId = newSubnet.getUniId();
+ Identifier45 nwIpUniId = newSubnet.getIpUniId();
+
+ createNetwork(newSubnet, nwUniId, nwIpUniId);
+ }
+
+ private void createNetwork(Subnet newSubnet, Identifier45 nwUniId, Identifier45 nwIpUniId) {
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
+
+ InstanceIdentifier<Ipvc> ipvcId = findService(nwUniId, nwIpUniId);
+ if (ipvcId == null) {
+ Log.info("Subnet Uni {} IpUNI {} is not assosiated to service", nwUniId, nwIpUniId);
+ return;
+ }
+ IpvcVpn ipvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+ if (ipvcVpn == null || ipvcVpn.getVpnElans() == null) {
+ Log.error("Subnet Uni {} IpUNI {} is not operational", nwUniId, nwIpUniId);
+ return;
+ }
+ VpnElans vpnElan = MefServicesUtils.findVpnForNetwork(newSubnet, ipvcVpn);
+ if (vpnElan == null) {
+ Log.error("Subnet Uni {} IpUNI {} for network {} is not operational", nwUniId, nwIpUniId, subnetStr);
+ return;
+ }
+ if (MefServicesUtils.findNetwork(newSubnet, vpnElan) != null) {
+ Log.info("Network {} exists already", subnetStr);
+ return;
+ }
+
+ String vpnId = ipvcVpn.getVpnId();
+ synchronized (vpnId.intern()) {
+ if (newSubnet.getGateway() == null) {
+ checkCreateDirectNetwork(newSubnet, ipvcVpn, ipvcId, vpnElan);
+ } else {
+ createNonDirectNetwork(newSubnet, ipvcVpn, ipvcId, vpnElan);
+ }
+ }
+ MefServicesUtils.addOperIpvcVpnElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), nwUniId, nwIpUniId,
+ vpnElan.getElanId(), vpnElan.getElanPort(), Collections.singletonList(subnetStr));
+
+ }
+
+ private void createNonDirectNetwork(Subnet newSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId,
+ VpnElans vpnElan) {
+ if (newSubnet.getGateway() == null) {
+ return;
+ }
+
+ Identifier45 nwUniId = newSubnet.getUniId();
+ Identifier45 nwIpUniId = newSubnet.getIpUniId();
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
+
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, nwUniId, nwIpUniId, LogicalDatastoreType.CONFIGURATION);
+ if (ipUni == null) {
+ Log.error("Uni {} IpUni {} for network {} is not operational", nwUniId, nwIpUniId, subnetStr);
+ return;
+ }
+
+ String srcTpAddressStr = NetvirtVpnUtils.getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
+ IpAddress srcIpAddress = new IpAddress(srcTpAddressStr.toCharArray());
+ String subnet = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
+ gwMacListener.resolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress, newSubnet.getGateway(), subnet);
+ }
+
+ private void checkCreateDirectNetwork(Subnet newSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId,
+ VpnElans vpnElan) {
+ if (newSubnet.getGateway() != null) {
+ return;
+ }
+
+ NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, ipvcVpn.getVpnId(),
+ vpnElan.getElanId(), newSubnet.getSubnet(), vpnElan.getElanPort());
+
+ }
+
+ private void removeNetwork(DataTreeModification<Subnet> deletedDataObject) {
+ Subnet deletedSubnet = deletedDataObject.getRootNode().getDataBefore();
+ Identifier45 dlUniId = deletedSubnet.getUniId();
+ Identifier45 dlIpUniId = deletedSubnet.getIpUniId();
+ InstanceIdentifier<Ipvc> ipvcId = findService(dlUniId, dlIpUniId);
+ if (ipvcId == null) {
+ Log.info("Subnet Uni {} IpUNI {} for deleted network is not assosiated to service", dlUniId, dlIpUniId);
+ return;
+ }
+ removeNetwork(deletedSubnet, dlUniId, dlIpUniId, ipvcId);
+ }
+
+ private void removeNetwork(Subnet dlSubnet, Identifier45 dlUniId, Identifier45 dlIpUniId,
+ InstanceIdentifier<Ipvc> ipvcId) {
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(dlSubnet.getSubnet());
+ IpvcVpn ipvcVpn = MefServicesUtils.getOperIpvcVpn(dataBroker, ipvcId);
+ if (ipvcVpn == null || ipvcVpn.getVpnElans() == null) {
+ Log.error("Subnet Uni {} IpUNI {} is not operational", dlUniId, dlIpUniId);
+ return;
+ }
+ VpnElans vpnElan = MefServicesUtils.findVpnForNetwork(dlSubnet, ipvcVpn);
+ if (vpnElan == null) {
+ Log.error("Trying to remove non-operational network {}", subnetStr);
+ return;
+ }
+ if (MefServicesUtils.findNetwork(dlSubnet, vpnElan) == null) {
+ Log.error("Trying to remove non-operational network {}", subnetStr);
+ return;
+ }
+
+ String vpnId = ipvcVpn.getVpnId();
+ synchronized (vpnId.intern()) {
+ if (dlSubnet.getGateway() == null) {
+ removeDirectNetwork(dlSubnet, ipvcVpn, ipvcId);
+ } else {
+ removeNonDirectNetwork(dlSubnet, ipvcVpn, ipvcId);
+ }
+ }
+ MefServicesUtils.removeOperIpvcSubnet(dataBroker, ipvcId, ipvcVpn.getVpnId(), dlUniId, dlIpUniId,
+ vpnElan.getElanId(), vpnElan.getElanPort(), subnetStr);
+ }
+
+
+ private void removeDirectNetwork(Subnet deletedSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId) {
+ if (deletedSubnet.getGateway() != null) {
+ return;
+ }
+
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(deletedSubnet.getSubnet());
+ VpnElans vpnElan = MefServicesUtils.findVpnForNetwork(deletedSubnet, ipvcVpn);
+ if (vpnElan == null) {
+ Log.error("Network {} has not been created as required, nothing to remove", subnetStr);
+ return;
+ }
+
+ NetvirtVpnUtils.removeDirectSubnetFromVpn(dataBroker, notificationPublishService, ipvcVpn.getVpnId(),
+ vpnElan.getElanId(), vpnElan.getElanPort());
+
+ }
+
+ private void removeNonDirectNetwork(Subnet deletedSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId) {
+ if (deletedSubnet.getGateway() == null) {
+ return;
+ }
+
+ Identifier45 nwUniId = deletedSubnet.getUniId();
+ Identifier45 nwIpUniId = deletedSubnet.getIpUniId();
+ String subnetStr = NetvirtVpnUtils.ipPrefixToString(deletedSubnet.getSubnet());
+ VpnElans vpnElan = MefServicesUtils.findVpnForNetwork(deletedSubnet, ipvcVpn);
+ if (vpnElan == null) {
+ Log.error("Network {} has not been created as required, nothing to remove", subnetStr);
+ return;
+ }
+
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, nwUniId, nwIpUniId, LogicalDatastoreType.CONFIGURATION);
+ if (ipUni == null) {
+ Log.error("Uni {} IpUni {} for network {} is not operational", nwUniId, nwIpUniId, subnetStr);
+ return;
+ }
+
+ String srcTpAddressStr = NetvirtVpnUtils.getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
+ IpAddress srcIpAddress = new IpAddress(srcTpAddressStr.toCharArray());
+ gwMacListener.unResolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress, deletedSubnet.getGateway() );
+
+ NetvirtVpnUtils.removeVpnInterfaceAdjacency(dataBroker, vpnElan.getElanPort(), deletedSubnet.getSubnet());
+ NetvirtVpnUtils.removeVpnInterfaceAdjacency(dataBroker, vpnElan.getElanPort(), deletedSubnet.getGateway());
+ }
+
+ private InstanceIdentifier<Ipvc> findService(Identifier45 uniId, Identifier45 ipUniId) {
+ InstanceIdentifier<MefServices> path = MefServicesUtils.getMefServicesInstanceIdentifier();
+ Optional<MefServices> mefServices = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+ if (!mefServices.isPresent() || mefServices.get() == null) {
+ Log.info("Uni {} IpUni {} is not assosiated with service", uniId, ipUniId);
+ return null;
+ }
+ for (MefService service : mefServices.get().getMefService()) {
+ if (service.getMefServiceChoice() instanceof IpvcChoice) {
+ Ipvc ipvc = ((IpvcChoice) service.getMefServiceChoice()).getIpvc();
+ if (ipvc.getUnis() == null || ipvc.getUnis().getUni() == null) {
+ continue;
+ }
+ List<Uni> unis = ipvc.getUnis().getUni();
+ for (Uni uni : unis) {
+ if (uni.getUniId().equals(uniId) && uni.getIpUniId().equals(ipUniId)) {
+ Log.info("Find service {} for uni {} ipuni {}", service.getSvcId(), uniId, ipUniId);
+ return MefServicesUtils.getIpvcsInstanceIdentifier(service.getSvcId());
+ }
+ }
+ }
+ }
+ Log.info("Uni {} IpUni {} is not assosiated with service", uniId, ipUniId);
+ return null;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.unimgr.mef.netvirt;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefServiceBuilder;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.EvcChoice;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TenantEnhancerUtils {
- private static final Logger log = LoggerFactory.getLogger(TenantEnhancerUtils.class);
-
- public static boolean isServiceTenanted(MefService service) {
- return service.getTenantId().equals("");
- }
-
- public static boolean isUniTenanted(
- org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni) {
- return uni.getTenantId().equals("");
- }
-
- public static void updateService(DataBroker dataBroker, String tenant, MefService service) {
- log.info("service is {}", service);
-
- MefServiceBuilder builder = new MefServiceBuilder();
- builder.setKey(service.getKey());
- builder.setTenantId(tenant);
- MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getMefServiceInstanceIdentifier(service.getSvcId()), service);
- }
-
- public static Evc GetEvc(MefService service) {
- if (!(service.getMefServiceChoice() instanceof EvcChoice)) {
- return null;
- }
-
- return ((EvcChoice) service.getMefServiceChoice()).getEvc();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.unimgr.mef.netvirt;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-public class TenantUniListener extends UnimgrDataTreeChangeListener<Uni> {
-
- private static final Logger log = LoggerFactory.getLogger(TenantUniListener.class);
- private ListenerRegistration<TenantUniListener> evcListenerRegistration;
-
- public TenantUniListener(final DataBroker dataBroker) {
- super(dataBroker);
-
- registerListener();
- }
-
- public void registerListener() {
- try {
- final DataTreeIdentifier<Uni> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
- MefUtils.getUniListInterfaceInstanceIdentifier());
- evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
- log.info("TenantUniListener created and registered");
- } catch (final Exception e) {
- log.error("TenantUniListener registration failed !", e);
- throw new IllegalStateException("Evc registration Listener failed.", e);
- }
- }
-
- @Override
- public void close() throws Exception {
- evcListenerRegistration.close();
- }
-
- @Override
- public void add(DataTreeModification<Uni> newDataObject) {
- log.info("received add Uni notification");
- handleUniChanged(newDataObject.getRootNode().getDataAfter());
- }
-
- @Override
- public void remove(DataTreeModification<Uni> removedDataObject) {
- }
-
- @Override
- public void update(DataTreeModification<Uni> modifiedDataObject) {
- log.info("received update Uni notification");
- handleUniChanged(modifiedDataObject.getRootNode().getDataAfter());
- }
-
- private void handleUniChanged(Uni uni) {
- if (!TenantEnhancerUtils.isUniTenanted(uni)) {
- return;
- }
-
- String tenant = uni.getTenantId();
-
- Optional<MefServices> optionalServices = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getMefServicesInstanceIdentifier());
- if (!optionalServices.isPresent()) {
- return;
- }
-
- for (MefService service : optionalServices.get().getMefService()) {
- for (org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni serviceUni : TenantEnhancerUtils
- .GetEvc(service).getUnis().getUni()) {
- if (!TenantEnhancerUtils.isServiceTenanted(service) && serviceUni.getUniId().equals(uni.getUniId())) {
- log.info("instance identifier is {}", MefUtils.getMefServiceInstanceIdentifier(service.getSvcId()));
- TenantEnhancerUtils.updateService(dataBroker, tenant, service);
- }
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.unimgr.mef.netvirt;
-
-import java.util.List;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-public class TenantlessEvcListener extends UnimgrDataTreeChangeListener<MefService> {
-
- private static final Logger log = LoggerFactory.getLogger(TenantlessEvcListener.class);
- private ListenerRegistration<TenantlessEvcListener> evcListenerRegistration;
-
- public TenantlessEvcListener(final DataBroker dataBroker) {
- super(dataBroker);
-
- registerListener();
- }
-
- public void registerListener() {
- try {
- final DataTreeIdentifier<MefService> dataTreeIid = new DataTreeIdentifier<>(
- LogicalDatastoreType.CONFIGURATION, MefUtils.getMefServiceInstanceIdentifier());
- evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
- log.info("TenantlessEvcListener created and registered");
- } catch (final Exception e) {
- log.error("TenantlessEvcListener registration failed !", e);
- throw new IllegalStateException("Evc registration Listener failed.", e);
- }
- }
-
- @Override
- public void close() throws Exception {
- evcListenerRegistration.close();
- }
-
- @Override
- public void add(DataTreeModification<MefService> newDataObject) {
- if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
- log.info("service {} created", newDataObject.getRootNode().getIdentifier());
- handleService(newDataObject.getRootNode().getDataAfter());
- }
- }
-
- @Override
- public void remove(DataTreeModification<MefService> removedDataObject) {
- }
-
- @Override
- public void update(DataTreeModification<MefService> modifiedDataObject) {
- if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
- log.info("service {} updated", modifiedDataObject.getRootNode().getIdentifier());
- handleService(modifiedDataObject.getRootNode().getDataAfter());
- }
- }
-
- private void handleService(MefService service) {
- if (TenantEnhancerUtils.isServiceTenanted(service)) {
- log.info("Service {} is already connected to a Service", service.getSvcId().getValue());
- return;
- }
- Evc evc = TenantEnhancerUtils.GetEvc(service);
- if (evc.getUnis() == null) {
- log.info("No UNI's in service {}, exiting", service.getSvcId().getValue());
- return;
- }
- List<Uni> unis = evc.getUnis().getUni();
- for (Uni uni : unis) {
- Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni> optonalUniInterface = MdsalUtils
- .read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- MefUtils.getUniInstanceIdentifier(uni.getUniId().getValue()));
- if (optonalUniInterface.isPresent()) {
- org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uniInterface = optonalUniInterface
- .get();
- if (TenantEnhancerUtils.isUniTenanted(uniInterface)) {
- String tenant = uniInterface.getTenantId();
- log.info("updating service {} with tenant {}", service.getSvcId().getValue(), tenant);
- TenantEnhancerUtils.updateService(dataBroker, tenant, service);
- return;
- }
- } else {
- log.info("Couldn't find uni {}", uni.getUniId());
- }
- }
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.PortVlanMapping;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.PortVlanMappingBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.CeVlansBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.VlanToPort;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.VlanToPortBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ce.vlans.CeVlan;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.ce.vlans.CeVlanBuilder;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.VlanIdOrNoneType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.VlanIdType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+
+public class UniPortManager extends UnimgrDataTreeChangeListener<Uni> implements IUniPortManager {
+
+ private static final Logger log = LoggerFactory.getLogger(UniPortManager.class);
+ private ListenerRegistration<UniPortManager> uniListenerRegistration;
+ private static int maxWaitRetries = 3;
+
+ public UniPortManager(final DataBroker dataBroker) {
+ super(dataBroker);
+
+ registerListener();
+ }
+
+ public void registerListener() {
+ try {
+ final DataTreeIdentifier<Uni> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ getInstanceIdentifier());
+ uniListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+ log.info("UniPortListener created and registered");
+ } catch (final Exception e) {
+ log.error("UniPortListener registration failed !", e);
+ throw new IllegalStateException("UniPortListener registration failed.", e);
+ }
+ }
+
+ private InstanceIdentifier<Uni> getInstanceIdentifier() {
+ return MefInterfaceUtils.getUniListInstanceIdentifier();
+ }
+
+ @Override
+ public void close() throws Exception {
+ uniListenerRegistration.close();
+ }
+
+ @Override
+ public void add(DataTreeModification<Uni> newDataObject) {
+ if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+ log.info("uni node {} created", newDataObject.getRootNode().getIdentifier());
+ }
+ Uni confUni = newDataObject.getRootNode().getDataAfter();
+ String uniId = confUni.getUniId().getValue();
+
+ synchronized (uniId.intern()) {
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ addCheckUniPorts(confUni);
+ }
+ }
+
+ @Override
+ public void remove(DataTreeModification<Uni> removedDataObject) {
+ if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+ log.info("uni node {} deleted", removedDataObject.getRootNode().getIdentifier());
+ }
+ Uni confUni = removedDataObject.getRootNode().getDataBefore();
+ String uniId = confUni.getUniId().getValue();
+ synchronized (uniId.intern()) {
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ removeUniPorts(confUni);
+ }
+ }
+
+ @Override
+ public void update(DataTreeModification<Uni> modifiedDataObject) {
+ if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+ log.info("node connector {} updated", modifiedDataObject.getRootNode().getIdentifier());
+ }
+ Uni confUni = modifiedDataObject.getRootNode().getDataAfter();
+ String uniId = confUni.getUniId().getValue();
+ synchronized (uniId.intern()) {
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ removeCheckUniPorts(confUni);
+ addCheckUniPorts(confUni);
+ }
+ }
+
+ @Override
+ public void updateOperUni(String uniId) {
+ Uni confUni = MefInterfaceUtils.getUni(dataBroker, uniId, LogicalDatastoreType.CONFIGURATION);
+ if (confUni == null) {
+ log.debug("No UNI {} exists, nothing to update");
+ return;
+ }
+ synchronized (uniId.intern()) {
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ log.info("UNI {} ports updated", uniId);
+
+ removeCheckUniPorts(confUni);
+ addCheckUniPorts(confUni);
+ }
+ }
+
+ @Override
+ public void removeUniPorts(String uniId) {
+ Uni confUni = MefInterfaceUtils.getUni(dataBroker, uniId, LogicalDatastoreType.CONFIGURATION);
+ if (confUni == null) {
+ log.debug("No UNI {} exists, nothing to update");
+ return;
+ }
+ synchronized (uniId.intern()) {
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ removeUniPorts(confUni);
+ }
+ }
+
+ private boolean checkOperUni(String uniId) {
+ Uni operUni = MefInterfaceUtils.getUni(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
+ if (operUni == null) {
+ log.info("Uni {} is not operational", uniId);
+ return false;
+ }
+ return true;
+ }
+
+ private void addCheckUniPorts(Uni confUni) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+
+ String uniId = confUni.getUniId().getValue();
+ Link link = MefInterfaceUtils.getLink(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
+ String trunkInterface = MefInterfaceUtils.getInterfaceNameForVlan(uniId, null);
+ String parentInterfaceName = MefInterfaceUtils.getTrunkParentName(link);
+ List<VlanToPort> operVlanInterfaces = getOperTrunkInterfaces(uniId);
+ if (!hasVlanPort(operVlanInterfaces, Long.valueOf(0))) {
+ VlanToPort newOperVlanInterface = addTrunkInterface(trunkInterface, parentInterfaceName, tx);
+ operVlanInterfaces.add(newOperVlanInterface);
+ }
+
+ List<CeVlan> ceVlans = confUni.getCeVlans() != null ? confUni.getCeVlans().getCeVlan()
+ : Collections.emptyList();
+ for (CeVlan ceVlan : ceVlans) {
+ Long vlan = ceVlan.getVid().getValue().longValue();
+ if (hasVlanPort(operVlanInterfaces, vlan)) {
+ continue;
+ }
+
+ String trunkMemberName = MefInterfaceUtils.getInterfaceNameForVlan(uniId, vlan);
+ VlanToPort newOperVlanInterface = addTrunkMemberInterface(trunkMemberName, trunkInterface, vlan, tx);
+ operVlanInterfaces.add(newOperVlanInterface);
+ }
+ // set VlanMapping to Uni
+ setOperTrunkInterfaces(uniId, operVlanInterfaces, tx);
+
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ private void removeCheckUniPorts(Uni confUni) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+
+ List<CeVlan> ceVlans = confUni.getCeVlans() != null ? confUni.getCeVlans().getCeVlan()
+ : Collections.emptyList();
+ List<Long> vlansValue = ceVlans.stream().map(x -> x.getVid().getValue()).collect(Collectors.toList());
+
+ String uniId = confUni.getUniId().getValue();
+ List<VlanToPort> operVlanInterfaces = getOperTrunkInterfaces(uniId);
+
+ for (VlanToPort oldPort : getOperTrunkInterfaces(uniId)) {
+ Long oldVlan = oldPort.getVlan().getValue();
+ if (!vlansValue.contains(oldVlan)) {
+ VlanToPort removedOperVlanInterface = removeTrunkInterface(oldPort.getVlanPortId(), oldVlan, tx);
+ operVlanInterfaces.remove(removedOperVlanInterface);
+ }
+ }
+ // set VlanMapping to Uni
+ setOperTrunkInterfaces(uniId, operVlanInterfaces, tx);
+
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ private void removeUniPorts(Uni confUni) {
+ WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+ String uniId = confUni.getUniId().getValue();
+
+ for (VlanToPort oldPort : getOperTrunkInterfaces(uniId)) {
+ Long oldVlan = oldPort.getVlan().getValue();
+ removeTrunkInterface(oldPort.getVlanPortId(), oldVlan, tx);
+ }
+ setOperTrunkInterfaces(uniId, new ArrayList<>(), tx);
+
+ MdsalUtils.commitTransaction(tx);
+ }
+
+ private VlanToPort addTrunkInterface(String interfaceName, String parentInterfaceName, WriteTransaction tx) {
+ log.info("Adding VLAN trunk {} ParentRef {}", interfaceName, parentInterfaceName);
+ Interface trunkInterface = NetvirtUtils.createTrunkInterface(interfaceName, parentInterfaceName);
+ NetvirtUtils.writeInterface(trunkInterface, tx);
+ return createOperTrunkInterfaceMapping(Long.valueOf(0), trunkInterface.getName());
+ }
+
+ private VlanToPort addTrunkMemberInterface(String interfaceName, String parentInterfaceName, Long vlan,
+ WriteTransaction tx) {
+ log.info("Adding VLAN trunk member {} ParentRef {}", interfaceName, parentInterfaceName);
+ Interface trunkInterface = NetvirtUtils.createTrunkMemberInterface(interfaceName, parentInterfaceName,
+ vlan.intValue());
+ NetvirtUtils.writeInterface(trunkInterface, tx);
+ return createOperTrunkInterfaceMapping(vlan, trunkInterface.getName());
+ }
+
+ private VlanToPort removeTrunkInterface(String interfaceName, Long vlan, WriteTransaction tx) {
+ log.info("Delete VLAN trunk {} ParentRef {}", interfaceName);
+ NetvirtUtils.deleteInterface(interfaceName, tx);
+ return createOperTrunkInterfaceMapping(vlan, interfaceName);
+ }
+
+ private List<VlanToPort> getOperTrunkInterfaces(String operUniId) {
+ InstanceIdentifier<Uni> identifier = MefInterfaceUtils.getUniInstanceIdentifier(operUniId);
+ InstanceIdentifier<PortVlanMapping> path = identifier.augmentation(PortVlanMapping.class);
+ Optional<PortVlanMapping> portVlanMapping = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+ if (portVlanMapping.isPresent()) {
+ return portVlanMapping.get().getVlanToPort();
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ private void setOperTrunkInterfaces(String operUniId, List<VlanToPort> vlanToPort, WriteTransaction tx) {
+ InstanceIdentifier<Uni> identifier = MefInterfaceUtils.getUniInstanceIdentifier(operUniId);
+ InstanceIdentifier<PortVlanMapping> path = identifier.augmentation(PortVlanMapping.class);
+
+ PortVlanMappingBuilder portVlanMappingB = new PortVlanMappingBuilder();
+ portVlanMappingB.setVlanToPort(vlanToPort);
+
+ tx.put(LogicalDatastoreType.OPERATIONAL, path, portVlanMappingB.build());
+ }
+
+ private VlanToPort createOperTrunkInterfaceMapping(Long vlan, String interfaceName) {
+ final Long vlanNotNull = replaceNull(vlan);
+
+ VlanToPortBuilder vlanToPortBuilder = new VlanToPortBuilder();
+ vlanToPortBuilder.setVlan(new VlanIdOrNoneType(vlanNotNull));
+ vlanToPortBuilder.setVlanPortId(interfaceName);
+ return vlanToPortBuilder.build();
+ }
+
+ private boolean hasVlanPort(List<VlanToPort> vlanInterfaces, Long vlan) {
+ if (vlanInterfaces == null) {
+ return false;
+ }
+ final Long vlanNotNull = replaceNull(vlan);
+
+ if (vlanInterfaces.stream().filter(x -> x.getVlan().getValue().equals(vlanNotNull)).findAny().isPresent()) {
+ return true;
+ }
+ return false;
+ }
+
+ private static final Long replaceNull(Long vlan) {
+ if (vlan == null) {
+ return Long.valueOf(0);
+ }
+ return vlan;
+ }
+
+ @Override
+ public void addCeVlan(String uniId, Long vlanId) {
+ if (getUniVlanInterfaceNoRetry(uniId, vlanId) != null) {
+ log.debug("UNI {} Port for vlan {} exists already, nothing to update", uniId, vlanId);
+ return;
+ }
+ synchronized (uniId.intern()) {
+ Uni confUni = MefInterfaceUtils.getUni(dataBroker, uniId, LogicalDatastoreType.CONFIGURATION);
+ if (confUni == null) {
+ log.debug("No UNI {} exists, nothing to update");
+ return;
+ }
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ log.info("UNI {} Vlan {} adding", uniId, vlanId);
+ List<CeVlan> ceVlans = confUni.getCeVlans() != null ? confUni.getCeVlans().getCeVlan() : new ArrayList<>();
+ CeVlanBuilder ceVlanBuilder = new CeVlanBuilder();
+ ceVlanBuilder.setVid(new VlanIdType(vlanId));
+ CeVlansBuilder ceVlansBuilder = confUni.getCeVlans() != null ? new CeVlansBuilder(confUni.getCeVlans())
+ : new CeVlansBuilder();
+ ceVlans.add(ceVlanBuilder.build());
+ ceVlansBuilder.setCeVlan(ceVlans);
+ UniBuilder uniBuilder = new UniBuilder();
+ uniBuilder.setUniId(confUni.getUniId());
+ uniBuilder.setCeVlans(ceVlansBuilder.build());
+ MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ MefInterfaceUtils.getUniInstanceIdentifier(uniId), uniBuilder.build());
+ }
+ }
+
+ @Override
+ public void removeCeVlan(String uniId, Long vlanId) {
+ if (getUniVlanInterfaceNoRetry(uniId, vlanId) == null) {
+ log.debug("No UNI {} Port for vlan {} exists already, nothing to delete", uniId, vlanId);
+ return;
+ }
+ synchronized (uniId.intern()) {
+ Uni confUni = MefInterfaceUtils.getUni(dataBroker, uniId, LogicalDatastoreType.CONFIGURATION);
+ if (confUni == null) {
+ log.debug("No UNI {} exists, nothing to update");
+ return;
+ }
+ if (!checkOperUni(uniId)) {
+ return;
+ }
+ log.info("UNI {} Vlan {} deleting", uniId, vlanId);
+ UniBuilder uniBuilder = new UniBuilder(confUni);
+
+ if (vlanId != null && vlanId != 0l) {
+ List<CeVlan> ceVlans = confUni.getCeVlans() != null ? confUni.getCeVlans().getCeVlan()
+ : Collections.emptyList();
+ CeVlanBuilder ceVlanBuilder = new CeVlanBuilder();
+ ceVlanBuilder.setVid(new VlanIdType(vlanId));
+ CeVlansBuilder ceVlansBuilder = new CeVlansBuilder(confUni.getCeVlans());
+ ceVlans.remove(ceVlanBuilder.build());
+ ceVlansBuilder.setCeVlan(ceVlans);
+ uniBuilder.setCeVlans(ceVlansBuilder.build());
+ } else {
+ uniBuilder.setCeVlans(null);
+ }
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ MefInterfaceUtils.getUniInstanceIdentifier(uniId), uniBuilder.build());
+ }
+
+ }
+
+ @Override
+ public List<String> getUniVlanInterfaces(String uniId) {
+ synchronized (uniId.intern()) {
+ List<VlanToPort> vlanToPorts = getOperTrunkInterfaces(uniId);
+ return vlanToPorts.stream().map(port -> port.getVlanPortId()).collect(Collectors.toList());
+ }
+ }
+
+ @Override
+ public String getUniVlanInterface(String uniId, Long vlanId) {
+ Long vlanNotNull = replaceNull(vlanId);
+ return getUniVlanInterfaceRetry(uniId, vlanNotNull, 0);
+ }
+
+ public String getUniVlanInterfaceNoRetry(String uniId, Long vlanId) {
+ Long vlanNotNull = replaceNull(vlanId);
+ return getUniVlanInterfaceRetry(uniId, vlanNotNull, maxWaitRetries);
+ }
+
+ private String getUniVlanInterfaceRetry(String uniId, Long vlanId, int retries) {
+ log.trace("Retry {} to wait for uniId {} vlan {} interface", retries, uniId, vlanId);
+ List<VlanToPort> vlanToPorts = getOperTrunkInterfaces(uniId);
+ java.util.Optional<String> toReturn = vlanToPorts.stream()
+ .filter(port -> port.getVlan().getValue().equals(vlanId)).map(port -> port.getVlanPortId()).findFirst();
+ if (toReturn.isPresent()) {
+ return toReturn.get();
+ } else {
+ if (retries >= maxWaitRetries) {
+ return null;
+ }
+ NetvirtUtils.safeSleep();
+ return getUniVlanInterfaceRetry(uniId, vlanId, ++retries);
+ }
+ }
+}
-<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights
- reserved. This program and the accompanying materials are made available
- under the terms of the Eclipse Public License v1.0 which accompanies this
- distribution, and is available at http://www.eclipse.org/legal/epl-v10.html -->
+<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights
+ reserved. This program and the accompanying materials are made available
+ under the terms of the Eclipse Public License v1.0 which accompanies this
+ distribution, and is available at http://www.eclipse.org/legal/epl-v10.html -->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
- odl:use-default-for-reference-types="true">
-
- <reference id="dataBroker"
- interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
- <reference id="notificationPublishService"
- interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService" />
- <odl:rpc-service id="odlArputilService"
- interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
-
- <bean class="org.opendaylight.unimgr.mef.netvirt.EvcListener">
- <argument index="0" ref="dataBroker" />
- </bean>
-
- <bean class="org.opendaylight.unimgr.mef.netvirt.NodeConnectorListener">
- <argument index="0" ref="dataBroker" />
- <argument index="1" value="false" />
- </bean>
-
- <!-- <bean class="org.opendaylight.unimgr.mef.netvirt.TenantlessEvcListener"> -->
- <!-- <argument index="0" ref="dataBroker" /> -->
- <!-- </bean> -->
-
- <!-- <bean class="org.opendaylight.unimgr.mef.netvirt.TenantUniListener"> -->
- <!-- <argument index="0" ref="dataBroker" /> -->
- <!-- </bean> -->
-
- <bean class="org.opendaylight.unimgr.mef.netvirt.IpvcListener">
- <argument ref="dataBroker" />
- <argument ref="notificationPublishService" />
- <argument ref="odlArputilService" />
- </bean>
-
-</blueprint>
\ No newline at end of file
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <reference id="dataBroker"
+ interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
+ <reference id="notificationPublishService"
+ interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService" />
+ <odl:rpc-service id="odlArputilService"
+ interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
+
+
+ <bean id="uniPortManager" class="org.opendaylight.unimgr.mef.netvirt.UniPortManager">
+ <argument ref="dataBroker" />
+ </bean>
+
+ <bean id="nodeConnectorListener"
+ class="org.opendaylight.unimgr.mef.netvirt.NodeConnectorListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ <argument value="false" />
+ </bean>
+
+ <bean id="evcListener" class="org.opendaylight.unimgr.mef.netvirt.EvcListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ </bean>
+
+ <bean id="ipvcListener" class="org.opendaylight.unimgr.mef.netvirt.IpvcListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ <argument ref="subnetListener" />
+ </bean>
+
+ <bean id="subnetListener" class="org.opendaylight.unimgr.mef.netvirt.SubnetListener">
+ <argument ref="dataBroker" />
+ <argument ref="notificationPublishService" />
+ <argument ref="qwMacListener" />
+ </bean>
+
+ <bean id="qwMacListener" class="org.opendaylight.unimgr.mef.netvirt.GwMacListener">
+ <argument ref="dataBroker" />
+ <argument ref="odlArputilService" />
+ <argument value="10" />
+ </bean>
+</blueprint>
+