ofctl_v1_[23]: Convert masked match value into str

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 <wliu43@illinois.edu>
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
Yusuke Iwase 2015-08-25 16:02:15 +09:00 committed by FUJITA Tomonori
parent 9bca06c31c
commit 2701fa129f
4 changed files with 44 additions and 56 deletions

View File

@ -1585,7 +1585,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"}
@ -1629,9 +1631,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::

View File

@ -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)

View File

@ -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)

View File

@ -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},