Openflow 1.1 and later versions allow the use of IP address with
arbitrary bitmask in match fields. This introduces new match fields
for arbitrary bitmask support in REST API.
Newly added fields are:
nw_src_w, nw_dst_w, ipv4_src_w, ipv4_dst_w,
arp_spa_w, arp_tpa_w, ipv6_src_w, ipv6_dst_w.
These fields can be filled with only dotted decimal mask (for IPv4)
or colon-hexadecimal mask (for IPv6), and it always override mask
value in the relative match field which has no '_w' suffix.
For examples,
1. "match": {"dl_type": 2048,
"nw_src": "192.168.1.2",
"nw_src_w": "0.255.0.255"}
In this case, the flow has "nw_src" with value "0.168.0.2/0.255.0.255".
2. "match": {"dl_type": 2048,
"nw_src": "192.168.1.2/255.255.255.0",
"nw_src_w": "0.255.0.255"}
The flow also has "nw_src" with value "0.168.0.2/0.255.0.255" while
original mask defined in "nw_src" has been overridden by "nw_src_w".
If "nw_src" did not exist in match fields, "nw_src_w" is ignored.
Reported-by: Yi-Ching Lee <[email protected]>
Reported-by: Li-Der Chou <[email protected]>
Signed-off-by: Wei-Li Tang <[email protected]>
---
ryu/lib/ofctl_v1_2.py | 24 +++++++++++++++++++++++-
ryu/lib/ofctl_v1_3.py | 24 +++++++++++++++++++++++-
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
index 80d28b0..a86aa89 100644
--- a/ryu/lib/ofctl_v1_2.py
+++ b/ryu/lib/ofctl_v1_2.py
@@ -244,6 +244,16 @@ def to_match(dp, attrs):
'ipv6_src': to_match_ipv6,
'ipv6_dst': to_match_ipv6}
+ # Conversion function mapping for arbitrary bitmask fields
+ convert_w = {'nw_src_w': to_match_ip_bitmask,
+ 'nw_dst_w': to_match_ip_bitmask,
+ 'ipv4_src_w': to_match_ip_bitmask,
+ 'ipv4_dst_w': to_match_ip_bitmask,
+ 'arp_spa_w': to_match_ip_bitmask,
+ 'arp_tpa_w': to_match_ip_bitmask,
+ 'ipv6_src_w': to_match_ipv6_bitmask,
+ 'ipv6_dst_w': to_match_ipv6_bitmask}
+
match_append = {'in_port': match.set_in_port,
'dl_src': match.set_dl_src,
'dl_dst': match.set_dl_dst,
@@ -289,7 +299,11 @@ def to_match(dp, attrs):
key == 'ipv6_src' or key == 'ipv6_dst':
# IP address
ip = value[0]
- mask = value[1]
+ # hook if arbitrary bitmask defined
+ if key + '_w' in attrs:
+ mask = convert_w[key + '_w'](attrs.get(key + '_w'))
+ else:
+ mask = value[1]
match_append[key](ip, mask)
elif key == 'tp_src' or key == 'tp_dst' or \
key == 'tcp_src' or key == 'tcp_dst' or \
@@ -335,6 +349,14 @@ def to_match_ipv6(value):
return ip.ip.words, ip.netmask.words
+def to_match_ip_bitmask(value):
+ return struct.unpack('!I', socket.inet_aton(value))[0]
+
+
+def to_match_ipv6_bitmask(value):
+ return netaddr.IPAddress(value).words
+
+
def match_to_str(ofmatch):
keys = {ofproto_v1_2.OXM_OF_IN_PORT: 'in_port',
ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src',
diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index 4bc739d..d7ca59f 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
@@ -258,6 +258,16 @@ def to_match(dp, attrs):
'tunnel_id': int,
'ipv6_exthdr': int}
+ # Conversion function mapping for arbitrary bitmask fields
+ convert_w = {'nw_src_w': to_match_ip_bitmask,
+ 'nw_dst_w': to_match_ip_bitmask,
+ 'ipv4_src_w': to_match_ip_bitmask,
+ 'ipv4_dst_w': to_match_ip_bitmask,
+ 'arp_spa_w': to_match_ip_bitmask,
+ 'arp_tpa_w': to_match_ip_bitmask,
+ 'ipv6_src_w': to_match_ipv6_bitmask,
+ 'ipv6_dst_w': to_match_ipv6_bitmask}
+
match_append = {'in_port': match.set_in_port,
'dl_src': match.set_dl_src,
'dl_dst': match.set_dl_dst,
@@ -326,7 +336,11 @@ def to_match(dp, attrs):
key == 'ipv6_src' or key == 'ipv6_dst':
# IP address
ip = value[0]
- mask = value[1]
+ # hook if arbitrary bitmask defined
+ if key + '_w' in attrs:
+ mask = convert_w[key + '_w'](attrs.get(key + '_w'))
+ else:
+ mask = value[1]
match_append[key](ip, mask)
elif key == 'tp_src' or key == 'tp_dst' or \
key == 'tcp_src' or key == 'tcp_dst' or \
@@ -377,6 +391,14 @@ def to_match_ipv6(value):
return ip.ip.words, ip.netmask.words
+def to_match_ip_bitmask(value):
+ return struct.unpack('!I', socket.inet_aton(value))[0]
+
+
+def to_match_ipv6_bitmask(value):
+ return netaddr.IPAddress(value).words
+
+
def to_match_metadata(value):
if '/' in value:
metadata = value.split('/')
--
1.7.9.5
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel