Skip to content

Commit

Permalink
Started adding the QinQ test case
Browse files Browse the repository at this point in the history
  • Loading branch information
bfinnema committed Jul 7, 2024
1 parent 5fb6e34 commit 07439c2
Show file tree
Hide file tree
Showing 63 changed files with 1,950 additions and 0 deletions.
23 changes: 23 additions & 0 deletions l3vpn_qinq_cfs/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
This is a generated Python package, made by:

ncs-make-package --service-skeleton python-and-template \
--component-class main.Main l3vpn_qinq_cfs

It contains a dummy YANG model which implements a minimal Service
and an Action that doesn't really do anything useful. They are
there just to get you going.

You will also find two test cases in:

test/internal/lux/service/
test/internal/lux/action/

that you can run if you have the 'lux' testing tool.
Your top Makefile also need to implement some Make targets
as described in the Makefiles of the test cases.
You can also just read the corresponding run.lux tests and
do them manually if you wish.

The 'lux' test tool can be obtained from:

https://github.com/hawk/lux.git
Binary file added l3vpn_qinq_cfs/load-dir/l3vpn_qinq_cfs.fxs
Binary file not shown.
13 changes: 13 additions & 0 deletions l3vpn_qinq_cfs/package-meta-data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<ncs-package xmlns="http://tail-f.com/ns/ncs-packages">
<name>l3vpn_qinq_cfs</name>
<package-version>1.0</package-version>
<description>Generated Python package</description>
<ncs-min-version>6.2</ncs-min-version>

<component>
<name>main</name>
<application>
<python-class-name>l3vpn_qinq_cfs.main.Main</python-class-name>
</application>
</component>
</ncs-package>
Empty file.
44 changes: 44 additions & 0 deletions l3vpn_qinq_cfs/python/l3vpn_qinq_cfs/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- mode: python; python-indent: 4 -*-
import ncs
from ncs.application import Service
import requests

class ServiceCallbacks(Service):

@Service.create
def cb_create(self, tctx, root, service, proplist):
self.log.info('Service create(service=', service._path, ')')

api_url="http://10.101.180.45/api/ipam/prefixes/1/available-ips/"
headers = {"Authorization":"Token e657404c0e1f57481ad0a06c293e8fe794e720ac"}

vars = ncs.template.Variables()
template = ncs.template.Template(service)
for endpoint in service.endpoint:
# PE part
response=requests.get(api_url, headers=headers, verify=False)
self.log.info('Netbox response: ', response.json)
ipv4_address = response.json["address"]
self.log.info('Address: ', ipv4_address)

name = "L3VPN-"+str(endpoint.pe_device)+"-"+str(endpoint.id)
vars.add('name', name)
vars.add('pe_device', endpoint.pe_device)
vars.add('cpe_interface_address', endpoint.cpe_interface.ipv4_address)
vars.add('pe_interface_name', endpoint.pe_interface.interface_name)
vars.add('pe_interface_number', endpoint.pe_interface.interface_number)
pe_interface_description = "L3VPN interface to " + str(endpoint.cpe_device) + ", interface " + str(endpoint.cpe_interface.interface_name) + str(endpoint.cpe_interface.interface_number)
vars.add('pe_interface_description', pe_interface_description)
vars.add('pe_ipv4_address', endpoint.pe_interface.ipv4_address)
vars.add('pe_ipv4_mask', endpoint.pe_interface.ipv4_mask)
self.log.info('ipv4_mask: ', endpoint.pe_interface.ipv4_mask)
template.apply('l3vpn_qinq_pe-template', vars)


class Main(ncs.application.Application):
def setup(self):
self.log.info('Main RUNNING')
self.register_service('l3vpn_qinq_cfs-servicepoint', ServiceCallbacks)

def teardown(self):
self.log.info('Main FINISHED')
32 changes: 32 additions & 0 deletions l3vpn_qinq_cfs/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
all: fxs
.PHONY: all

# Include standard NCS examples build definitions and rules
include $(NCS_DIR)/src/ncs/build/include.ncs.mk

