# How to push multiple flows to the controller at once

Hi everyone. This problem is driving me nuts: I have an external controller (out-of-band) conneted to a local hypervisor where running Open vSwitch with a vmbr0 bridge.

When I manually add the following flows to Open vSwitch, it works like expected and the switch redirects traffics like a charm:

ovs-ofctl add-flow vmbr0 priority=20000,ip,nw_dst=10.30.5.1,actions=NORMAL (


But I want to control the bridges from ODL but I haven't been able to figure out how to send these flows at once to the ODL controller by using postman because if I send the first one it gets stored at CONFIG but when I send the second, then the first one gets deleted and remains only the last one.

This is the way I am sending the flows to this URL: http://controller:8181/restconf/confi...

FLOW1:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<node xmlns="urn:opendaylight:inventory">
<id>openflow:1</id>
<table xmlns="urn:opendaylight:flow:inventory">
<id>0</id>
<flow>
<priority>20000</priority>
<flow-name>FLOW1</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<ipv4-destination>10.30.5.1/32</ipv4-destination>
</match>
<id>1</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<output-action>
<output-node-connector>NORMAL</output-node-connector>
</output-action>
<order>0</order>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>
</table>
<pass-through xmlns="urn:opendaylight:netconf-node-inventory"/>
</node>


FLOW2:

<?xml version="1.0"?>
<node xmlns="urn:opendaylight:inventory">
<id>openflow:1</id>
<table xmlns="urn:opendaylight:flow:inventory">
<id>0</id>
<flow>
<id>2</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<strip-vlan-action/>
</action>
</apply-actions>
</instruction>
</instructions>
<priority>15000</priority>
<match>
<ipv4-source>10.30.5.0/24</ipv4-source>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
</match>
<flow-name>FLOW2</flow-name>
</flow>
</table>
<pass-through xmlns="urn:opendaylight:netconf-node-inventory"/>
</node>


The first flow gets deleted from http://controller:8181/restconf/confi...

What am I doing wrong?

Thank you very much

edit retag close merge delete

Sort by » oldest newest most voted

Your URL is referring to "node/openflow:1" and you are passing complete <node>, so ideally you are overriding your complete flow table with new table (id = 0) in both the calls. That's why it might look like overriding flows as well, because all other parameters are same.

If you would like to add flow one by one using postman (two consecutive post calls) then you should use:

Note: If your config datastore is completely empty, then there is a chance that table (id = 0) is does not exist then you should try adding first flow as you were doing earlier & then second flow as I suggested below (under table 0).

URL:

http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0


With following contents:

Flow 1:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<priority>20000</priority>
<flow-name>FLOW1</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<ipv4-destination>10.30.5.1/32</ipv4-destination>
</match>
<id>1</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<output-action>
<output-node-connector>NORMAL</output-node-connector>
</output-action>
<order>0</order>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>


Flow 2:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<id>2</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<order>0</order>
<strip-vlan-action/>
</action>
</apply-actions>
</instruction>
</instructions>
<priority>15000</priority>
<match>
<ipv4-source>10.30.5.0/24</ipv4-source>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
</match>
<flow-name>FLOW2</flow-name>
</flow>

more

Finally I've found the issue. I was sending an xml with the wrong tags. I wish there was a simpler way to build the right XML without using YANG, but this helped me a lot. Thanks.

( 2016-10-23 06:21:14 -0800 )edit

Hey pcolomes, do you mind elaborating on what you mean by "I was sending an xml with the wrong tags"? Also, if you have one, would you mind posting an example? Thanks!

( 2016-12-01 12:10:19 -0800 )edit

Interesting issue... It almost sounds like ODL considers your 2nd flow to be a flow-mod to the first flow, so it updates the original flow with the details of the 2nd flow... I assume your changing the flow id in the put line to match the respective flow your adding in postman? Here's the syntax I use when adding multiple flows to a switch (hardware or openvswtch):

Hope that helps!

more

Thank you sterdnotshaken! Now I wonder if it's correct to send a single REST call with Postman to the controller containing all the flows at once or if I must send one call for each flow

( 2016-10-19 17:23:24 -0800 )edit

You can do that, and it is actually more performant than sending flow one by one.

( 2016-10-21 05:40:05 -0800 )edit

You can send as many flows as required with different flow ids and priority.

This bash script might be useful; I am pushing 1000 flows from Controller to the bridge.

# !/bin/bash

for rank in $(seq 1 1000); do curl -X PUT -H "Content-Type:application/json" -H "Accept:application/json" --user admin:admin http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/10/flow/$rank --data '{"flow": [{"id": "'"$rank"'", "match": { "ethernet-match": { "ethernet-type": { "type": "2048" } },"ip-match": { "ip-protocol": "6", "ip-proto": "ipv4" }, "tcp-source-port": "'"$rank"'"},"instructions": {"instruction": [{"order": "0","apply-actions": {"action": [{"order": "0","drop-action": {}}]}}]},"flow-name": "FT10","priority": "'"\$rank"'","table_id": "10"}]}';


done

Hope this helps.

Thanks, Swathi

more