Currently, ofctl_v1_[23].py always converts metadata field into str
type for display, but does not convert pbb_isid and tunnel_id fields
even if these fields are masked.
So ofctl_v1_3.py fails to convert masked pbb_isid and tunnel_id fields.

This patch fixes to convert masked match field into str type and not
to convert non-masked field.
These changes will improve maintainability when ofctl_v1_*.py will
support new match fields.

Reported-by: Weijie Liu <[email protected]>
Signed-off-by: IWASE Yusuke <[email protected]>
---
 doc/source/app/ofctl_rest.rst    | 16 +++++++++---
 ryu/lib/ofctl_v1_2.py            | 16 +++---------
 ryu/lib/ofctl_v1_3.py            | 14 +++--------
 ryu/tests/unit/lib/test_ofctl.py | 54 +++++++++++++++++++---------------------
 4 files changed, 44 insertions(+), 56 deletions(-)

diff --git a/doc/source/app/ofctl_rest.rst b/doc/source/app/ofctl_rest.rst
index 25b4795..0343fdf 100644
--- a/doc/source/app/ofctl_rest.rst
+++ b/doc/source/app/ofctl_rest.rst
@@ -1582,7 +1582,9 @@ Description of Match on request messages
         =============== ================================================== 
=======================================================================================================
         in_port         Switch input port (int)                            
{"in_port": 7}
         in_phy_port     Switch physical input port (int)                   
{"in_phy_port": 5, "in_port": 3}
-        metadata        Metadata passed between tables (string)            
{"metadata": "0x1212121212121212"}
+        metadata        Metadata passed between tables (int or string)     
{"metadata": 12345}
+
+                                                                           | 
{"metadata": "0x1212/0xffff"}
         dl_dst          Ethernet destination address (string)              
{"dl_dst": "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"}
         dl_src          Ethernet source address (string)                   
{"dl_src": "aa:bb:cc:11:22:33"}
         eth_dst         Ethernet destination address (string)              
{"eth_dst": "aa:bb:cc:11:22:33/00:00:00:00:ff:ff"}
@@ -1626,9 +1628,15 @@ Description of Match on request messages
         mpls_label      MPLS label (int)                                   
{"mpls_label": 3, "eth_type": 34888}
         mpls_tc         MPLS Traffic Class (int)                           
{"mpls_tc": 2, "eth_type": 34888}
         mpls_bos        MPLS BoS bit (int)                                 
{"mpls_bos": 1, "eth_type": 34888}
-        pbb_isid        PBB I-SID (int)                                    
{"pbb_isid": 5, "eth_type": 35047}
-        tunnel_id       Logical Port Metadata (int)                        
{"tunnel_id": 7}
-        ipv6_exthdr     IPv6 Extension Header pseudo-field (string)        
{"ipv6_exthdr": "0x40/0x1F0", "eth_type": 34525}
+        pbb_isid        PBB I-SID (int or string)                          
{"pbb_isid": 5, "eth_type": 35047}
+
+                                                                           | 
{"pbb_isid": "0x05/0xff", "eth_type": 35047}
+        tunnel_id       Logical Port Metadata (int or string)              
{"tunnel_id": 7}
+
+                                                                           | 
{"tunnel_id": "0x07/0xff"}
+        ipv6_exthdr     IPv6 Extension Header pseudo-field (int or string) 
{"ipv6_exthdr": 3, "eth_type": 34525}
+
+                                                                           | 
{"ipv6_exthdr": "0x40/0x1F0", "eth_type": 34525}
         =============== ================================================== 
=======================================================================================================
 
     .. NOTE::
diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
index 038bb49..7308e1c 100644
--- a/ryu/lib/ofctl_v1_2.py
+++ b/ryu/lib/ofctl_v1_2.py
@@ -188,7 +188,7 @@ def actions_to_str(instructions):
 def to_match(dp, attrs):
     convert = {'in_port': int,
                'in_phy_port': int,
-               'metadata': to_match_metadata,
+               'metadata': to_match_masked_int,
                'dl_dst': to_match_eth,
                'dl_src': to_match_eth,
                'eth_dst': to_match_eth,
@@ -316,8 +316,8 @@ def to_match_vid(value):
                 return int(value, 0)
 
 
-def to_match_metadata(value):
-    if '/' in value:
+def to_match_masked_int(value):
+    if isinstance(value, str) and '/' in value:
         value = value.split('/')
         return str_to_int(value[0]), str_to_int(value[1])
     else:
@@ -351,22 +351,14 @@ def match_to_str(ofmatch):
         value = match_field['OXMTlv']['value']
         if key == 'dl_vlan':
             value = match_vid_to_str(value, mask)
-        elif key == 'metadata':
-            value = match_metadata_to_str(value, mask)
         else:
             if mask is not None:
-                value = value + '/' + mask
-            else:
-                value = value
+                value = str(value) + '/' + str(mask)
         match.setdefault(key, value)
 
     return match
 
 
-def match_metadata_to_str(value, mask):
-    return '%d/%d' % (value, mask) if mask else '%d' % value
-
-
 def match_vid_to_str(value, mask):
     if mask is not None:
         value = '0x%04x/0x%04x' % (value, mask)
diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index 5b709f3..15452e6 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
@@ -249,8 +249,8 @@ def to_match(dp, attrs):
                'mpls_label': int,
                'mpls_tc': int,
                'mpls_bos': int,
-               'pbb_isid': int,
-               'tunnel_id': int,
+               'pbb_isid': to_match_masked_int,
+               'tunnel_id': to_match_masked_int,
                'ipv6_exthdr': to_match_masked_int}
 
     keys = {'dl_dst': 'eth_dst',
@@ -373,22 +373,14 @@ def match_to_str(ofmatch):
         value = match_field['OXMTlv']['value']
         if key == 'dl_vlan':
             value = match_vid_to_str(value, mask)
-        elif key == 'metadata' or key == 'ipv6_exthdr':
-            value = match_masked_int_to_str(value, mask)
         else:
             if mask is not None:
-                value = value + '/' + mask
-            else:
-                value = value
+                value = str(value) + '/' + str(mask)
         match.setdefault(key, value)
 
     return match
 
 
-def match_masked_int_to_str(value, mask):
-    return '%d/%d' % (value, mask) if mask else '%d' % value
-
-
 def match_vid_to_str(value, mask):
     if mask is not None:
         value = '0x%04x/0x%04x' % (value, mask)
diff --git a/ryu/tests/unit/lib/test_ofctl.py b/ryu/tests/unit/lib/test_ofctl.py
index 1c02f35..d63a1da 100644
--- a/ryu/tests/unit/lib/test_ofctl.py
+++ b/ryu/tests/unit/lib/test_ofctl.py
@@ -37,15 +37,11 @@ LOG = logging.getLogger('test_ofctl_v1_2, v1_3')
 """ Common Functions """
 
 
-def _str_to_int(src):
-    if isinstance(src, str):
-        if src.startswith("0x") or src.startswith("0X"):
-            dst = int(src, 16)
-        else:
-            dst = int(src)
-    else:
-        dst = src
-    return dst
+def _str_to_int(v):
+    try:
+        return int(v, 0)
+    except (ValueError, TypeError):
+        return v
 
 
 def _to_match_eth(value):
@@ -74,6 +70,12 @@ def _to_match_masked_int(value):
         return _str_to_int(value), None
 
 
+def _to_masked_int_str(value):
+    v, m = _to_match_masked_int(value)
+    v &= m
+    return '%d/%d' % (v, m)
+
+
 conv_of10_to_of12_dict = {
     'dl_dst': 'eth_dst',
     'dl_src': 'eth_src',
@@ -323,20 +325,16 @@ class Test_ofctl(unittest.TestCase):
                     eq_(test.expected_value['vlan_vid'][
                         value]['to_match'], field_value)
                 return
-            elif key == 'metadata' or key == 'ipv6_exthdr':
-                # Metadata or IPv6 Extension Header pseudo-field
-                value, mask = _to_match_masked_int(value)
-                if mask is not None:
+            else:
+                if isinstance(value, str) and '/' in value:
                     # with mask
+                    value, mask = _to_match_masked_int(value)
                     value &= mask
                     eq_(value, field_value[0])
                     eq_(mask, field_value[1])
                 else:
                     # without mask
-                    eq_(value, field_value)
-                return
-            else:
-                eq_(value, field_value)
+                    eq_(_str_to_int(value), field_value)
                 return
 
         for key, value in attrs.items():
@@ -403,21 +401,14 @@ class Test_ofctl(unittest.TestCase):
                     eq_(test.expected_value['vlan_vid'][
                         value]['to_str'], field_value)
                 return
-            elif key == 'metadata' or key == 'ipv6_exthdr':
-                # Metadata or IPv6 Extension Header pseudo-field
-                value, mask = _to_match_masked_int(value)
-                if mask is not None:
+            else:
+                if isinstance(value, str) and '/' in value:
                     # with mask
-                    field_value = field_value.split('/')
-                    value &= mask
-                    eq_(str(value), field_value[0])
-                    eq_(str(mask), field_value[1])
+                    value = _to_masked_int_str(value)
+                    eq_(value, field_value)
                 else:
                     # without mask
-                    eq_(str(value), field_value)
-                return
-            else:
-                eq_(value, field_value)
+                    eq_(_str_to_int(value), field_value)
                 return
 
         for key, value in attrs.items():
@@ -565,6 +556,7 @@ class test_data_v1_2(test_data_base):
         self.attr_list = [
             {'in_port': 7},
             {'in_phy_port': 5, 'in_port': 3},
+            {'metadata': 12345},
             {'metadata': '0x1212121212121212'},
             {'metadata': '0x19af28be37fa91b/0x1010101010101010'},
             {'dl_src': "aa:bb:cc:11:22:33"},
@@ -757,7 +749,11 @@ class test_data_v1_3(test_data_v1_2):
             [
                 {'mpls_bos': 3, 'eth_type': 0x8848},
                 {'pbb_isid': 5, 'eth_type': 0x88E7},
+                {'pbb_isid': "0x05", 'eth_type': 0x88E7},
+                {'pbb_isid': "0x05/0xff", 'eth_type': 0x88E7},
                 {'tunnel_id': 7},
+                {'tunnel_id': "0x07"},
+                {'tunnel_id': "0x07/0xff"},
                 {'ipv6_exthdr': 3, 'eth_type': 0x86dd},
                 {'ipv6_exthdr': "0x40", 'eth_type': 0x86dd},
                 {'ipv6_exthdr': "0x40/0x1F0", 'eth_type': 0x86dd},
-- 
1.9.1


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to