diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2016-01-19 13:46:10 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-01-19 13:38:12 +0900 |
commit | 19e49c861f0fa0228712c8f03dfe4af39e24122b (patch) | |
tree | 259901d4af8cbf9052792ac82215448c57b60784 | |
parent | 9571fde7dddfafe48d961a7ffd312e3c872687b2 (diff) |
lib/ofctl: Add utility library for ofctl_v1_*.py
This patch enables ofctl_v1_*.py to use the reserved OpenFlow
numbers (e.g. port numbering such as "OFPP_CONTROLLER") in the
request and reply parameters of ofctl_rest.py.
Example:
- When adding a flow entry:
$ curl -X POST -d '{
"dpid": 1,
"actions":[
{
"type": "OUTPUT",
"port": "CONTROLLER"
}
]
}' http://localhost:8080/stats/flowentry/add
- When getting flows stats:
$ curl -X GET http://localhost:8080/stats/flow/1
{
"1": [
{
...
"actions": [
"OUTPUT:CONTROLLER"
],
...
}
]
}
Suggested-by: Sergio Andres Rivera Polanco <sergiorivera88@gmail.com>
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/lib/ofctl_utils.py | 92 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_0.py | 50 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_2.py | 99 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_3.py | 112 |
4 files changed, 239 insertions, 114 deletions
diff --git a/ryu/lib/ofctl_utils.py b/ryu/lib/ofctl_utils.py new file mode 100644 index 00000000..978d1f6e --- /dev/null +++ b/ryu/lib/ofctl_utils.py @@ -0,0 +1,92 @@ +# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + + +LOG = logging.getLogger(__name__) + + +def str_to_int(str_num): + return int(str(str_num), 0) + + +class OFCtlUtil(object): + + def __init__(self, ofproto): + self.ofproto = ofproto + + def _reserved_num_from_user(self, num, prefix): + if isinstance(num, int): + return num + else: + if num.startswith(prefix): + return getattr(self.ofproto, num) + else: + return getattr(self.ofproto, prefix + num.upper()) + + def _reserved_num_to_user(self, num, prefix): + for k, v in self.ofproto.__dict__.items(): + if k.startswith(prefix) and v == num: + return k.replace(prefix, '') + return num + + def ofp_port_from_user(self, port): + return self._reserved_num_from_user(port, 'OFPP_') + + def ofp_port_to_user(self, port): + return self._reserved_num_to_user(port, 'OFPP_') + + def ofp_table_from_user(self, table): + return self._reserved_num_from_user(table, 'OFPTT_') + + def ofp_table_to_user(self, table): + return self._reserved_num_to_user(table, 'OFPTT_') + + def ofp_cml_from_user(self, max_len): + return self._reserved_num_from_user(max_len, 'OFPCML_') + + def ofp_cml_to_user(self, max_len): + return self._reserved_num_to_user(max_len, 'OFPCML_') + + def ofp_group_from_user(self, group): + return self._reserved_num_from_user(group, 'OFPG_') + + def ofp_group_to_user(self, group): + return self._reserved_num_to_user(group, 'OFPG_') + + def ofp_buffer_from_user(self, buffer): + if buffer in ['OFP_NO_BUFFER', 'NO_BUFFER']: + return self.ofproto.OFP_NO_BUFFER + else: + return buffer + + def ofp_buffer_to_user(self, buffer): + if self.ofproto.OFP_NO_BUFFER == buffer: + return 'NO_BUFFER' + else: + return buffer + + def ofp_meter_from_user(self, meter): + return self._reserved_num_from_user(meter, 'OFPM_') + + def ofp_meter_to_user(self, meter): + return self._reserved_num_to_user(meter, 'OFPM_') + + def ofp_queue_from_user(self, queue): + return self._reserved_num_from_user(queue, 'OFPQ_') + + def ofp_queue_to_user(self, queue): + return self._reserved_num_to_user(queue, 'OFPQ_') diff --git a/ryu/lib/ofctl_v1_0.py b/ryu/lib/ofctl_v1_0.py index 430d63f2..97ffa7b2 100644 --- a/ryu/lib/ofctl_v1_0.py +++ b/ryu/lib/ofctl_v1_0.py @@ -19,6 +19,7 @@ import logging from ryu.ofproto import ofproto_v1_0 from ryu.lib import hub +from ryu.lib import ofctl_utils from ryu.lib.mac import haddr_to_bin, haddr_to_str @@ -26,13 +27,16 @@ LOG = logging.getLogger('ryu.lib.ofctl_v1_0') DEFAULT_TIMEOUT = 1.0 # TODO:XXX +UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_0) + def to_actions(dp, acts): actions = [] for a in acts: action_type = a.get('type') if action_type == 'OUTPUT': - port = int(a.get('port', ofproto_v1_0.OFPP_NONE)) + port = UTIL.ofp_port_from_user( + a.get('port', ofproto_v1_0.OFPP_NONE)) # NOTE: The reason of this magic number (0xffe5) # is because there is no good constant in of1.0. # The same value as OFPCML_MAX of of1.2 and of1.3 is used. @@ -68,8 +72,9 @@ def to_actions(dp, acts): tp_dst = int(a.get('tp_dst', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpDst(tp_dst)) elif action_type == 'ENQUEUE': - port = int(a.get('port', ofproto_v1_0.OFPP_NONE)) - queue_id = int(a.get('queue_id', 0)) + port = UTIL.ofp_port_from_user( + a.get('port', ofproto_v1_0.OFPP_NONE)) + queue_id = UTIL.ofp_queue_from_user(a.get('queue_id', 0)) actions.append(dp.ofproto_parser.OFPActionEnqueue(port, queue_id)) else: LOG.error('Unknown action type') @@ -83,7 +88,8 @@ def actions_to_str(acts): action_type = a.cls_action_type if action_type == ofproto_v1_0.OFPAT_OUTPUT: - buf = 'OUTPUT:' + str(a.port) + port = UTIL.ofp_port_to_user(a.port) + buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID: buf = 'SET_VLAN_VID:' + str(a.vlan_vid) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP: @@ -107,7 +113,9 @@ def actions_to_str(acts): elif action_type == ofproto_v1_0.OFPAT_SET_TP_DST: buf = 'SET_TP_DST:' + str(a.tp) elif action_type == ofproto_v1_0.OFPAT_ENQUEUE: - buf = 'ENQUEUE:' + str(a.port) + ":" + str(a.queue_id) + port = UTIL.ofp_port_to_user(a.port) + queue = UTIL.ofp_queue_to_user(a.queue_id) + buf = 'ENQUEUE:' + str(port) + ":" + str(queue) elif action_type == ofproto_v1_0.OFPAT_VENDOR: buf = 'VENDOR' else: @@ -146,7 +154,7 @@ def to_match(dp, attrs): for key, value in attrs.items(): if key == 'in_port': - in_port = int(value) + in_port = UTIL.ofp_port_from_user(value) wildcards &= ~ofp.OFPFW_IN_PORT elif key == 'dl_src': dl_src = haddr_to_bin(value) @@ -210,7 +218,7 @@ def match_to_str(m): match = {} if ~m.wildcards & ofproto_v1_0.OFPFW_IN_PORT: - match['in_port'] = m.in_port + match['in_port'] = UTIL.ofp_port_to_user(m.in_port) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_SRC: match['dl_src'] = haddr_to_str(m.dl_src) @@ -328,8 +336,10 @@ def get_queue_stats(dp, waiters): def get_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} match = to_match(dp, flow.get('match', {})) - table_id = int(flow.get('table_id', 0xff)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_NONE)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', 0xff)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_NONE)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, 0, match, table_id, out_port) @@ -353,7 +363,7 @@ def get_flow_stats(dp, waiters, flow=None): 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, - 'table_id': stats.table_id} + 'table_id': UTIL.ofp_table_to_user(stats.table_id)} flows.append(s) flows = {str(dp.id): flows} return flows @@ -362,8 +372,10 @@ def get_flow_stats(dp, waiters, flow=None): def get_aggregate_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} match = to_match(dp, flow.get('match', {})) - table_id = int(flow.get('table_id', 0xff)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_NONE)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', 0xff)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_NONE)) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, 0, match, table_id, out_port) @@ -422,7 +434,7 @@ def get_table_stats(dp, waiters): for k, v in match_convert.items(): if (1 << k) & stat.wildcards: wildcards.append(v) - s = {'table_id': stat.table_id, + s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'name': stat.name.decode('utf-8'), 'wildcards': wildcards, 'max_entries': stat.max_entries, @@ -444,7 +456,7 @@ def get_port_stats(dp, waiters): ports = [] for msg in msgs: for stats in msg.body: - s = {'port_no': stats.port_no, + s = {'port_no': UTIL.ofp_port_to_user(stats.port_no), 'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, @@ -473,7 +485,7 @@ def get_port_desc(dp, waiters): for msg in msgs: stats = msg.ports for stat in stats.values(): - d = {'port_no': stat.port_no, + d = {'port_no': UTIL.ofp_port_to_user(stat.port_no), 'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8'), 'config': stat.config, @@ -491,8 +503,10 @@ def mod_flow_entry(dp, flow, cmd): cookie = int(flow.get('cookie', 0)) priority = int(flow.get('priority', dp.ofproto.OFP_DEFAULT_PRIORITY)) - buffer_id = int(flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_NONE)) + buffer_id = UTIL.ofp_buffer_from_user( + flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_NONE)) flags = int(flow.get('flags', 0)) idle_timeout = int(flow.get('idle_timeout', 0)) hard_timeout = int(flow.get('hard_timeout', 0)) @@ -522,7 +536,7 @@ def delete_flow_entry(dp): def mod_port_behavior(dp, port_config): - port_no = int(port_config.get('port_no', 0)) + port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = int(port_config.get('config', 0)) mask = int(port_config.get('mask', 0)) diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py index 3566f0f1..23ba30c2 100644 --- a/ryu/lib/ofctl_v1_2.py +++ b/ryu/lib/ofctl_v1_2.py @@ -22,22 +22,14 @@ from ryu.ofproto import inet from ryu.ofproto import ofproto_v1_2 from ryu.ofproto import ofproto_v1_2_parser from ryu.lib import hub +from ryu.lib import ofctl_utils LOG = logging.getLogger('ryu.lib.ofctl_v1_2') DEFAULT_TIMEOUT = 1.0 - -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 +UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_2) def to_action(dp, dic): @@ -46,8 +38,8 @@ def to_action(dp, dic): action_type = dic.get('type') if action_type == 'OUTPUT': - out_port = int(dic.get('port', ofp.OFPP_ANY)) - max_len = int(dic.get('max_len', ofp.OFPCML_MAX)) + out_port = UTIL.ofp_port_from_user(dic.get('port', ofp.OFPP_ANY)) + max_len = UTIL.ofp_cml_from_user(dic.get('max_len', ofp.OFPCML_MAX)) result = parser.OFPActionOutput(out_port, max_len) elif action_type == 'COPY_TTL_OUT': result = parser.OFPActionCopyTtlOut() @@ -70,10 +62,10 @@ def to_action(dp, dic): ethertype = int(dic.get('ethertype')) result = parser.OFPActionPopMpls(ethertype) elif action_type == 'SET_QUEUE': - queue_id = int(dic.get('queue_id')) + queue_id = UTIL.ofp_queue_from_user(dic.get('queue_id')) result = parser.OFPActionSetQueue(queue_id) elif action_type == 'GROUP': - group_id = int(dic.get('group_id')) + group_id = UTIL.ofp_group_from_user(dic.get('group_id')) result = parser.OFPActionGroup(group_id) elif action_type == 'SET_NW_TTL': nw_ttl = int(dic.get('nw_ttl')) @@ -118,11 +110,11 @@ def to_actions(dp, acts): inst.append(parser.OFPInstructionActions( ofp.OFPIT_CLEAR_ACTIONS, [])) elif action_type == 'GOTO_TABLE': - table_id = int(a.get('table_id')) + table_id = UTIL.ofp_table_from_user(a.get('table_id')) inst.append(parser.OFPInstructionGotoTable(table_id)) elif action_type == 'WRITE_METADATA': - metadata = str_to_int(a.get('metadata')) - metadata_mask = (str_to_int(a['metadata_mask']) + metadata = ofctl_utils.str_to_int(a.get('metadata')) + metadata_mask = (ofctl_utils.str_to_int(a['metadata_mask']) if 'metadata_mask' in a else parser.UINT64_MAX) inst.append( @@ -141,7 +133,8 @@ def action_to_str(act): action_type = act.cls_action_type if action_type == ofproto_v1_2.OFPAT_OUTPUT: - buf = 'OUTPUT:' + str(act.port) + port = UTIL.ofp_port_to_user(act.port) + buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_2.OFPAT_COPY_TTL_OUT: buf = 'COPY_TTL_OUT' elif action_type == ofproto_v1_2.OFPAT_COPY_TTL_IN: @@ -159,9 +152,11 @@ def action_to_str(act): elif action_type == ofproto_v1_2.OFPAT_POP_MPLS: buf = 'POP_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_2.OFPAT_SET_QUEUE: - buf = 'SET_QUEUE:' + str(act.queue_id) + queue_id = UTIL.ofp_queue_to_user(act.queue_id) + buf = 'SET_QUEUE:' + str(queue_id) elif action_type == ofproto_v1_2.OFPAT_GROUP: - buf = 'GROUP:' + str(act.group_id) + group_id = UTIL.ofp_group_to_user(act.group_id) + buf = 'GROUP:' + str(group_id) elif action_type == ofproto_v1_2.OFPAT_SET_NW_TTL: buf = 'SET_NW_TTL:' + str(act.nw_ttl) elif action_type == ofproto_v1_2.OFPAT_DEC_NW_TTL: @@ -194,7 +189,8 @@ def actions_to_str(instructions): actions.append('UNKNOWN') elif isinstance(instruction, ofproto_v1_2_parser.OFPInstructionGotoTable): - buf = 'GOTO_TABLE:' + str(instruction.table_id) + table_id = UTIL.ofp_table_to_user(instruction.table_id) + buf = 'GOTO_TABLE:' + str(table_id) actions.append(buf) elif isinstance(instruction, @@ -212,7 +208,7 @@ def actions_to_str(instructions): def to_match(dp, attrs): - convert = {'in_port': int, + convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': int, 'metadata': to_match_masked_int, 'dl_dst': to_match_eth, @@ -345,9 +341,10 @@ def to_match_vid(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]) + return (ofctl_utils.str_to_int(value[0]), + ofctl_utils.str_to_int(value[1])) else: - return str_to_int(value) + return ofctl_utils.str_to_int(value) def match_to_str(ofmatch): @@ -377,6 +374,8 @@ def match_to_str(ofmatch): value = match_field['OXMTlv']['value'] if key == 'dl_vlan': value = match_vid_to_str(value, mask) + elif key == 'in_port': + value = UTIL.ofp_port_to_user(value) else: if mask is not None: value = str(value) + '/' + str(mask) @@ -455,6 +454,7 @@ def get_queue_stats(dp, waiters): def get_queue_config(dp, port, waiters): ofp = dp.ofproto + port = UTIL.ofp_port_from_user(port) stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) msgs = [] send_stats_request(dp, stats, waiters, msgs) @@ -478,11 +478,11 @@ def get_queue_config(dp, port, waiters): p['experimenter'] = prop.experimenter p['data'] = prop.data prop_list.append(p) - q = {'port': queue.port, + q = {'port': UTIL.ofp_port_to_user(queue.port), 'properties': prop_list, - 'queue_id': queue.queue_id} + 'queue_id': UTIL.ofp_queue_to_user(queue.queue_id)} queue_list.append(q) - c = {'port': config.port, + c = {'port': UTIL.ofp_port_to_user(config.port), 'queues': queue_list} configs.append(c) configs = {str(dp.id): configs} @@ -492,9 +492,12 @@ def get_queue_config(dp, port, waiters): def get_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} - table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', dp.ofproto.OFPTT_ALL)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) @@ -520,7 +523,7 @@ def get_flow_stats(dp, waiters, flow=None): 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, - 'table_id': stats.table_id, + 'table_id': UTIL.ofp_table_to_user(stats.table_id), 'length': stats.length} flows.append(s) flows = {str(dp.id): flows} @@ -530,9 +533,12 @@ def get_flow_stats(dp, waiters, flow=None): def get_aggregate_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} - table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', dp.ofproto.OFPTT_ALL)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) @@ -658,7 +664,7 @@ def get_table_stats(dp, waiters): for k, v in table_conf_convert.items(): if (1 << k) & stat.config: config.append(v) - s = {'table_id': stat.table_id, + s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'name': stat.name.decode('utf-8'), 'match': match, 'wildcards': wildcards, @@ -689,7 +695,7 @@ def get_port_stats(dp, waiters): ports = [] for msg in msgs: for stats in msg.body: - s = {'port_no': stats.port_no, + s = {'port_no': UTIL.ofp_port_to_user(stats.port_no), 'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, @@ -722,7 +728,7 @@ def get_group_stats(dp, waiters): 'byte_count': bucket_counter.byte_count} bucket_counters.append(c) g = {'length': stats.length, - 'group_id': stats.group_id, + 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'ref_count': stats.ref_count, 'packet_count': stats.packet_count, 'byte_count': stats.byte_count, @@ -817,7 +823,7 @@ def get_group_desc(dp, waiters): 'actions': actions} buckets.append(b) d = {'type': type_convert.get(stats.type), - 'group_id': stats.group_id, + 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'buckets': buckets} descs.append(d) descs = {str(dp.id): descs} @@ -835,7 +841,7 @@ def get_port_desc(dp, waiters): for msg in msgs: stats = msg.ports for stat in stats.values(): - d = {'port_no': stat.port_no, + d = {'port_no': UTIL.ofp_port_to_user(stat.port_no), 'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8'), 'config': stat.config, @@ -854,13 +860,16 @@ def get_port_desc(dp, waiters): def mod_flow_entry(dp, flow, cmd): cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) - table_id = int(flow.get('table_id', 0)) + table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = int(flow.get('idle_timeout', 0)) hard_timeout = int(flow.get('hard_timeout', 0)) priority = int(flow.get('priority', 0)) - buffer_id = int(flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + buffer_id = UTIL.ofp_buffer_from_user( + flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) flags = int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_actions(dp, flow.get('actions', [])) @@ -884,7 +893,7 @@ def mod_group_entry(dp, group, cmd): if type_ is None: LOG.error('Unknown group type: %s', group.get('type')) - group_id = int(group.get('group_id', 0)) + group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) buckets = [] for bucket in group.get('buckets', []): @@ -906,7 +915,7 @@ def mod_group_entry(dp, group, cmd): def mod_port_behavior(dp, port_config): - port_no = int(port_config.get('port_no', 0)) + port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = int(port_config.get('config', 0)) mask = int(port_config.get('mask', 0)) diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py index 28560e6a..2de9e37f 100644 --- a/ryu/lib/ofctl_v1_3.py +++ b/ryu/lib/ofctl_v1_3.py @@ -22,22 +22,14 @@ from ryu.ofproto import inet from ryu.ofproto import ofproto_v1_3 from ryu.ofproto import ofproto_v1_3_parser from ryu.lib import hub +from ryu.lib import ofctl_utils LOG = logging.getLogger('ryu.lib.ofctl_v1_3') DEFAULT_TIMEOUT = 1.0 - -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 +UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_3) def to_action(dp, dic): @@ -46,8 +38,8 @@ def to_action(dp, dic): action_type = dic.get('type') if action_type == 'OUTPUT': - out_port = int(dic.get('port', ofp.OFPP_ANY)) - max_len = int(dic.get('max_len', ofp.OFPCML_MAX)) + out_port = UTIL.ofp_port_from_user(dic.get('port', ofp.OFPP_ANY)) + max_len = UTIL.ofp_cml_from_user(dic.get('max_len', ofp.OFPCML_MAX)) result = parser.OFPActionOutput(out_port, max_len) elif action_type == 'COPY_TTL_OUT': result = parser.OFPActionCopyTtlOut() @@ -70,10 +62,10 @@ def to_action(dp, dic): ethertype = int(dic.get('ethertype')) result = parser.OFPActionPopMpls(ethertype) elif action_type == 'SET_QUEUE': - queue_id = int(dic.get('queue_id')) + queue_id = UTIL.ofp_queue_from_user(dic.get('queue_id')) result = parser.OFPActionSetQueue(queue_id) elif action_type == 'GROUP': - group_id = int(dic.get('group_id')) + group_id = UTIL.ofp_group_from_user(dic.get('group_id')) result = parser.OFPActionGroup(group_id) elif action_type == 'SET_NW_TTL': nw_ttl = int(dic.get('nw_ttl')) @@ -124,18 +116,18 @@ def to_actions(dp, acts): inst.append(parser.OFPInstructionActions( ofp.OFPIT_CLEAR_ACTIONS, [])) elif action_type == 'GOTO_TABLE': - table_id = int(a.get('table_id')) + table_id = UTIL.ofp_table_from_user(a.get('table_id')) inst.append(parser.OFPInstructionGotoTable(table_id)) elif action_type == 'WRITE_METADATA': - metadata = str_to_int(a.get('metadata')) - metadata_mask = (str_to_int(a['metadata_mask']) + metadata = ofctl_utils.str_to_int(a.get('metadata')) + metadata_mask = (ofctl_utils.str_to_int(a['metadata_mask']) if 'metadata_mask' in a else parser.UINT64_MAX) inst.append( parser.OFPInstructionWriteMetadata( metadata, metadata_mask)) elif action_type == 'METER': - meter_id = int(a.get('meter_id')) + meter_id = UTIL.ofp_meter_from_user(a.get('meter_id')) inst.append(parser.OFPInstructionMeter(meter_id)) else: LOG.error('Unknown action type: %s', action_type) @@ -150,7 +142,8 @@ def action_to_str(act): action_type = act.cls_action_type if action_type == ofproto_v1_3.OFPAT_OUTPUT: - buf = 'OUTPUT:' + str(act.port) + port = UTIL.ofp_port_to_user(act.port) + buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_OUT: buf = 'COPY_TTL_OUT' elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_IN: @@ -168,9 +161,11 @@ def action_to_str(act): elif action_type == ofproto_v1_3.OFPAT_POP_MPLS: buf = 'POP_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_3.OFPAT_SET_QUEUE: - buf = 'SET_QUEUE:' + str(act.queue_id) + queue_id = UTIL.ofp_queue_to_user(act.queue_id) + buf = 'SET_QUEUE:' + str(queue_id) elif action_type == ofproto_v1_3.OFPAT_GROUP: - buf = 'GROUP:' + str(act.group_id) + group_id = UTIL.ofp_group_to_user(act.group_id) + buf = 'GROUP:' + str(group_id) elif action_type == ofproto_v1_3.OFPAT_SET_NW_TTL: buf = 'SET_NW_TTL:' + str(act.nw_ttl) elif action_type == ofproto_v1_3.OFPAT_DEC_NW_TTL: @@ -207,7 +202,8 @@ def actions_to_str(instructions): actions.append('UNKNOWN') elif isinstance(instruction, ofproto_v1_3_parser.OFPInstructionGotoTable): - buf = 'GOTO_TABLE:' + str(instruction.table_id) + table_id = UTIL.ofp_table_to_user(instruction.table_id) + buf = 'GOTO_TABLE:' + str(table_id) actions.append(buf) elif isinstance(instruction, @@ -220,7 +216,8 @@ def actions_to_str(instructions): elif isinstance(instruction, ofproto_v1_3_parser.OFPInstructionMeter): - buf = 'METER:' + str(instruction.meter_id) + meter_id = UTIL.ofp_meter_to_user(instruction.meter_id) + buf = 'METER:' + str(meter_id) actions.append(buf) else: @@ -230,7 +227,7 @@ def actions_to_str(instructions): def to_match(dp, attrs): - convert = {'in_port': int, + convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': int, 'metadata': to_match_masked_int, 'dl_dst': to_match_eth, @@ -367,9 +364,10 @@ def to_match_vid(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]) + return (ofctl_utils.str_to_int(value[0]), + ofctl_utils.str_to_int(value[1])) else: - return str_to_int(value) + return ofctl_utils.str_to_int(value) def match_to_str(ofmatch): @@ -400,6 +398,8 @@ def match_to_str(ofmatch): value = match_field['OXMTlv']['value'] if key == 'dl_vlan': value = match_vid_to_str(value, mask) + elif key == 'in_port': + value = UTIL.ofp_port_to_user(value) else: if mask is not None: value = str(value) + '/' + str(mask) @@ -480,6 +480,7 @@ def get_queue_stats(dp, waiters): def get_queue_config(dp, port, waiters): ofp = dp.ofproto + port = UTIL.ofp_port_from_user(port) stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) msgs = [] send_stats_request(dp, stats, waiters, msgs) @@ -503,11 +504,11 @@ def get_queue_config(dp, port, waiters): p['experimenter'] = prop.experimenter p['data'] = prop.data prop_list.append(p) - q = {'port': queue.port, + q = {'port': UTIL.ofp_port_to_user(queue.port), 'properties': prop_list, - 'queue_id': queue.queue_id} + 'queue_id': UTIL.ofp_queue_to_user(queue.queue_id)} queue_list.append(q) - c = {'port': config.port, + c = {'port': UTIL.ofp_port_to_user(config.port), 'queues': queue_list} configs.append(c) configs = {str(dp.id): configs} @@ -517,10 +518,13 @@ def get_queue_config(dp, port, waiters): def get_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} - table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = int(flow.get('flags', 0)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) @@ -548,7 +552,7 @@ def get_flow_stats(dp, waiters, flow=None): 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, - 'table_id': stats.table_id, + 'table_id': UTIL.ofp_table_to_user(stats.table_id), 'length': stats.length, 'flags': stats.flags} flows.append(s) @@ -559,10 +563,13 @@ def get_flow_stats(dp, waiters, flow=None): def get_aggregate_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} - table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) + table_id = UTIL.ofp_table_from_user( + flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = int(flow.get('flags', 0)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) @@ -595,7 +602,7 @@ def get_table_stats(dp, waiters): for msg in msgs: stats = msg.body for stat in stats: - s = {'table_id': stat.table_id, + s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'active_count': stat.active_count, 'lookup_count': stat.lookup_count, 'matched_count': stat.matched_count} @@ -687,7 +694,7 @@ def get_table_features(dp, waiters): elif prop.type in p_type_experimenter: pass properties.append(p) - s = {'table_id': stat.table_id, + s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'name': stat.name.decode('utf-8'), 'metadata_match': stat.metadata_match, 'metadata_write': stat.metadata_write, @@ -710,7 +717,7 @@ def get_port_stats(dp, waiters): ports = [] for msg in msgs: for stats in msg.body: - s = {'port_no': stats.port_no, + s = {'port_no': UTIL.ofp_port_to_user(stats.port_no), 'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, @@ -744,7 +751,7 @@ def get_meter_stats(dp, waiters): b = {'packet_band_count': band.packet_band_count, 'byte_band_count': band.byte_band_count} bands.append(b) - s = {'meter_id': stats.meter_id, + s = {'meter_id': UTIL.ofp_meter_to_user(stats.meter_id), 'len': stats.len, 'flow_count': stats.flow_count, 'packet_in_count': stats.packet_in_count, @@ -826,7 +833,7 @@ def get_meter_config(dp, waiters): if k & config.flags: c_flags.append(v) c = {'flags': c_flags, - 'meter_id': config.meter_id, + 'meter_id': UTIL.ofp_meter_to_user(config.meter_id), 'bands': bands} configs.append(c) configs = {str(dp.id): configs} @@ -848,7 +855,7 @@ def get_group_stats(dp, waiters): 'byte_count': bucket_stat.byte_count} bucket_stats.append(c) g = {'length': stats.length, - 'group_id': stats.group_id, + 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'ref_count': stats.ref_count, 'packet_count': stats.packet_count, 'byte_count': stats.byte_count, @@ -947,7 +954,7 @@ def get_group_desc(dp, waiters): 'actions': actions} buckets.append(b) d = {'type': type_convert.get(stats.type), - 'group_id': stats.group_id, + 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'buckets': buckets} descs.append(d) descs = {str(dp.id): descs} @@ -965,7 +972,7 @@ def get_port_desc(dp, waiters): for msg in msgs: stats = msg.body for stat in stats: - d = {'port_no': stat.port_no, + d = {'port_no': UTIL.ofp_port_to_user(stat.port_no), 'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8'), 'config': stat.config, @@ -984,13 +991,16 @@ def get_port_desc(dp, waiters): def mod_flow_entry(dp, flow, cmd): cookie = int(flow.get('cookie', 0)) cookie_mask = int(flow.get('cookie_mask', 0)) - table_id = int(flow.get('table_id', 0)) + table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = int(flow.get('idle_timeout', 0)) hard_timeout = int(flow.get('hard_timeout', 0)) priority = int(flow.get('priority', 0)) - buffer_id = int(flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) - out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) - out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + buffer_id = UTIL.ofp_buffer_from_user( + flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) + out_port = UTIL.ofp_port_from_user( + flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = UTIL.ofp_group_from_user( + flow.get('out_group', dp.ofproto.OFPG_ANY)) flags = int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_actions(dp, flow.get('actions', [])) @@ -1021,7 +1031,7 @@ def mod_meter_entry(dp, meter, cmd): continue flags |= flags_convert.get(flag) - meter_id = int(meter.get('meter_id', 0)) + meter_id = UTIL.ofp_meter_from_user(meter.get('meter_id', 0)) bands = [] for band in meter.get('bands', []): @@ -1061,7 +1071,7 @@ def mod_group_entry(dp, group, cmd): if type_ is None: LOG.error('Unknown group type: %s', group.get('type')) - group_id = int(group.get('group_id', 0)) + group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) buckets = [] for bucket in group.get('buckets', []): @@ -1083,7 +1093,7 @@ def mod_group_entry(dp, group, cmd): def mod_port_behavior(dp, port_config): - port_no = int(port_config.get('port_no', 0)) + port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = int(port_config.get('config', 0)) mask = int(port_config.get('mask', 0)) |