1 # Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 from ryu.ofproto import ether
19 from ryu.ofproto import ofproto_v1_4
20 from ryu.ofproto import ofproto_v1_4_parser
21 from ryu.lib import ofctl_utils
23 LOG = logging.getLogger(__name__)
27 UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_4)
28 str_to_int = ofctl_utils.str_to_int
31 def to_action(dp, dic):
33 parser = dp.ofproto_parser
34 action_type = dic.get('type')
35 return ofctl_utils.to_action(dic, ofp, parser, action_type, UTIL)
38 def _get_actions(dp, dics):
41 action = to_action(dp, d)
42 if action is not None:
43 actions.append(action)
45 LOG.error('Unknown action type: %s', d)
49 def to_instructions(dp, insts):
52 parser = dp.ofproto_parser
55 inst_type = i.get('type')
56 if inst_type in ['APPLY_ACTIONS', 'WRITE_ACTIONS']:
57 dics = i.get('actions', [])
58 actions = _get_actions(dp, dics)
60 if inst_type == 'APPLY_ACTIONS':
62 parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS,
66 parser.OFPInstructionActions(ofp.OFPIT_WRITE_ACTIONS,
68 elif inst_type == 'CLEAR_ACTIONS':
70 parser.OFPInstructionActions(ofp.OFPIT_CLEAR_ACTIONS, []))
71 elif inst_type == 'GOTO_TABLE':
72 table_id = str_to_int(i.get('table_id'))
73 instructions.append(parser.OFPInstructionGotoTable(table_id))
74 elif inst_type == 'WRITE_METADATA':
75 metadata = str_to_int(i.get('metadata'))
76 metadata_mask = (str_to_int(i['metadata_mask'])
77 if 'metadata_mask' in i
78 else parser.UINT64_MAX)
80 parser.OFPInstructionWriteMetadata(
81 metadata, metadata_mask))
82 elif inst_type == 'METER':
83 meter_id = str_to_int(i.get('meter_id'))
84 instructions.append(parser.OFPInstructionMeter(meter_id))
86 LOG.error('Unknown instruction type: %s', inst_type)
91 def action_to_str(act):
92 s = act.to_jsondict()[act.__class__.__name__]
93 t = UTIL.ofp_action_type_to_user(s['type'])
94 s['type'] = t if t != s['type'] else 'UNKNOWN'
97 field = s.pop('field')
98 s['field'] = field['OXMTlv']['field']
99 s['mask'] = field['OXMTlv']['mask']
100 s['value'] = field['OXMTlv']['value']
105 def instructions_to_str(instructions):
109 for i in instructions:
110 v = i.to_jsondict()[i.__class__.__name__]
111 t = UTIL.ofp_instruction_type_to_user(v['type'])
112 inst_type = t if t != v['type'] else 'UNKNOWN'
113 # apply/write/clear-action instruction
114 if isinstance(i, ofproto_v1_4_parser.OFPInstructionActions):
117 acts.append(action_to_str(a))
118 v['type'] = inst_type
123 v['type'] = inst_type
129 def to_match(dp, attrs):
130 convert = {'in_port': UTIL.ofp_port_from_user,
131 'in_phy_port': str_to_int,
132 'metadata': ofctl_utils.to_match_masked_int,
133 'eth_dst': ofctl_utils.to_match_eth,
134 'eth_src': ofctl_utils.to_match_eth,
135 'eth_type': str_to_int,
136 'vlan_vid': to_match_vid,
137 'vlan_pcp': str_to_int,
138 'ip_dscp': str_to_int,
139 'ip_ecn': str_to_int,
140 'ip_proto': str_to_int,
141 'ipv4_src': ofctl_utils.to_match_ip,
142 'ipv4_dst': ofctl_utils.to_match_ip,
143 'tcp_src': str_to_int,
144 'tcp_dst': str_to_int,
145 'udp_src': str_to_int,
146 'udp_dst': str_to_int,
147 'sctp_src': str_to_int,
148 'sctp_dst': str_to_int,
149 'icmpv4_type': str_to_int,
150 'icmpv4_code': str_to_int,
151 'arp_op': str_to_int,
152 'arp_spa': ofctl_utils.to_match_ip,
153 'arp_tpa': ofctl_utils.to_match_ip,
154 'arp_sha': ofctl_utils.to_match_eth,
155 'arp_tha': ofctl_utils.to_match_eth,
156 'ipv6_src': ofctl_utils.to_match_ip,
157 'ipv6_dst': ofctl_utils.to_match_ip,
158 'ipv6_flabel': str_to_int,
159 'icmpv6_type': str_to_int,
160 'icmpv6_code': str_to_int,
161 'ipv6_nd_target': ofctl_utils.to_match_ip,
162 'ipv6_nd_sll': ofctl_utils.to_match_eth,
163 'ipv6_nd_tll': ofctl_utils.to_match_eth,
164 'mpls_label': str_to_int,
165 'mpls_tc': str_to_int,
166 'mpls_bos': str_to_int,
167 'pbb_isid': ofctl_utils.to_match_masked_int,
168 'tunnel_id': ofctl_utils.to_match_masked_int,
169 'ipv6_exthdr': ofctl_utils.to_match_masked_int,
170 'pbb_uca': str_to_int}
172 keys = {'dl_dst': 'eth_dst',
174 'dl_type': 'eth_type',
175 'dl_vlan': 'vlan_vid',
176 'nw_src': 'ipv4_src',
177 'nw_dst': 'ipv4_dst',
178 'nw_proto': 'ip_proto'}
180 if attrs.get('eth_type') == ether.ETH_TYPE_ARP:
181 if 'ipv4_src' in attrs and 'arp_spa' not in attrs:
182 attrs['arp_spa'] = attrs['ipv4_src']
183 del attrs['ipv4_src']
184 if 'ipv4_dst' in attrs and 'arp_tpa' not in attrs:
185 attrs['arp_tpa'] = attrs['ipv4_dst']
186 del attrs['ipv4_dst']
189 for key, value in attrs.items():
194 value = convert[key](value)
197 LOG.error('Unknown match field: %s', key)
199 return dp.ofproto_parser.OFPMatch(**kwargs)
202 def to_match_vid(value):
203 return ofctl_utils.to_match_vid(value, ofproto_v1_4.OFPVID_PRESENT)
206 def match_to_str(ofmatch):
209 ofmatch = ofmatch.to_jsondict()['OFPMatch']
210 ofmatch = ofmatch['oxm_fields']
212 for match_field in ofmatch:
213 key = match_field['OXMTlv']['field']
214 mask = match_field['OXMTlv']['mask']
215 value = match_field['OXMTlv']['value']
216 if key == 'vlan_vid':
217 value = match_vid_to_str(value, mask)
218 elif key == 'in_port':
219 value = UTIL.ofp_port_to_user(value)
222 value = str(value) + '/' + str(mask)
223 match.setdefault(key, value)
228 def match_vid_to_str(value, mask):
229 return ofctl_utils.match_vid_to_str(
230 value, mask, ofproto_v1_4.OFPVID_PRESENT)
233 def wrap_dpid_dict(dp, value, to_user=True):
235 return {str(dp.id): value}
237 return {dp.id: value}
240 def get_desc_stats(dp, waiters, to_user=True):
241 stats = dp.ofproto_parser.OFPDescStatsRequest(dp, 0)
243 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
248 s = stats.to_jsondict()[stats.__class__.__name__]
250 return wrap_dpid_dict(dp, s, to_user)
253 def get_queue_stats(dp, waiters, port_no=None, queue_id=None, to_user=True):
255 port_no = dp.ofproto.OFPP_ANY
257 port_no = UTIL.ofp_port_from_user(port_no)
259 queue_id = dp.ofproto.OFPQ_ALL
261 queue_id = UTIL.ofp_queue_from_user(queue_id)
263 stats = dp.ofproto_parser.OFPQueueStatsRequest(
264 dp, 0, port_no, queue_id)
266 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
272 s = stat.to_jsondict()[stat.__class__.__name__]
274 for prop in stat.properties:
275 p = prop.to_jsondict()[prop.__class__.__name__]
277 t = UTIL.ofp_queue_stats_prop_type_to_user(prop.type)
278 p['type'] = t if t != p['type'] else 'UNKNOWN'
280 s['properties'] = properties
283 return wrap_dpid_dict(dp, desc, to_user)
286 def get_queue_desc(dp, waiters, port_no=None, queue_id=None, to_user=True):
288 port_no = dp.ofproto.OFPP_ANY
290 port_no = UTIL.ofp_port_from_user(port_no)
292 queue_id = dp.ofproto.OFPQ_ALL
294 queue_id = UTIL.ofp_queue_from_user(queue_id)
296 stats = dp.ofproto_parser.OFPQueueDescStatsRequest(
297 dp, 0, port_no, queue_id)
299 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
303 for queue in msg.body:
304 q = queue.to_jsondict()[queue.__class__.__name__]
306 for prop in queue.properties:
307 p = prop.to_jsondict()[prop.__class__.__name__]
309 t = UTIL.ofp_queue_desc_prop_type_to_user(prop.type)
310 p['type'] = t if t != prop.type else 'UNKNOWN'
312 q['properties'] = prop_list
315 return wrap_dpid_dict(dp, configs, to_user)
318 def get_flow_stats(dp, waiters, flow=None, to_user=True):
319 flow = flow if flow else {}
320 table_id = UTIL.ofp_table_from_user(
321 flow.get('table_id', dp.ofproto.OFPTT_ALL))
322 flags = str_to_int(flow.get('flags', 0))
323 out_port = UTIL.ofp_port_from_user(
324 flow.get('out_port', dp.ofproto.OFPP_ANY))
325 out_group = UTIL.ofp_group_from_user(
326 flow.get('out_group', dp.ofproto.OFPG_ANY))
327 cookie = str_to_int(flow.get('cookie', 0))
328 cookie_mask = str_to_int(flow.get('cookie_mask', 0))
329 match = to_match(dp, flow.get('match', {}))
330 # Note: OpenFlow does not allow to filter flow entries by priority,
331 # but for efficiency, ofctl provides the way to do it.
332 priority = str_to_int(flow.get('priority', -1))
334 stats = dp.ofproto_parser.OFPFlowStatsRequest(
335 dp, flags, table_id, out_port, out_group, cookie, cookie_mask,
339 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
343 for stats in msg.body:
344 if 0 <= priority != stats.priority:
347 s = stats.to_jsondict()[stats.__class__.__name__]
348 s['instructions'] = instructions_to_str(stats.instructions)
349 s['match'] = match_to_str(stats.match)
352 return wrap_dpid_dict(dp, flows, to_user)
355 def get_aggregate_flow_stats(dp, waiters, flow=None, to_user=True):
356 flow = flow if flow else {}
357 table_id = UTIL.ofp_table_from_user(
358 flow.get('table_id', dp.ofproto.OFPTT_ALL))
359 flags = str_to_int(flow.get('flags', 0))
360 out_port = UTIL.ofp_port_from_user(
361 flow.get('out_port', dp.ofproto.OFPP_ANY))
362 out_group = UTIL.ofp_group_from_user(
363 flow.get('out_group', dp.ofproto.OFPG_ANY))
364 cookie = str_to_int(flow.get('cookie', 0))
365 cookie_mask = str_to_int(flow.get('cookie_mask', 0))
366 match = to_match(dp, flow.get('match', {}))
368 stats = dp.ofproto_parser.OFPAggregateStatsRequest(
369 dp, flags, table_id, out_port, out_group, cookie, cookie_mask,
373 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
378 s = stats.to_jsondict()[stats.__class__.__name__]
381 return wrap_dpid_dict(dp, flows, to_user)
384 def get_table_stats(dp, waiters, to_user=True):
385 stats = dp.ofproto_parser.OFPTableStatsRequest(dp, 0)
387 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
393 s = stat.to_jsondict()[stat.__class__.__name__]
396 s['table_id'] = UTIL.ofp_table_to_user(stat.table_id)
400 return wrap_dpid_dict(dp, tables, to_user)
403 def get_table_features(dp, waiters, to_user=True):
404 stats = dp.ofproto_parser.OFPTableFeaturesStatsRequest(dp, 0, [])
407 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
409 p_type_instructions = [ofproto.OFPTFPT_INSTRUCTIONS,
410 ofproto.OFPTFPT_INSTRUCTIONS_MISS]
412 p_type_next_tables = [ofproto.OFPTFPT_NEXT_TABLES,
413 ofproto.OFPTFPT_NEXT_TABLES_MISS,
414 ofproto.OFPTFPT_TABLE_SYNC_FROM]
416 p_type_actions = [ofproto.OFPTFPT_WRITE_ACTIONS,
417 ofproto.OFPTFPT_WRITE_ACTIONS_MISS,
418 ofproto.OFPTFPT_APPLY_ACTIONS,
419 ofproto.OFPTFPT_APPLY_ACTIONS_MISS]
421 p_type_oxms = [ofproto.OFPTFPT_MATCH,
422 ofproto.OFPTFPT_WILDCARDS,
423 ofproto.OFPTFPT_WRITE_SETFIELD,
424 ofproto.OFPTFPT_WRITE_SETFIELD_MISS,
425 ofproto.OFPTFPT_APPLY_SETFIELD,
426 ofproto.OFPTFPT_APPLY_SETFIELD_MISS]
428 p_type_experimenter = [ofproto.OFPTFPT_EXPERIMENTER,
429 ofproto.OFPTFPT_EXPERIMENTER_MISS]
435 s = stat.to_jsondict()[stat.__class__.__name__]
437 for prop in stat.properties:
439 t = UTIL.ofp_table_feature_prop_type_to_user(prop.type)
440 p['type'] = t if t != prop.type else 'UNKNOWN'
441 if prop.type in p_type_instructions:
443 for i in prop.instruction_ids:
444 inst = {'len': i.len,
446 instruction_ids.append(inst)
447 p['instruction_ids'] = instruction_ids
448 elif prop.type in p_type_next_tables:
450 for i in prop.table_ids:
452 p['table_ids'] = table_ids
453 elif prop.type in p_type_actions:
455 for i in prop.action_ids:
456 act = i.to_jsondict()[i.__class__.__name__]
457 action_ids.append(act)
458 p['action_ids'] = action_ids
459 elif prop.type in p_type_oxms:
461 for i in prop.oxm_ids:
462 oxm = i.to_jsondict()[i.__class__.__name__]
464 p['oxm_ids'] = oxm_ids
465 elif prop.type in p_type_experimenter:
468 s['name'] = stat.name.decode('utf-8')
469 s['properties'] = properties
472 s['table_id'] = UTIL.ofp_table_to_user(stat.table_id)
476 return wrap_dpid_dict(dp, tables, to_user)
479 def get_port_stats(dp, waiters, port_no=None, to_user=True):
481 port_no = dp.ofproto.OFPP_ANY
483 port_no = UTIL.ofp_port_from_user(port_no)
485 stats = dp.ofproto_parser.OFPPortStatsRequest(dp, 0, port_no)
487 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
491 for stats in msg.body:
492 s = stats.to_jsondict()[stats.__class__.__name__]
494 for prop in stats.properties:
495 p = prop.to_jsondict()[prop.__class__.__name__]
496 t = UTIL.ofp_port_stats_prop_type_to_user(prop.type)
497 p['type'] = t if t != prop.type else 'UNKNOWN'
499 s['properties'] = properties
502 s['port_no'] = UTIL.ofp_port_to_user(stats.port_no)
506 return wrap_dpid_dict(dp, ports, to_user)
509 def get_meter_stats(dp, waiters, meter_id=None, to_user=True):
511 meter_id = dp.ofproto.OFPM_ALL
513 meter_id = UTIL.ofp_meter_from_user(meter_id)
515 stats = dp.ofproto_parser.OFPMeterStatsRequest(
518 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
522 for stats in msg.body:
523 s = stats.to_jsondict()[stats.__class__.__name__]
525 for band in stats.band_stats:
526 b = band.to_jsondict()[band.__class__.__name__]
528 s['band_stats'] = bands
531 s['meter_id'] = UTIL.ofp_meter_to_user(stats.meter_id)
535 return wrap_dpid_dict(dp, meters, to_user)
538 def get_meter_features(dp, waiters, to_user=True):
540 type_convert = {ofp.OFPMBT_DROP: 'DROP',
541 ofp.OFPMBT_DSCP_REMARK: 'DSCP_REMARK'}
543 capa_convert = {ofp.OFPMF_KBPS: 'KBPS',
544 ofp.OFPMF_PKTPS: 'PKTPS',
545 ofp.OFPMF_BURST: 'BURST',
546 ofp.OFPMF_STATS: 'STATS'}
548 stats = dp.ofproto_parser.OFPMeterFeaturesStatsRequest(dp, 0)
550 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
554 for feature in msg.body:
556 for k, v in type_convert.items():
557 if (1 << k) & feature.band_types:
566 for k, v in sorted(capa_convert.items()):
567 if k & feature.capabilities:
570 capabilities.append(v)
573 capabilities.append(k)
575 f = {'max_meter': feature.max_meter,
576 'band_types': band_types,
577 'capabilities': capabilities,
578 'max_bands': feature.max_bands,
579 'max_color': feature.max_color}
582 return wrap_dpid_dict(dp, features, to_user)
585 def get_meter_config(dp, waiters, meter_id=None, to_user=True):
586 flags = {dp.ofproto.OFPMF_KBPS: 'KBPS',
587 dp.ofproto.OFPMF_PKTPS: 'PKTPS',
588 dp.ofproto.OFPMF_BURST: 'BURST',
589 dp.ofproto.OFPMF_STATS: 'STATS'}
592 meter_id = dp.ofproto.OFPM_ALL
594 meter_id = UTIL.ofp_meter_from_user(meter_id)
596 stats = dp.ofproto_parser.OFPMeterConfigStatsRequest(
599 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
603 for config in msg.body:
604 c = config.to_jsondict()[config.__class__.__name__]
606 for band in config.bands:
607 b = band.to_jsondict()[band.__class__.__name__]
610 t = UTIL.ofp_meter_band_type_to_user(band.type)
611 b['type'] = t if t != band.type else 'UNKNOWN'
615 for k, v in sorted(flags.items()):
627 c['meter_id'] = UTIL.ofp_meter_to_user(config.meter_id)
631 return wrap_dpid_dict(dp, configs, to_user)
634 def get_group_stats(dp, waiters, group_id=None, to_user=True):
636 group_id = dp.ofproto.OFPG_ALL
638 group_id = UTIL.ofp_group_from_user(group_id)
640 stats = dp.ofproto_parser.OFPGroupStatsRequest(
643 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
647 for stats in msg.body:
648 g = stats.to_jsondict()[stats.__class__.__name__]
650 for bucket_stat in stats.bucket_stats:
651 c = bucket_stat.to_jsondict()[bucket_stat.__class__.__name__]
652 bucket_stats.append(c)
653 g['bucket_stats'] = bucket_stats
656 g['group_id'] = UTIL.ofp_group_to_user(stats.group_id)
660 return wrap_dpid_dict(dp, groups, to_user)
663 def get_group_features(dp, waiters, to_user=True):
666 type_convert = {ofp.OFPGT_ALL: 'ALL',
667 ofp.OFPGT_SELECT: 'SELECT',
668 ofp.OFPGT_INDIRECT: 'INDIRECT',
670 cap_convert = {ofp.OFPGFC_SELECT_WEIGHT: 'SELECT_WEIGHT',
671 ofp.OFPGFC_SELECT_LIVENESS: 'SELECT_LIVENESS',
672 ofp.OFPGFC_CHAINING: 'CHAINING',
673 ofp.OFPGFC_CHAINING_CHECKS: 'CHAINING_CHECKS'}
674 act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT',
675 ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT',
676 ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN',
677 ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL',
678 ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL',
679 ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN',
680 ofp.OFPAT_POP_VLAN: 'POP_VLAN',
681 ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS',
682 ofp.OFPAT_POP_MPLS: 'POP_MPLS',
683 ofp.OFPAT_SET_QUEUE: 'SET_QUEUE',
684 ofp.OFPAT_GROUP: 'GROUP',
685 ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL',
686 ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL',
687 ofp.OFPAT_SET_FIELD: 'SET_FIELD',
688 ofp.OFPAT_PUSH_PBB: 'PUSH_PBB',
689 ofp.OFPAT_POP_PBB: 'POP_PBB',
690 ofp.OFPAT_EXPERIMENTER: 'EXPERIMENTER'}
692 stats = dp.ofproto_parser.OFPGroupFeaturesStatsRequest(dp, 0)
694 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
700 for k, v in type_convert.items():
701 if (1 << k) & feature.types:
709 for k, v in cap_convert.items():
710 if k & feature.capabilities:
712 capabilities.append(v)
715 capabilities.append(k)
719 for k, v in type_convert.items():
720 max_groups.append({v: feature.max_groups[k]})
723 max_groups = feature.max_groups
726 for k1, v1 in type_convert.items():
728 for k2, v2 in act_convert.items():
729 if (1 << k2) & feature.actions[k1]:
737 actions.append({v1: acts})
740 actions.append({k1: acts})
743 'capabilities': capabilities,
744 'max_groups': max_groups,
748 return wrap_dpid_dict(dp, features, to_user)
751 def get_group_desc(dp, waiters, to_user=True):
752 stats = dp.ofproto_parser.OFPGroupDescStatsRequest(dp, 0)
754 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
758 for stats in msg.body:
759 d = stats.to_jsondict()[stats.__class__.__name__]
761 for bucket in stats.buckets:
762 b = bucket.to_jsondict()[bucket.__class__.__name__]
764 for action in bucket.actions:
766 actions.append(action_to_str(action))
769 actions.append(action)
770 b['actions'] = actions
773 d['buckets'] = buckets
775 d['group_id'] = UTIL.ofp_group_to_user(stats.group_id)
776 t = UTIL.ofp_group_type_to_user(stats.type)
777 d['type'] = t if t != stats.type else 'UNKNOWN'
781 return wrap_dpid_dict(dp, descs, to_user)
784 def get_port_desc(dp, waiters, port_no=None, to_user=True):
786 port_no = dp.ofproto.OFPP_ANY
788 port_no = UTIL.ofp_port_from_user(port_no)
790 stats = dp.ofproto_parser.OFPPortDescStatsRequest(dp, 0, port_no)
792 ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG)
799 d = stat.to_jsondict()[stat.__class__.__name__]
801 for prop in stat.properties:
802 p = prop.to_jsondict()[prop.__class__.__name__]
805 t = UTIL.ofp_port_desc_prop_type_to_user(prop.type)
806 p['type'] = t if t != prop.type else 'UNKNOWN'
809 d['name'] = stat.name.decode('utf-8')
810 d['properties'] = properties
813 d['port_no'] = UTIL.ofp_port_to_user(stat.port_no)
817 return wrap_dpid_dict(dp, descs, to_user)
820 def get_role(dp, waiters, to_user=True):
821 return ofctl_utils.get_role(dp, waiters, to_user)
824 def mod_flow_entry(dp, flow, cmd):
825 cookie = str_to_int(flow.get('cookie', 0))
826 cookie_mask = str_to_int(flow.get('cookie_mask', 0))
827 table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0))
828 idle_timeout = str_to_int(flow.get('idle_timeout', 0))
829 hard_timeout = str_to_int(flow.get('hard_timeout', 0))
830 priority = str_to_int(flow.get('priority', 0))
831 buffer_id = UTIL.ofp_buffer_from_user(
832 flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER))
833 out_port = UTIL.ofp_port_from_user(
834 flow.get('out_port', dp.ofproto.OFPP_ANY))
835 out_group = UTIL.ofp_group_from_user(
836 flow.get('out_group', dp.ofproto.OFPG_ANY))
837 importance = str_to_int(flow.get('importance', 0))
838 flags = str_to_int(flow.get('flags', 0))
839 match = to_match(dp, flow.get('match', {}))
840 inst = to_instructions(dp, flow.get('instructions', []))
842 flow_mod = dp.ofproto_parser.OFPFlowMod(
843 dp, cookie, cookie_mask, table_id, cmd, idle_timeout,
844 hard_timeout, priority, buffer_id, out_port, out_group,
845 flags, importance, match, inst)
847 ofctl_utils.send_msg(dp, flow_mod, LOG)
850 def mod_meter_entry(dp, meter, cmd):
853 meter_flags = meter['flags']
854 if not isinstance(meter_flags, list):
855 meter_flags = [meter_flags]
856 for flag in meter_flags:
857 t = UTIL.ofp_meter_flags_from_user(flag)
858 f = t if t != flag else None
860 LOG.error('Unknown meter flag: %s', flag)
864 meter_id = UTIL.ofp_meter_from_user(meter.get('meter_id', 0))
867 for band in meter.get('bands', []):
868 band_type = band.get('type')
869 rate = str_to_int(band.get('rate', 0))
870 burst_size = str_to_int(band.get('burst_size', 0))
871 if band_type == 'DROP':
873 dp.ofproto_parser.OFPMeterBandDrop(rate, burst_size))
874 elif band_type == 'DSCP_REMARK':
875 prec_level = str_to_int(band.get('prec_level', 0))
877 dp.ofproto_parser.OFPMeterBandDscpRemark(
878 rate, burst_size, prec_level))
879 elif band_type == 'EXPERIMENTER':
880 experimenter = str_to_int(band.get('experimenter', 0))
882 dp.ofproto_parser.OFPMeterBandExperimenter(
883 rate, burst_size, experimenter))
885 LOG.error('Unknown band type: %s', band_type)
887 meter_mod = dp.ofproto_parser.OFPMeterMod(
888 dp, cmd, flags, meter_id, bands)
890 ofctl_utils.send_msg(dp, meter_mod, LOG)
893 def mod_group_entry(dp, group, cmd):
894 group_type = str(group.get('type', 'ALL'))
895 t = UTIL.ofp_group_type_from_user(group_type)
896 group_type = t if t != group_type else None
897 if group_type is None:
898 LOG.error('Unknown group type: %s', group.get('type'))
900 group_id = UTIL.ofp_group_from_user(group.get('group_id', 0))
903 for bucket in group.get('buckets', []):
904 weight = str_to_int(bucket.get('weight', 0))
905 watch_port = str_to_int(
906 bucket.get('watch_port', dp.ofproto.OFPP_ANY))
907 watch_group = str_to_int(
908 bucket.get('watch_group', dp.ofproto.OFPG_ANY))
910 for dic in bucket.get('actions', []):
911 action = to_action(dp, dic)
912 if action is not None:
913 actions.append(action)
914 buckets.append(dp.ofproto_parser.OFPBucket(
915 weight, watch_port, watch_group, actions))
917 group_mod = dp.ofproto_parser.OFPGroupMod(
918 dp, cmd, group_type, group_id, buckets)
920 ofctl_utils.send_msg(dp, group_mod, LOG)
923 def mod_port_behavior(dp, port_config):
925 parser = dp.ofproto_parser
926 port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0))
927 hw_addr = str(port_config.get('hw_addr'))
928 config = str_to_int(port_config.get('config', 0))
929 mask = str_to_int(port_config.get('mask', 0))
930 properties = port_config.get('properties')
934 type_ = UTIL.ofp_port_mod_prop_type_from_user(p['type'])
936 if type_ == ofp.OFPPDPT_ETHERNET:
937 advertise = UTIL.ofp_port_features_from_user(p['advertise'])
939 parser.OFPPortModPropEthernet(type_, length, advertise))
940 elif type_ == ofp.OFPPDPT_OPTICAL:
942 parser.OFPPortModPropOptical(
943 type_, length, p['configure'], p['freq_lmda'],
944 p['fl_offset'], p['grid_span'], p['tx_pwr']))
945 elif type_ == ofp.OFPPDPT_EXPERIMENTER:
947 parser.OFPPortModPropExperimenter(
948 type_, length, p['experimenter'], p['exp_type'],
951 LOG.error('Unknown port desc prop type: %s', type_)
953 port_mod = dp.ofproto_parser.OFPPortMod(
954 dp, port_no, hw_addr, config, mask, prop)
956 ofctl_utils.send_msg(dp, port_mod, LOG)
959 def set_role(dp, role):
960 r = UTIL.ofp_role_from_user(role.get('role', dp.ofproto.OFPCR_ROLE_EQUAL))
961 role_request = dp.ofproto_parser.OFPRoleRequest(dp, r, 0)
962 ofctl_utils.send_msg(dp, role_request, LOG)
965 # NOTE(jkoelker) Alias common funcitons
966 send_experimenter = ofctl_utils.send_experimenter