SRC = $(wildcard yang/*.yang)
DIRS = ../load-dir
FXS = $(SRC:yang/%.yang=../load-dir/%.fxs)

## Uncomment and patch the line below if you have a dependency to a NED
## or to other YANG files
# YANGPATH += ../../<ned-name>/src/ncsc-out/modules/yang \
# ../../<pkt-name>/src/yang

NCSCPATH = $(YANGPATH:%=--yangpath %)
YANGERPATH = $(YANGPATH:%=--path %)

fxs: $(DIRS) $(FXS)

$(DIRS):
mkdir -p $@

../load-dir/%.fxs: yang/%.yang
$(NCSC) `ls $*-ann.yang > /dev/null 2>&1 && echo "-a $*-ann.yang"` \
--fail-on-warnings \
$(NCSCPATH) \
-c -o $@ $<

clean:
rm -rf $(DIRS)
.PHONY: clean
147 changes: 147 additions & 0 deletions l3vpn_qinq_cfs/src/yang/l3vpn_qinq_cfs.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
module l3vpn_qinq_cfs {

namespace "http://example.com/l3vpn_qinq_cfs";
prefix l3vpn_qinq_cfs;

import ietf-inet-types {
prefix inet;
}
import tailf-common {
prefix tailf;
}
import tailf-ncs {
prefix ncs;
}

description
"CFS, L3VPN using QinQ";

revision 2024-07-06 {
description
"Initial revision.";
}

grouping interface_grouping {
leaf interface_name {
tailf:info "Interface name. For example TenGigE.";
type enumeration {
enum FastEthernet;
enum GigabitEthernet;
enum TenGigE;
enum TwentyFiveGigE;
enum FortyGigE;
enum FiftyGigE;
enum HundredGigE;
enum TwoHundredGigE;
enum FourHundredGigE;
enum EightHundredGigE;
enum xe;
}
}
leaf interface_number {
tailf:info "Interface number. For example 0 or 1/0";
type string {
pattern "[0-9]{1,2}(/[0-9]{1,2}){1,4}";
}
}
leaf ipv4_address {
tailf:info "Interface IPv4 address.";
type inet:ipv4-address;
}
leaf ipv4_mask {
tailf:info "Interface IPv4 mask.";
type inet:ipv4-address;
}
leaf interface_description {
tailf:info "Interface description.";
type string;
}
}

list l3vpn_qinq_cfs {
description "This is an RFS skeleton service";

key vrf_name;
leaf vrf_name {
tailf:info "Unique service id";
tailf:cli-allow-range;
type string;
}

uses ncs:service-data;
ncs:servicepoint l3vpn_qinq_cfs-servicepoint;

leaf as_number {
tailf:info "SP Autonomous System number eg 65000";
type uint16;
mandatory true;
}

leaf customer_as_number {
tailf:info "Remote Autonomous System number of the customer eg 65002";
type uint16;
mandatory true;
}

list endpoint {
key id;
leaf id {
tailf:info "Endpoint identifier. It should be the id of the CPE. It will be added to the hostname";
type string;
}

leaf pe_device {
type leafref {
path "/ncs:devices/ncs:device/ncs:name";
}
}

leaf cpe_device {
type leafref {
path "/ncs:devices/ncs:device/ncs:name";
}
}

leaf cpe_loopback0_address {
tailf:info "Address of the Loopback 0 interface of the CPE. The mask is assumed to be /32";
type inet:ipv4-address;
}

leaf ovlan {
tailf:info "Outer VLAN eg 10";
type uint16;
}

leaf ivlan {
tailf:info "Inner VLAN eg 20";
type uint16;
}

container pe_interface {
uses interface_grouping;
}

container cpe_interface {
uses interface_grouping;
}

container qos {
leaf enable_qos_policy {
type boolean;
default false;
}

leaf bit_rate {
tailf:info "Bitrate for shaping in Kbps";
type enumeration {
enum 256;
enum 512;
enum 1024;
enum 10240;
}
default 1024;
}
}
}
}
}
20 changes: 20 additions & 0 deletions l3vpn_qinq_cfs/templates/l3vpn_qinq_cfs-template.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<devices xmlns="http://tail-f.com/ns/ncs">
<device>
<!--
Select the devices from some data structure in the service
model. In this skeleton the devices are specified in a leaf-list.
Select all devices in that leaf-list:
-->
<name>{/device}</name>
<config>
<!--
Add device-specific parameters here.
In this skeleton the, java code sets a variable DUMMY, use it
to set something on the device e.g.:
<ip-address-on-device>{$DUMMY}</ip-address-on-device>
-->
</config>
</device>
</devices>
</config-template>
19 changes: 19 additions & 0 deletions l3vpn_qinq_cfs/templates/l3vpn_qinq_pe-template.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<config-template xmlns="http://tail-f.com/ns/config/1.0">
<l3vpn_qinq_pe_rfs xmlns="http://example.com/l3vpn_qinq_pe_rfs">
<name>{$name}</name>
<device>{$pe_device}</device>
<vrf_name>{/vrf_name}</vrf_name>
<as_number>{/as_number}</as_number>
<remote_as_number>{/customer_as_number}</remote_as_number>
<neighbor_ip_address>{$cpe_interface_address}</neighbor_ip_address>
<ovlan>{/ovlan}</ovlan>
<ivlan>{/ivlan}</ivlan>
<interface>
<interface_name>{$pe_interface_name}</interface_name>
<interface_number>{$pe_interface_number}</interface_number>
<ipv4_address>{$pe_ipv4_address}</ipv4_address>
<ipv4_mask>{$pe_ipv4_mask}</ipv4_mask>
<interface_description>{$pe_interface_description}</interface_description>
</interface>
</l3vpn_qinq_pe_rfs>
</config-template>
37 changes: 37 additions & 0 deletions l3vpn_qinq_cfs/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
DIRS = external internal

ifeq ($(BUILD_JOB),external)
DIR = external
endif

ifeq ($(BUILD_JOB),internal_realhw)
DIR = internal
JOB_DIR = realhw
endif

ifeq ($(BUILD_JOB),internal_simulated)
DIR = internal
JOB_DIR = simulated
endif

ifeq ($(BUILD_JOB),)
DIR = internal
JOB_DIR = simulated
endif

all: test

build:
$(MAKE) -C $(DIR) build JOB_DIR=$(JOB_DIR) || exit 1

clean:
$(MAKE) -C $(DIR) clean JOB_DIR=$(JOB_DIR) || exit 1

test:
$(MAKE) -C $(DIR) test JOB_DIR=$(JOB_DIR) || exit 1

desc:
@echo "==Test Cases for NED=="
@for d in $(DIRS) ; do \
$(MAKE) -sC $$d desc || exit 1; \
done
21 changes: 21 additions & 0 deletions l3vpn_qinq_cfs/test/internal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
DIRS = lux

build:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d build || exit 1; \
done

clean:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d clean || exit 1; \
done

test:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d test || exit 1; \
done

desc:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d desc || exit 1; \
done
21 changes: 21 additions & 0 deletions l3vpn_qinq_cfs/test/internal/lux/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
DIRS = service

build:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d build || exit 1; \
done

clean:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d clean || exit 1; \
done

test:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d test || exit 1; \
done

desc:
@for d in $(DIRS) ; do \
$(MAKE) -C $$d desc || exit 1; \
done
Loading

0 comments on commit 07439c2

Please sign in to comment.