Slide deck to give some theoretical background before stepping into the hands-on tutorial at http://sdnhub.org/tutorials/opendaylight. Compared to earlier version of this slide deck, this tutorial slide deck has been updated to focus more on MD-SAL and YANG modeled app development.
3. OpenDaylight Consortium
► Heavy industry involvement and backing.
► Platinum and Gold members as of June 2016:
► Focused on having an open framework for building upon
SDN/NFV innovations
Not limited to OpenFlow innovations, but in fact decoupled from it
allowing the two to evolve independently
3
4. Other
apps
SDN Polytheism in OpenDaylight
i.e., OpenDaylight embraces the full spectrum of choices
4
Data plane
Orchestration
Legacy control
plane
Data plane
Orchestration
Legacy
control
plane
Controller
Data plane
Orchestration
Applications
Controller
Risk
NETCONF/YANG
NETCONF/YANG, REST
OpenFlow, P4OpenFlow, P4
Data plane
Orchestration
Controller
OpenFlow, P4
NETCONF/YANG, REST
Applications
REST
Legacy
control plane
OF
Agent
OF Agent OF Agent
Purist-modelHybrid-model
Solving only
operational issue Backward-compatible
6. Lithium: List of Projects (Total: 40)
opflex* OpFlex protocol
ovsdb OVSDB protocol and OpenStack integration
packetcable PacketCable PCMM/COPS
pss* Persistence Store Service
plugin2oc Southbound plugin to the OpenContrail platform
reservation* Dynamic Resource Reservation project
sdninterfaceapp SDNi Cross-controller interface
sfc Service Function Chaining
snbi Secure Network Bootstrap Infrastructure
snmp4sdn SNMP4SDN Plugin
snmp* SNMP Southbound Plugin
sxp* Source-Group Tag eXchange Protocol
tcpmd5 TCP-MD5 Support library
toolkit Quickstart Toolkit
tpf* Topology Processing Framework
tsdr* Time Series Data Repository
ttp TTP Project
usc* Unified Secure Channel
vtn VTN (Virtual Tenant Network)
yangtools YANG Tools
Project keyword Description
aaa AAA Project
alto* Application-Layer Traffic Optimization
bgpcep BGP/PCEP protocol library
capwap*
Control and Provisioning of Wireless
Access Point
controller OpenDaylight Controller
defense4all Radware Defense4All
didm*
Device Identification and Drive
Management
discovery Discovery Service
dlux OpenDaylight UI
docs Documentation Project
groupbasedpolicy Group Based Policy Plugin
integration Integration Framework
iotdm* IoT Data-centric Middleware
l2switch Separate Layer 2 switching
lacp* Link Aggregation Control Protocol
lispflowmapping LISP Mapping Service
nic* Network Intent Composition
openflowjava OpenFlow Protocol Library
openflowplugin OpenFlow Plugin
* New in Lithium release
7. What does it mean to program in ODL?
1. Get familiar with the Model-View-Control approach for app development in
a modular fashion
YANG Model for data, RPC and notifications
RESTconf View generated automatically
Implementation in Java or Scala to handle data changes, notifications and RPC
call backs
2. Get familiar with platform essentials (maven, config subsystem,
dependencies) and useful tools
3. Learn about existing projects and reuse modules
No need to change code of other projects. Just link them as binary libraries
7
These are our goals for the hands-on part
8. What’s new in this tutorial?
► Old tutorials focused solely on:
OpenFlow based app development
API driven SAL that is similar in spirit to what ONOS uses
OSGi based activation
► New tutorial
Approaches app development from the perspective of YANG
modeling since it is core to OpenDaylight
Model driven SAL (MD-SAL) for all state handling
Uses config subsystem for bundle activation
8
10. YANG
► Data modeling language
that is also the preferred
configuration language for
NETCONF protocol
► Further reads:
YANG introductory tutorial
RFC 6020 - YANG - A data
modeling language for
NETCONF
module model1 {
namespace "urn:model1";
prefix model1;
yang-version 1;
revision 2015-04-06 {
description "Initial revision";
}
grouping A {
list B {
key id;
leaf id {
type uint32;
}
leaf D {
type uint32;
}
}
}
container C {
uses A;
}
}
11. Module model1
Namespace “urn:model1”
MD-SAL Data Access
► Model-driven SAL is the kernel of the OpenDaylight controller!
► It manages the contracts and state exchanges between every application. It
does this adaptation by managing centralized state
► Takes in the YANG model at runtime and constructs the tree in the data store
For the YANG model in previous slide, here is the view of the root and its children
11
C
B
id=1
Leaf D
Val=9
Leaf D
Val=16
Leaf D
Val=2
B
id=2
B
id=3
/restconf/config/model1:C
/restconf/config/model1:C/B/3
12. MD-SAL Data Access (contd.)
► When the model is compiled with maven, you will see classes generated in
Model1Data. java, B.java, and C.java
► InstanceIdentifier is used as a pointer to a child. Following points to the first
child node in the figure
► ReadOnlyTransaction, and WriteTransaction are used to access the data store.
► Transaction can also be batched
12
InstanceIdentifier iid = InstanceIdentifier.builder(C.class)
.child(B.class, new BKey((long)1))
.build();
B updatedB = new BBuilder().setD((long)19).build();
WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
modification.merge(LogicalDataStoreType.CONFIGURATION, iid, updatedB, true);
modification.submit();
13. YANG modeled data Store at the core
13
Karaf/OSGi
App 2
Data
model
impl
MD-SAL
App 1
model data
Possibly Policy,
Possibly even Intents
Devices
or other
external
systems
App1
Data
model
Impl
1
2
7
8
App 2
model data
Class
X
Class
Y
4
5
3
Config Subsystem
RESTconf
App 1 and 2
config data
Config
model
6 Config
model
Class Z
JVM
14. Two types of data store
► For the same model, there are two types of data store
maintained by MD-SAL
Config store: App developers typically use this to store user input and
associated derived state for apps
Operational store: Typically used to keep transient ephemeral state
► Choice of store has implications on RESTconf and persistence
Config store is always kept persistent. There is control on how many
replicas to keep
Operational store cannot be changed over RESTconf
14
15. YANG not restricted to Just Data Store
► Notifications:
Publish one or more notifications to registered listeners
► RPC:
Perform procedure call with input/output,
without worrying about actual provider for that procedure
15
16. Using Notifications and RPCs
► Application developer usage for receiving notification and making RPC calls.
► Note: Whenever there is a change in the MD-SAL data store, you can receive
a notification similar to the YANG defined notifications by implementing the
DataChangeListener interface in a provider module
16
public class ConsumerImpl implements OpendaylightInventoryListener
public ConsumerImpl(..) {
notificationService.registerNotificationListener(this);
this.salFlowService = rpcProviderRegistry.getRpcService(SalFlowService.class)
}
@Override
public void onNodeUpdated(NodeUpdated nodeUpdated) {
RemoveFlowInputBuilder flowBuilder = new RemoveFlowInputBuilder();
flowBuilder.setBarrier(true);
flowBuilder.setNode(NodeUtils.createNodeRef(nodeUpdated.getId()));
salFlowService.removeFlow(flowBuilder.build());
}
}
19. Java, Interface, Maven, OSGi, Karaf
► Java chosen as an enterprise-grade,
cross-platform compatible language
► Java Interfaces are used for event listening,
specifications and forming patterns
► Maven – build system for Java
► OSGi:
Allows dynamically loading bundles
Allows registering dependencies and
services exported
For exchanging information across bundles
► Karaf: Light-weight Runtime for loading modules/bundles
OSGi based. Primary distribution mechanism for Helium
19
OSGi Framework
(Equinox)
Feature
A
SAL
Feature
B …
Karaf
20. Running OpenDaylight Controller: Lithium release
Typically we get started with the following
$ wget
https://nexus.opendaylight.org/content/groups/public/org/opendaylight/in
tegration/distribution-karaf/0.3.0-Lithium/distribution-karaf-0.3.0-
Lithium.zip
$ unzip distribution-karaf-0.3.0-Lithium.zip
$ cd distribution-karaf-0.3.0-Lithium
$ ./bin/karaf
opendaylight-user@root> feature:list (get all apps available)
opendaylight-user@root> feature:install odl-dlux-core (install UI)
opendaylight-user@root> feature:install odl-openflowplugin-all
opendaylight-user@root> feature:install odl-l2switch-all
opendaylight-user@root> bundle:list | grep Active
Now your controller is ready to connect to switches and handle incoming flows.
See UI at http://localhost:8181/index.html
20
21. REST APIs
► OpenDaylight has significant support
for REST APIs
► Restconf allows for checking config
and operational state
feature:install odl-restconf
http://localhost:8181/restconf/....
► List of exposed Northbound APIs are
autogenerated using swagger.
feature:install odl-mdsal-apidocs
http://localhost:8181/apidoc/explorer
21
22. ODL’s opendaylight-inventory.yang (Lithium)
notification node-updated {
status deprecated;
leaf node-ref {
type node-ref;
}
uses node;
}
notification node-connector-updated {
status deprecated;
leaf node-connector-ref {
type node-connector-ref;
}
uses node-connector;
}
notification node-removed {
status deprecated;
leaf node-ref {
type node-ref;
}
}
notification node-connector-removed {
status deprecated;
leaf node-connector-ref {
type node-connector-ref;
}
}
}
grouping node {
leaf id {
type node-id;
}
list "node-connector" {
key "id";
uses node-connector;
}
}
grouping node-connector {
leaf id {
type node-connector-id;
}
}
container nodes {
list node {
key "id";
uses node;
. . .
}
}
module opendaylight-inventory {
namespace
"urn:opendaylight:inventory";
prefix inv;
typedef node-id {
type inet:uri;
}
typedef node-connector-id {
type inet:uri;
}
typedef node-ref {
type instance-identifier;
}
typedef node-connector-ref {
type instance-identifier;
}
Augmentation made by
OpenFlow plugin for storing:
1. All switch description
2. All OpenFlow features
3. All tables and its flows
4. All meters, groups
22
23. ODL’s Inventory Config Data Store
http://localhost:8181/restconf/config/opendaylight-inventory:nodes
23
24. ODL’s network-topology.yang (Lithium)
http://localhost:8181/restconf/operational/network-topology:network-topology
24
container network-topology {
list topology {
key "topology-id";
leaf topology-id {
type inet:uri;
}
container topology-types {
}
list underlay-topology {
key "topology-ref";
leaf topology-ref {
type topology-ref;
}
}
list node {
key "node-id";
uses node-attributes;
list termination-point {
key "tp-id";
uses tp-attributes;
}
}
list link {
key "link-id";
uses link-attributes;
}
}
}
}
grouping node-attributes {
leaf node-id {
type inet:uri;
}
list supporting-node {
key "node-ref";
leaf node-ref {
type node-ref;
}
}
}
grouping link-attributes {
leaf link-id {
type inet:uri;
}
container source {
leaf source-node {
mandatory true;
type node-ref;
}
leaf source-tp {
type tp-ref;
}
}
container destination {
leaf dest-node {
mandatory true;
type node-ref;
}
leaf dest-tp {
type tp-ref;
}
}
list supporting-link {
key "link-ref";
leaf link-ref {
type link-ref;
}
}
}
module network-topology {
namespace
"urn:TBD:params:xml:ns:yang:network-topology";
typedef topology-ref {
type leafref {
path "/network-
topology/topology/inet:uri";
}
}
typedef node-ref {
type leafref {
path "/network-
topology/topology/node/inet:uri";
}
}
typedef link-ref {
type leafref {
path "/network-
topology/topology/link/inet:uri";
}
}
grouping tp-attributes {
leaf tp-id {
type inet:uri;
}
leaf-list tp-ref {
type tp-ref;
}
}
25. Extension to models through Augments
► Unless specified otherwise, YANG models can be augmented in a new namespace to
add extra data within an existing data model.
► For example, odl-l2-switch augments above inventory to store hosts learned
25
import opendaylight-inventory { prefix inv; revision-date 2013-08-19; }
augment "/inv:nodes/inv:node/inv:node-connector" {
ext:augment-identifier "address-capable-node-connector";
uses address-node-connector;
}
curl http://localhost:8080/restconf/operational/opendaylight-
inventory:nodes/node/openflow:1/node-connector/openflow:1:1
{ "node-connector":
[ { "id": "openflow:1:1",
"address-tracker:addresses": [ {
"address-tracker:last-seen": 1404918398057,
"address-tracker:ip": "10.0.0.1",
"address-tracker:first-seen": 1404918392926,
"address-tracker:mac": "f2:0c:dd:80:9f:f7"
}]
}]
}
26. Code Design
► yangtools generates data model classes
Builders for generating immutable objects also generated
identity mapped to interfaces
All else are mapped to classes
Identity is the only one that allows inheritance
► Developers have to write the gateway adapters
Converting from one data model to another
Translating between a non-ODL source and ODL app
https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping
26
27. Data Store Management
► Persistence
Everything that gets into a shard is stored in-memory and on the disk.
Restarting the controller will reconstitute the state of the shards from the
persisted data.
► Clustering
Multiple controller instances can interwork and share state (for backup reasons
rather than load-sharing)
One leader (writer) and multiple followers (read-only) where state consistency is
achieved using RAFT algorithm
► Sharding
The big in-memory MD-SAL tree is broken up into a bunch of smaller sub-trees
such that 1 model is 1 shard (e.g., inventory, topology and default).
27
29. OpenDaylight External Interfaces
► Southbound:
Built-in NETCONF client and BGP speaker to interact with legacy control planes
and orchestrate them
Plugin for OpenFlow 1.0 and 1.3 support
Plugin for OVSDB that works with OVS schema (VTEP schema in future)
► Northbound:
REST and NETCONF for receiving intent data
Controller platform
OpenFlow OVSDB NETCONF BGP
Network
functions
State
mgmt
App/
Logic
Service intent and policy
Device manager
NETCONF REST
Service
models
Device
models
30. OpenFlow Southbound
► Programming a flow_mod
Make data transaction as an
augmentation to ODL inventory
► Sending a packet_out
Craft packet data as modeled
by YANG and make RPC call to
transmit
► Receiving a packet_in
Register consumer for data receive
notification
► Checking statistics and network changes
Check operational store of ODL inventory
Your application
OpenFlow
Plugin
OpenFlow
Java
Nicira Ext
OF plugin
Nicira Ext
OF Java
Datastore
(1)
(2)
(3)
Switch1 Switch2 Switch3
31. NETCONF Southbound
To work with any NETCONF device,
1. Register device with netconf connector of ODL by
providing the details of the netconf-enabled device IP,
Username, Password, Port
2. Device supports ietf-netconf-monitoring?
a) Yes - Controller automatically pulls in the device’s model
b) No - Inject device’s model statically
3. ODL controller automatically mounts the netconf
configs in the device to the controller data store.
4. The apps (both JVM apps and REST apps) are now ready
to make read/write transaction to the device.
31
32. NETCONF based Multi-Vendor OSS
August 2015
32
Orchestrator
NETCONF
Service
models
Device
models
OSS Engine
CLI
Models are vendor specific
and still need vendor
specific adapters in the
orchestrator layer. This
makes case for OpenConfig
34. Three main steps
► Step 1: Define the YANG model for the state
► Step 2: Activation using config subsystem
Each implementation has a YANG file defining its necessary MD-SAL
dependencies and its namespace (See tapapp-impl.yang)
Each module has a config XML file that points to the implementation YANG file
along with input to the config subsystem (See 50-tapapp-config.xml)
► Step 3: Implement the event handlers for all notifications and call backs
Provider:
► Module that is handles config data changes, receives RPC calls, or publishes
notifications
Consumer:
► Module that makes RPC calls, listens to operational data changes, or listens to
notifications
35. Example of Consumer
► Here is a consumer of OpenFlow inventory updates
and flow programming
35
public class ConsumerImpl implements OpendaylightInventoryListener
public ConsumerImpl(..) {
notificationService.registerNotificationListener(this);
this.salFlowService = rpcProviderRegistry.getRpcService(SalFlowService.class)
}
@Override
public void onNodeUpdated(NodeUpdated nodeUpdated) {
RemoveFlowInputBuilder flowBuilder = new RemoveFlowInputBuilder();
flowBuilder.setBarrier(true);
flowBuilder.setNode(NodeUtils.createNodeRef(nodeUpdated.getId()));
salFlowService.removeFlow(flowBuilder.build());
}
}
36. ► Since RPC calls typically use the thread of the caller, it is generally
recommended to use executor threads to prevent blocking the caller thread.
Example of Consumer (contd.)
36
private final ListeningExecutorService executor =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
@Override
public void onNodeUpdated(NodeUpdated nodeUpdated) {
final ListenableFuture<RpcResult<RemoveFlowOutput>> result = executor.submit(
new Callable<RpcResult<RemoveFlowOutput>>() {
public RpcResult<RemoveFlowOutput> call() {
try {
return salFlowService.removeFlow(flowBuilder.build()).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return null;
}
}
});
Futures.addCallback(result, new FutureCallback<RpcResult<Void>>() {
public void onSuccess(RpcResult<RemoveFlowOutput> result) {
LOG.info(“Flow programming successful {}“, result.getResult());
}
public void onFailure(Throwable error) {
LOG.info(“Flow programming failed with error {}", error);
};
});
}
Submit
Future to
executor
Register
lean
callbbacks
37. Example of a Provider
► Implement the auto-generated RPC interface and the datachangelistener
37
public class TutorialTapProvider implements AutoCloseable, DataChangeListener, TapService {
public TutorialTapProvider(DataBroker dataBroker) {
//Register data change listener
dataBroker.registerDataChangeListener(
LogicalDatastoreType.CONFIGURATION,
rootIID, this, AsyncDataBroker.DataChangeScope.SUBTREE);
//Register this class as RPC provider for create-tap call
rpcProviderRegistry.addRpcImplementation(TapService.class, this);
}
@Override
public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
// Iterate over any data changes
...
}
@Override
public Future<RpcResult<CreateTapOutput>> createTap(CreateTapInput input) {
// Parse the input and perform the tap creation operation
...
}
}
41. ovs-vsctl and ovs-ofctl
► ovs-vsctl is used to check all the bridge configuration
► ovs-ofctl is used to check on the OpenFlow aspects and manage flows
► Before controller is started, execute the following
# ovs-ofctl show s1
# ovs-ofctl dump-flows s1
mininet> h1 ping h2
# ovs-ofctl add-flow s1 in_port=1,actions=output:2
# ovs-ofctl add-flow s1 in_port=2,actions=output:1
# ovs-ofctl dump-flows s1
mininet> h1 ping h2
41
All ports of switch
shown, but no
flows installed.
Ping fails because
ARP cannot go
through
Ping works now!
42. For exercise 1 of programming OpenFlow rules using REST API
opendaylight-user@root> feature:install odl-openflowplugin-all
opendaylight-user@root> feature:install odl-restconf
For exercise 2 of configuring NETCONF device
opendaylight-user@root> feature:install odl-netconf-connector-all
For enabling basic ping between mininet hosts using L2 Hub
opendaylight-user@root> feature:install sdnhub-tutorial-learning-switch
Running OpenDaylight Controller
$ cd SDNHub_Opendaylight_Tutorial
$ cd distribution/opendaylight-karaf/target/assembly/
$ ./bin/karaf clean
opendaylight-user@root> feature:list (get all apps available)
42
sdnhub-
tutorial
-tapapp
already
installed
Note: The tutorial project did not need all ODL libraries or source code
43. Running wireshark and Eclipse
► Wireshark helps investigate the OpenFlow messages exchanged
between the switch and controller
# wireshark &
► Eclipse is a popular IDE for developing Java applications. The VM
already has Eclipse with maven integration
$ eclipse &
43
Write code in Eclipse,
but run Karaf with
debug enabled in
Linux terminal
44. Exercises:
1. Flow programming through REST API
2. Configure NETCONF devices from OpenDaylight
3. Writing a simple tap application that receives config through REST
4. Update learning switch application:
a) Convert hub to switch
b) MD-SAL transaction for MAC Table in learning switch
5. Combine tap and learning switch (Homework)
45. 1. Flow Programming through REST
► It is possible to use RESTconf to send static flows to the controller. The REST
input is based on the YANG model. For instance, post following 2 static flows.
curl -X PUT –H “Content-Type: application/xml”
http://localhost:8181/restconf/config/opendaylight
-inventory:nodes/node/openflow:1/flow-node-
inventory:table/0/flow/Dummy_forward
curl -X PUT –H “Content-Type: application/xml”
http://localhost:8181/restconf/config/opendaylight
-inventory:nodes/node/openflow:1/flow-node-
inventory:table/0/flow/Dummy_reverse
<flow xmlns="urn:opendaylight:flow:inventory">
<id>Dummy_forward</id>
<flow-name>Dummy_forward</flow-name>
<table_id>0</table_id>
<match>
<in-port>1</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>2</output-node-connector>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>
<flow xmlns="urn:opendaylight:flow:inventory">
<id>Dummy_reverse</id>
<flow-name>Dummy_reverse</flow-name>
<table_id>0</table_id>
<match>
<in-port>2</in-port>
</match>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>1</output-node-connector>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>
46. 1. Flow Programming (contd.)
► Rules programmed on the switch leads to successful ping
46
$ sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow13 --controller remote
mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
From 10.0.0.1 icmp_seq=3 Destination Host Unreachable
From 10.0.0.1 icmp_seq=4 Destination Host Unreachable
64 bytes from 10.0.0.1: icmp_seq=5 ttl=64 time=0.409 ms
64 bytes from 10.0.0.1: icmp_seq=6 ttl=64 time=0.070 ms
64 bytes from 10.0.0.1: icmp_seq=7 ttl=64 time=0.099 ms
64 bytes from 10.0.0.1: icmp_seq=8 ttl=64 time=0.127 ms
--- 10.0.0.2 ping statistics ---
12 packets transmitted, 4 received, +8 errors, 66% packet loss, time 11078ms
rtt min/avg/max/mdev = 0.070/0.176/0.409/0.136 ms, pipe 4
$ sudo ovs-ofctl dump-flows –OOpenFlow13 s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x0, duration=183.006s, table=0, n_packets=8, n_bytes=560, idle_timeout=300,
hard_timeout=600, in_port=1 actions=output:2
cookie=0x0, duration=181.657s, table=0, n_packets=6, n_bytes=476, idle_timeout=300,
hard_timeout=600, in_port=2 actions=output:1
52. 3. Tap Application
► Network traffic tap is an application that filters certain traffic coming from a source
and sends it to a sink, based on proactively programmed OpenFlow rules
► Step 1: Build the data model…
52
typedef field-type {
type enumeration {
enum source;
enum destination;
enum both;
}
}
typedef traffic-type {
type enumeration {
enum ARP;
enum DNS;
enum HTTP;
enum HTTPS;
enum TCP;
enum UDP;
enum DHCP;
enum ICMP;
}
}
container tap-spec {
list tap {
key "id";
leaf id {
type string;
}
uses tap-grouping;
}
}
grouping tap-grouping {
leaf node {
mandatory true;
type leafref { path "/inv:nodes/inv:node/inv:id"; }
}
leaf-list src-node-connector {
min-elements 1;
type leafref { path "/inv:nodes/inv:node/inv:node-connector/inv:id"; }
}
leaf-list sink-node-connector {
min-elements 1;
type leafref { path "/inv:nodes/inv:node/inv:node-connector/inv:id"; }
}
container mac-address-match {
leaf type { type field-type; }
leaf value { type yang:mac-address; }
}
container ip-address-match {
leaf type { type field-type; }
leaf value { type inet:ipv4-prefix; }
}
leaf traffic-match {
type traffic-type;
}
}
53. 3. Tap Application (contd.)
► Step 2: Activation using config subsystem
► Step 3: Add event handler for data change to process any new tap config
53
public class TutorialTapProvider implements AutoCloseable, DataChangeListener {
public TutorialTapProvider(DataBroker dataBroker) {
//TODO 1: Register data change listener
}
@Override
public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
// Iterate over any created nodes or interfaces
for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
DataObject dataObject = entry.getValue();
if (dataObject instanceof Tap) {
//TODO 2: If tap configuration added, call programTap()
}
}
// Iterate over any deleted nodes or interfaces
Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();
for (InstanceIdentifier<?> path : change.getRemovedPaths()) {
DataObject dataObject = originalData.get(path);
if (dataObject instanceof Tap) {
//TODO 3: If tap configuration deleted, call removeTap()
}
}
}
54. 3. Tap Application (contd.)
► The goal of the tap provider
application is to translate data
from user input tap config
to OpenFlowPlugin data
► OpenFlowPlugin in turn uses
that data to program rules
54
{
"id":"Tap_1SrcPort_openflow:1:1",
"instructions":{
"instruction":[ {
"apply-actions":{
"action":[ {
"order":0,
"output-action":{
"max-length":65535,
"output-node-connector":"openflow:1:2"
}
} ]
},
"order":0
} ]
},
"match":{
"ethernet-match":{
"ethernet-type":{
"type":2048
}
},
"in-port":"openflow:1:1",
"ip-match":{
"ip-protocol":6
},
"tcp-destination-port":80
},
"table_id":0
}
{ "tap": [{
"id": "1",
"node": "openflow:1",
"sink-node-connector":
[ "openflow:1:2" ],
"src-node-connector":
[ "openflow:1:1" ],
"traffic-match": "HTTP"
}]
}
55. 4a. Learning Switch
► The code in the VM handles “hub” implementation of the learning-switch
Any received packet-in is received through the PacketProcessingListener.
onPacketReceived YANG Notification
Controller, then, performs a packet-out of this packet to all ports through a RPC call to
PacketProcessingService.transmitPacket
► Your first task is to convert the code to build a learning switch that:
1. tracks where each MAC address is located. i.e., create a MAC table like follows:
Map<String, NodeConnectorId> macTable = new HashMap <String, NodeConnectorId>();
2. Insert flow rules to switch traffic based on the destination MAC address
55
56. 4b. MAC Table of Learning Switch
► In code, you will see the Map data structure called macTable
Map<String, NodeConnectorId> macTable = new HashMap <String, NodeConnectorId>();
► Your second task:
Instead of using local data, store it in MD-SAL using
GenericTransactionUtils.writeData() provided
► This will require writing a augmentation YANG
model for defining a place to store it. I choose to
store it within the opendaylight-inventory tree
Whenever lookup is performed, look into MD-SAL store using
GenericTransactionUtils.readData() that is provided
56
augment /odl-inv:nodes/odl-inv:node {
ext:augment-identifier "MacTable";
list hosts {
leaf mac-address {
type yang:mac-address;
}
leaf attachment-point {
//I choose simple one
type inet:uri;
}
}
}
57. Coding time.
Welcome to OpenDaylight programming!
57
http://sdnhub.org/tutorials/opendaylight
Editor's Notes
Bootstrap and setup VM should be done offline.
Hands-on tutorial will includes:
-- introduction to the tools
-- start mininet OF network
-- ovs-ofctl: checkout switch status, flow status, add flow, delete flow, etc. (ping test)
--start OF ryu (do nothing): use wireshark to observe OF messages
-- Ryu controller and applications.
Bootstrap and setup VM should be done offline.
Hands-on tutorial will includes:
-- introduction to the tools
-- start mininet OF network
-- ovs-ofctl: checkout switch status, flow status, add flow, delete flow, etc. (ping test)
-- start OF ryu (do nothing): use wireshark to observe OF messages
-- Ryu controller and applications.
Summays