-
Notifications
You must be signed in to change notification settings - Fork 77
OF Config Demo
Note that while the default port for NETCONF over SSH is 830, in this example we use 1830 to get around the need for root privileges to use a port number below 1024.
The default sys.config
for LINC has no controllers configured:
$ cd $LINC_ROOT
$ make
$ ./rel/linc/bin/linc console
However, if you are using the LINC environment, you will need to modify the configuration after running ping_example setup
. Open /home/vagrant/development/linc/rel/linc/releases/1.0/sys.config
and change this line:
{controllers,[{"Switch0-Controller","localhost",6633,tcp}]},
to:
{controllers,[]},
Then start LINC with ping_example switch
as usual.
The controller can be started either before or after adding it to the LINC configuration. Here we do it before:
$ cd $LINC_ROOT/scripts
$ ./of_controller_v4.sh [Note: use this for running it against OF 1.3.1 Switch)
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:4:4] [async-threads:0] [kernel-poll:false]
Eshell V5.9.2 (abort with ^G)
1>
$ $RYU_ROOT/bin/ryu-manager --verbose $LINC_ROOT/scripts/ryu/l2_switch_v1_3.py
$ cd $LINC_ROOT/deps/enetconf
$ make run_client
1> {ok, C} = enetconf_client:connect("localhost", [{port, 1830}, {user, "linc"}, {password, "linc"}]).
{ok, <0.XXX.0>}
After building and installing Yuma few different applications become available via command line. One of them is yangcli, which is interactive client for Netconf.
Create a bash script file which will run yangcli. Running this script will connect to the enetconf or other Netconf server, exchange packets and wait for interactive input. You can read about yangcli commands and syntax here: http://doc.yumaworks.com/manuals/v2/html/yangcli/yuma-yangcli-manual3.xhtml
#!/bin/bash
yangcli --server=localhost --ncport=1830 --user=guest --password=guest
We can check that no controllers are configured with OF-Config:
2> {ok, X} = enetconf_client:get_config(C, running).
{ok, <<"<?xml ... ">>}
3> io:format("~p~n", [X]).
<<"<?xml ... <rpc-reply ... <controllers/> ... ">>
Detailed formatted output may look like this:
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="0">
<data>
<capable-switch xmlns="urn:onf:of111:config:yang">
<id>CapableSwitch0</id>
<resources>
<port>
<resource-id>LogicalSwitch0-Port7</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port6</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port4</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port1</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port2</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port3</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port5</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port7</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port6</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port4</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port1</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port8</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port2</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port3</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port5</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
</resources>
<logical-switches>
<switch>
<id>LogicalSwitch0</id>
<datapath-id>7A:AC:DF:F0:3A:F2:00:00</datapath-id>
<controllers>
<controller>
<id>Switch0-DefaultController</id>
<ip-address>10.48.11.5</ip-address>
<port>6633</port>
<protocol>tcp</protocol>
</controller>
</controllers>
</switch>
<switch>
<id>LogicalSwitch1</id>
<datapath-id>7A:AC:DF:F0:3A:F2:00:01</datapath-id>
<controllers />
</switch>
</logical-switches>
</capable-switch>
</data>
</rpc-reply>
Connect to yangcli as described above. Type in yangcli:
get-config source=running
We can also check directly on the LINC switch:
1> rr(of_config).
[capabilities, capable_switch ...]
2> supervisor:which_children(linc:lookup(0, channel_sup)).
[]
3> linc_ofconfig:get_switch_state(0).
{[], [#logical_switch{... controllers = [], ...
We now add a new controller to the LINC configuration using the edit-config
operation.
4> Controller = {controller, [{id, ["Controller0"]},
{'ip-address', ["127.0.0.1"]},
{port, ["6633"]}, {protocol, ["tcp"]}]},
Config = {'capable-switch', [{xmlns, "urn:onf:of111:config:yang"}],
[{id, ["CapableSwitch0"]}, {'logical-switches',
[{'switch', [{id, ["LogicalSwitch0"]}, {'datapath-id', ["11:11:11:11:11:11:11:11"]},
{enabled, ["true"]}, {controllers, [Controller]}]}]}]}.
{'capable-switch', ...
5> {ok, Y} = enetconf_client:edit_config(C, running, {xml, Config}).
{ok, <<"<?xml ... <rpc-reply ...
Yuma is capable of complex commands involving calling get/edit-config and operations on XML subtrees. Simplest operation without manually picking up subtrees and keys is edit-config: replace whole config with file contents.
Prepare a configuration in XML file, say config1.xml. Run:
edit-config target=running [email protected]
or more complex example
edit-config target=candidate default-operation=merge test-option=test error-option=stop-on-error\
[email protected]
We can see that LINC connected to the controller on the controller side:
XX:XX:XX.XXX [info] Accepted connection from #Port<0.XXXX> {{127,0,0,1}, XXXXX}
We can confirm that using get-config
operation:
6> {ok, Z} = enetconf_client:get_config(C, running).
{ok, <<"<?xml ... ">>}
7> io:format("~p~n", [Z]).
<<"<?xml ... <rpc-reply ... <controllers><controller ... </controllers> ... ">>
Formatted output may look like below. Note that controller to LogicalSwitch1 was added. The data path ID & IP address of controller in this example is different from the above used data path id of 11:11:...:11 and controller IP of 127.0.0.1 as it is from real output.
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
<data>
<capable-switch xmlns="urn:onf:of111:config:yang">
<id>CapableSwitch0</id>
<resources>
<port>
<resource-id>LogicalSwitch0-Port7</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port6</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port4</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port1</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port2</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port3</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch0-Port5</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port7</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port6</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port4</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port1</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port8</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port2</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port3</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
<port>
<resource-id>LogicalSwitch1-Port5</resource-id>
<configuration>
<admin-state>up</admin-state>
<no-receive>false</no-receive>
<no-forward>false</no-forward>
<no-packet-in>false</no-packet-in>
</configuration>
<features>
<advertised>
<rate>invalid</rate>
<auto-negotiate>true</auto-negotiate>
<medium>copper</medium>
<pause>unsupported</pause>
</advertised>
</features>
</port>
</resources>
<logical-switches>
<switch>
<id>LogicalSwitch0</id>
<datapath-id>7A:AC:DF:F0:3A:F2:00:00</datapath-id>
<controllers>
<controller>
<id>Switch0-DefaultController</id>
<ip-address>10.48.11.5</ip-address>
<port>6633</port>
<protocol>tcp</protocol>
</controller>
</controllers>
</switch>
<switch>
<id>LogicalSwitch1</id>
<datapath-id>7A:AC:DF:F0:3A:F2:00:01</datapath-id>
<controllers>
<controller>
<id>Controller0</id>
<ip-address>10.48.11.5</ip-address>
<port>6633</port>
<protocol>tcp</protocol>
</controller>
</controllers>
</switch>
</logical-switches>
</capable-switch>
</data>
</rpc-reply>
Same as above, execute command in yangcli console:
get-config source=running
4> supervisor:which_children(linc:lookup(0, channel_sup)).
[{'127.0.0.1_6633', <0.XXX.0>, worker, [ofs_receiver]}]
5> linc_ofconfig:get_switch_state(0).
{[], [#logical_switch{... controllers = [#controller{ ... }], ...