IETF 102 Hackathon
Alternative southbound interface to flow enabled network bridges
This is a new project originally defined in the following post on hackathon@ietf.org https://mailarchive.ietf.org/arch/msg/hackathon/vb27RmJivbwy8UURV_KXh2IzZd0
The project consists of 3 tasks:
- Design and publish draft with YANG model of a flow enabled network bridge.
- Device (server) side model implementation - loadable module for some of the available opensource NETCONF servers implementing the model for a OpenFlow device as a proxy controller with a single node.
- Controller (client) side plug-in implementation - ncflowplugin for
ODL interacting with NETCONF mounted nodes implementing the YANG model that ideally can coexist with openflowplugin.
Progress:
Design and publish draft with YANG model of a flow enabled network bridge.
Done. - https://datatracker.ietf.org/doc/draft-vassilev-netmod-network-bridge/
Device (server) side model implementation
Partial. Can be mounted from ODL but the OpenFlow part is not ready. - https://github.com/vlvassilev/yuma123/tree/master/example-modules/ietf-network-bridge
Controller (client) side plug-in implementation - ncflowplugin for ODL
Incomplete.
Walkthrough (tested on Debian)
Build and start netconfd server instance with the ietf-network-bridge* modules loaded listening on port 830:
cd sudo apt-get install git autoconf gcc libtool libxml2-dev libssh2-1-dev make libncurses5-dev zlib1g-dev libreadline-dev git clone git://git.code.sf.net/p/yuma123/git yuma123-git cd yuma123-git autoreconf -i -f ./configure CFLAGS='-g -O0' CXXFLAGS='-g -O0' --prefix=/usr make sudo make install #Enable the netconf subsystem and restart sshd echo "Port 830" | sudo tee -a /etc/ssh/sshd_config echo "Subsystem netconf "/usr/sbin/netconf-subsystem" | sudo tee -a /etc/ssh/sshd_config sudo /etc/init.d/ssh restart /usr/sbin/netconfd --module=/usr/share/yuma/modules/ietf/ietf-interfaces@2014-05-08.yang \ --module=/usr/share/yuma/modules/ietf/iana-if-type@2014-05-08.yang \ --module=/usr/share/yuma/modules/ietf-draft/ietf-network-bridge.yang \ --module=/usr/share/yuma/modules/ietf-draft/ietf-network-bridge-flows.yang \ --module=/usr/share/yuma/modules/ietf-draft/ietf-network-bridge-scheduler.yang \ --module=/usr/share/yuma/modules/examples/example-bridge.yang \ --startup=example-modules/ietf-network-bridge/example-bridge-cfg.xml --log-level=debug4 --superuser=${USER}
Validate everything is OK:
vladimir@lmf:~$ yangcli --server=localhost --ncport=830 --user=${USER} Warning: line is 82 chars, limit is 72 chars yangcli-ex.yang:69.1: warning(438): display line length exceeded yangcli version 2.11-0 libssh2 version 1.7.0 Copyright (c) 2008-2012, Andy Bierman, All Rights Reserved. Copyright (c) 2013-2017, Vladimir Vassilev, All Rights Reserved. Type 'help' or 'help <command-name>' to get started Use the <tab> key for command and value completion Use the <enter> key to accept the default value in brackets These escape sequences are available when filling parameter values: ? help ?? full help ?s skip current parameter ?c cancel current command These assignment statements are available when entering commands: $<varname> = <expr> Local user variable assignment $$<varname> = <expr> Global user variable assignment @<filespec> = <expr> File assignment Enter string value for leaf <password> yangcli:connect> val->res is NO_ERR. yangcli: Starting NETCONF session for vladimir on localhost NETCONF session established for vladimir on localhost Client Session Id: 1 Server Session Id: 3 Server Protocol Capabilities base:1.0 candidate:1.0 confirmed-commit:1.0 rollback-on-error:1.0 validate:1.0 url:1.0 xpath:1.0 notification:1.0 interleave:1.0 partial-lock:1.0 with-defaults:1.0 base:1.1 validate:1.1 confirmed-commit:1.1 yang-library:1.0 Server Module Capabilities example-bridge@2018-07-15 iana-crypt-hash@2014-08-06 Features: crypt-hash-md5 crypt-hash-sha-256 crypt-hash-sha-512 iana-if-type@2014-05-08 ietf-datastores@2018-01-11 ietf-inet-types@2013-07-15 ietf-interfaces@2014-05-08 Features: arbitrary-names pre-provisioning if-mib ietf-netconf-acm@2012-02-22 ietf-netconf-datastores@2017-08-24 Features: origin ietf-netconf-monitoring@2010-10-04 ietf-netconf-notifications@2012-02-06 ietf-netconf-partial-lock@2009-10-19 ietf-netconf-with-defaults@2011-06-01 ietf-network-bridge@2018-07-15 ietf-network-bridge-flows@2018-07-15 ietf-network-bridge-scheduler@2018-07-15 ietf-origin@2018-01-11 ietf-system@2014-08-06 Features: radius authentication local-users radius-authentication ntp ntp-udp-port timezone-name dns-udp-tcp-port ietf-yang-library@2016-06-21 ietf-yang-metadata@2016-08-05 ietf-yang-types@2013-07-15 nc-notifications@2008-07-14 notifications@2008-07-14 yuma-app-common@2012-08-16 yuma-mysession@2010-05-10 yuma-ncx@2012-01-13 yuma-proc@2012-10-10 yuma-time-filter@2012-11-15 yuma-types@2012-06-01 yuma123-netconf-types@2017-06-23 yuma123-system@2017-03-26 Server Enterprise Capabilities None Protocol version set to: RFC 6241 (base:1.1) Default target set to: <candidate> Save operation mapped to: commit Default with-defaults behavior: explicit Additional with-defaults behavior: trim,report-all,report-all-tagged Getting yang-library module set ... Current module-set-id: 475799d7bd3d7f8a8c72fc5fcd9ca5a8b2cb7674. Checking Server Modules... yangcli vladimir@localhost> xget-config source=running / RPC Data Reply 2 for session 3: rpc-reply { data { bridge { ports { port p0 { name p0 index 0 class example:default-port class-instance-index 0 } port p1 { name p1 index 1 class example:default-port class-instance-index 1 } port p2 { name p2 index 2 class example:default-port class-instance-index 2 } } default-traffic-class example:best-effort default-port-class example:best-effort traffic-classes { traffic-class example:best-effort traffic-class example:signaling traffic-class example:video0 traffic-class example:video1 } port-classes { port-class example:default-port } scheduler-classes { scheduler-class example:default-port { egress-port-class example:default-port inputs { input example:best-effort example:default-port { traffic-class example:best-effort ingress-port-class example:default-port gate-controller p input-class example:pri2 base-index 0 } input example:signaling example:default-port { traffic-class example:signaling ingress-port-class example:default-port gate-controller r1 input-class example:in base-index 0 } input example:video0 example:default-port { traffic-class example:video0 ingress-port-class example:default-port gate-controller t input-class example:timeslot0 base-index 0 } input example:video1 example:default-port { traffic-class example:video1 ingress-port-class example:default-port gate-controller t input-class example:timeslot1 base-index 0 } } gate-controllers { gate-controller a { id a type example:strict-priority-aggregator inputs { input example:pri0 { class example:pri0 instance-count 3 queue-len 2048 } } output { gate-controller r2 input-class example:in index 0 } } gate-controller p { id p type example:strict-priority-aggregator inputs { input example:pri0 { class example:pri0 instance-count 1 queue-len 2048 } input example:pri1 { class example:pri1 instance-count 1 queue-len 32768 } input example:pri2 { class example:pri2 instance-count 3 queue-len 1048576 } } } gate-controller r1 { id r1 type example:rate-limiter inputs { input example:in { class example:in instance-count 3 } } output { gate-controller a input-class example:pri0 index 0 } interval 10000000 limit 12500 } gate-controller r2 { id r2 type example:rate-limiter inputs { input example:in { class example:in instance-count 1 } } output { gate-controller p input-class example:pri0 index 0 } interval 10000000 limit 125000 } gate-controller t { id t type example:cyclic-timeslot-schedule-aggregator inputs { input example:timeslot0 { class example:timeslot0 instance-count 3 queue-len 1048576 } input example:timeslot1 { class example:timeslot1 instance-count 3 queue-len 1048576 } } output { gate-controller p input-class example:pri0 index 2 } period 10000000 time-slot0-interval 5000000 time-slot1-interval 5000000 } } } } } flows { flow best-effort-to-host0 { id best-effort-to-host0 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:00 } } } actions { action 0 { order 0 output-action { out-port p0 } } } traffic-class example:best-effort } flow best-effort-to-host1 { id best-effort-to-host1 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:01 } } } actions { action 0 { order 0 output-action { out-port p1 } } } traffic-class example:best-effort } flow best-effort-to-host2 { id best-effort-to-host2 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:02 } } } actions { action 0 { order 0 output-action { out-port p2 } } } traffic-class example:best-effort } flow ptp-to-host0 { id ptp-to-host0 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:00 } } } actions { action 0 { order 0 output-action { out-port p0 } } } traffic-class example:signaling } flow ptp-to-host1 { id ptp-to-host1 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:01 } } } actions { action 0 { order 0 output-action { out-port p1 } } } traffic-class example:signaling } flow ptp-to-host2 { id ptp-to-host2 match { ethernet-match { ethernet-destination { address 00:01:02:03:00:02 } } } actions { action 0 { order 0 output-action { out-port p2 } } } traffic-class example:signaling } flow video0 { id video0 match { vlan-match { vlan-id { vlan-id 10 } } } actions { action 0 { order 0 output-action { out-port p2 } } } traffic-class example:video0 } flow video1 { id video1 match { vlan-match { vlan-id { vlan-id 11 } } } actions { action 0 { order 0 output-action { out-port p2 } } } traffic-class example:video1 } } interfaces { interface if0 { name if0 type ianaift:ethernetCsmacd port-name p0 } interface if1 { name if1 type ianaift:ethernetCsmacd port-name p1 } interface if2 { name if2 type ianaift:ethernetCsmacd port-name p2 } } nacm { } } } yangcli vladimir@localhost> quit
Build and start ODL mounting the network bridge over NETCONF (change user:tester/pass:tester with the user that started netconfd and pass):
<nowiki>
cd sudo apt-get install -y openjdk-8-jdk sudo apt-get install -y maven mkdir ~/.m2 wget -q -O - https://raw.githubusercontent.com/opendaylight/odlparent/master/settings.xml > ~/.m2/settings.xml export MAVEN_OPTS='-Xmx1048m -XX:MaxPermSize=512m'
sudo apt-get install corkscrew mkdir opendaylight cd opendaylight for PROJECT in aaa aalldp alto armoury atrium bgpcep bier capwap cardinal centinel coe controller daexim didm discovery \ dlux dluxapps docs eman faas federation fpc genius groupbasedpolicy honeycomb/vbd integration/distribution \ integration/packaging integration/packaging/ansible-opendaylight integration/packaging/puppet-opendaylight integration/test \ iotdm jsonrpc kafkaproducer l2switch lacp lispflowmapping mdsal messaging4transport natapp nemo netconf netide netvirt \ neutron next nic ocpplugin odlparent of-config ofextensions/circuitsw ofextensions/epc openflowjava openflowplugin opflex \ ovsdb packetcable persistence plugin2oc releng releng/autorelease releng/builder reservation sdninterfaceapp sfc snbi snmp \ snmp4sdn sxp systemmetrics tcpmd5 topoprocessing transportpce tsdr ttp unimgr usc usecplugin vpnservice vtn yang-push \ yangide yangtools; \ do git clone https://git.opendaylight.org/gerrit/${PROJECT}.git ${PROJECT}; \ done
git clone https://git.opendaylight.org/gerrit/p/integration/distribution.git distribution
cd distribution git checkout tags/release/beryllium-sr4 mvn clean install -Pq
cd distribution-karaf/target/assembly
./bin/start sleep 30 ./bin/client -u karaf 'feature:list --installed'
- install NETCONF support
./bin/client -u karaf 'feature:install odl-netconf-all odl-netconf-ssh odl-netconf-connector-all'
- install GUI support
./bin/client -u karaf 'feature:install odl-dlux-all'
- install topology configuration support
./bin/client -u karaf 'feature:install odl-restconf-all' ./bin/client -u karaf 'feature:install odl-netconf-topology'
- odl-netconf-clustered-topology
./bin/client -u karaf feature:list
cat > myscript.txt << EOF merge /modules/module[name='ncflow'][type='sal-netconf-connector'] -- address=localhost sal-netconf:port=830 tcp-only=false username=tester password=tester sal-netconf:event-executor/type=netty-event-executor sal-netconf:event-executor/name=global-event-executor sal-netconf:binding-registry/type=binding-broker-osgi-registry sal-netconf:binding-registry/name=binding-osgi-broker sal-netconf:dom-registry/type=dom-broker-osgi-registry sal-netconf:dom-registry/name=dom-broker sal-netconf:client-dispatcher/type=netconf-client-dispatcher sal-netconf:client-dispatcher/name=global-netconf-dispatcher sal-netconf:processing-executor/type=threadpool sal-netconf:processing-executor/name=global-netconf-processing-executor sal-netconf:keepalive-executor/type=scheduled-threadpool sal-netconf:keepalive-executor/name=global-netconf-ssh-scheduled-executor commit EOF
- If commit is not done in the same session as the merge the changes to candidate are discarded autmatically .. thus the --run-script instead 2 sequential --run-command calls for merge and commit.
yangcli --server=localhost --ncport=1830 --user=admin --password=admin --dump-session=/tmp/yangcli- --keep-session-model-copies-after-compilation=true --batch-mode --run-script=myscript.txt --log-level=debug4
- enable northbound MD-SAL interface - opens port 2830
./bin/client -u karaf 'feature:install odl-netconf-mdsal' sleep 60
./bin/client -u karaf 'feature:install odl-mdsal-apidocs' ./bin/client -u karaf 'feature:install odl-openflowplugin-flow-services-rest' ./bin/client -u karaf 'feature:install odl-openflowplugin-flow-services-ui'
sleepp 30
cat > myscript.txt << EOF merge /nodes/node[id='openflow:1']/table[id='0']/flow[id='1'] -- match/in-port=openflow:1:1 match/ethernet-match/ethernet-type=35063 instructions/instruction[order='0']/apply-actions/action[order='0']/output-action/output-node-connector=2 out_port=2 flow-name=my-ptp-flow commit EOF
yangcli --server=localhost --ncport=2830 --user=admin --password=admin --dump-session=/tmp/yangcli- --keep-session-model-copies-after-compilation=true --batch-mode --run-script=myscript.txt --log-level=debug4
Start conventional openflow nodes to join the ncflow node:
mn --topo linear,3 --mac --controller=remote,ip=127.0.0.1,port=6633 --switch ovs,protocols=OpenFlow10