Difference between revisions of "IETF 102 Hackathon"
(20 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | ==Alternative southbound interface to flow enabled network bridges== |
||
− | ==Objectives== |
||
− | Below are the 3 main objectives. Updates will be published below. |
||
− | ===1 - 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 |
This is a new project originally defined in the following post on hackathon@ietf.org https://mailarchive.ietf.org/arch/msg/hackathon/vb27RmJivbwy8UURV_KXh2IzZd0 |
||
Line 8: | Line 6: | ||
#Design and publish draft with YANG model of a flow enabled network bridge. |
#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. |
#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 - |
+ | #Controller (client) side plug-in implementation - ncflowplugin for ODL interacting with NETCONF mounted nodes implementing the YANG model |
− | ODL interacting with NETCONF mounted nodes implementing the YANG model |
||
that ideally can coexist with openflowplugin. |
that ideally can coexist with openflowplugin. |
||
− | + | ==Progress:== |
|
+ | ===Design and publish draft with YANG model of a flow enabled network bridge.=== |
||
− | * Checked https://github.com/opencomputeproject/SAI for references. |
||
+ | Done. https://datatracker.ietf.org/doc/draft-vassilev-netmod-network-bridge/ |
||
+ | ===Device (server) side model implementation=== |
||
− | ===2 - Resume projects started in IETF 101 Hackathon=== |
||
+ | 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: |
||
+ | <nowiki> |
||
+ | 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 |
||
+ | git checkout 328a64829243684da65891851bf22acb88ca16a5 |
||
+ | 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} |
||
+ | </nowiki> |
||
− | ===3 - Release 2.11 version of yuma123=== |
||
+ | Validate everything is OK with NETCONF client: |
||
+ | <nowiki> |
||
+ | 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 |
||
+ | </nowiki> |
||
+ | |||
+ | 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' |
||
+ | |||
+ | #from https://wiki.opendaylight.org/view/GettingStarted:Pulling,_Hacking,_and_Pushing_All_the_Code_from_the_CLI |
||
+ | 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-1'][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' |
||
+ | |||
+ | sleep 30 |
||
+ | |||
+ | cat > myscript.txt << EOF |
||
+ | merge /nodes/node[id='ncflow-1']/table[id='0']/flow[id='1'] -- match/in-port=ncflow-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 |
||
+ | </nowiki> |
||
+ | |||
+ | 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 |
||
+ | |||
+ | [[File:ietf102-screenshot1.jpg|800px]] |
||
+ | |||
+ | [[File:ietf102-screenshot2.jpg|800px]] |
||
+ | |||
+ | ... work remaining to get ncflow appearing as the rest of flow enabled bridges running OpenFlow. |
||
+ | |||
+ | ===ODL Restconf Links=== |
||
+ | * http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/ncflow-1 |
Latest revision as of 18:12, 18 July 2018
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 git checkout 328a64829243684da65891851bf22acb88ca16a5 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 with NETCONF client:
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):
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' #from https://wiki.opendaylight.org/view/GettingStarted:Pulling,_Hacking,_and_Pushing_All_the_Code_from_the_CLI 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-1'][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' sleep 30 cat > myscript.txt << EOF merge /nodes/node[id='ncflow-1']/table[id='0']/flow[id='1'] -- match/in-port=ncflow-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
... work remaining to get ncflow appearing as the rest of flow enabled bridges running OpenFlow.