diff --git a/ryu/app/ofctl_rest.py b/ryu/app/ofctl_rest.py index e459b790..e41d7d6a 100644 --- a/ryu/app/ofctl_rest.py +++ b/ryu/app/ofctl_rest.py @@ -77,6 +77,9 @@ supported_ofctl = { # get queues stats of the switch # GET /stats/queue/ # +# get queues config stats of the switch +# GET /stats/queueconfig// +# # get meter features stats of the switch # GET /stats/meterfeatures/ # @@ -345,6 +348,35 @@ class StatsController(ControllerBase): body = json.dumps(queues) return Response(content_type='application/json', body=body) + def get_queue_config(self, req, dpid, port, **_kwargs): + + if type(dpid) == str and not dpid.isdigit(): + LOG.debug('invalid dpid %s', dpid) + return Response(status=400) + + if type(port) == str and not port.isdigit(): + LOG.debug('invalid port %s', port) + return Response(status=400) + + dp = self.dpset.get(int(dpid)) + port = int(port) + + if dp is None: + return Response(status=404) + + _ofp_version = dp.ofproto.OFP_VERSION + + _ofctl = supported_ofctl.get(_ofp_version, None) + if _ofctl is not None: + queues = _ofctl.get_queue_config(dp, port, self.waiters) + + else: + LOG.debug('Unsupported OF protocol') + return Response(status=501) + + body = json.dumps(queues) + return Response(content_type='application/json', body=body) + def get_meter_features(self, req, dpid, **_kwargs): if type(dpid) == str and not dpid.isdigit(): @@ -815,6 +847,11 @@ class RestStatsApi(app_manager.RyuApp): controller=StatsController, action='get_queue_stats', conditions=dict(method=['GET'])) + uri = path + '/queueconfig/{dpid}/{port}' + mapper.connect('stats', uri, + controller=StatsController, action='get_queue_config', + conditions=dict(method=['GET'])) + uri = path + '/meterfeatures/{dpid}' mapper.connect('stats', uri, controller=StatsController, action='get_meter_features', @@ -920,7 +957,8 @@ class RestStatsApi(app_manager.RyuApp): del self.waiters[dp.id][msg.xid] lock.set() - @set_ev_cls([ofp_event.EventOFPSwitchFeatures], MAIN_DISPATCHER) + @set_ev_cls([ofp_event.EventOFPSwitchFeatures, + ofp_event.EventOFPQueueGetConfigReply], MAIN_DISPATCHER) def features_reply_handler(self, ev): msg = ev.msg dp = msg.datapath diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py index 2f2c91f3..dcac557a 100644 --- a/ryu/lib/ofctl_v1_2.py +++ b/ryu/lib/ofctl_v1_2.py @@ -453,6 +453,43 @@ def get_queue_stats(dp, waiters): return desc +def get_queue_config(dp, port, waiters): + ofp = dp.ofproto + stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) + msgs = [] + send_stats_request(dp, stats, waiters, msgs) + + prop_type = {dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE', + dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE', + dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER', + } + + configs = [] + for config in msgs: + queue_list = [] + for queue in config.queues: + prop_list = [] + for prop in queue.properties: + p = {'property': prop_type.get(prop.property, 'UNKNOWN')} + if prop.property == dp.ofproto.OFPQT_MIN_RATE or \ + prop.property == dp.ofproto.OFPQT_MAX_RATE: + p['rate'] = prop.rate + elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER: + p['experimenter'] = prop.experimenter + p['data'] = prop.data + prop_list.append(p) + q = {'port': queue.port, + 'properties': prop_list, + 'queue_id': queue.queue_id} + queue_list.append(q) + c = {'port': config.port, + 'queues': queue_list} + configs.append(c) + configs = {str(dp.id): configs} + + return configs + + def get_flow_stats(dp, waiters, flow={}): table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py index a3eae1f5..81f9f704 100644 --- a/ryu/lib/ofctl_v1_3.py +++ b/ryu/lib/ofctl_v1_3.py @@ -478,6 +478,43 @@ def get_queue_stats(dp, waiters): return desc +def get_queue_config(dp, port, waiters): + ofp = dp.ofproto + stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) + msgs = [] + send_stats_request(dp, stats, waiters, msgs) + + prop_type = {dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE', + dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE', + dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER', + } + + configs = [] + for config in msgs: + queue_list = [] + for queue in config.queues: + prop_list = [] + for prop in queue.properties: + p = {'property': prop_type.get(prop.property, 'UNKNOWN')} + if prop.property == dp.ofproto.OFPQT_MIN_RATE or \ + prop.property == dp.ofproto.OFPQT_MAX_RATE: + p['rate'] = prop.rate + elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER: + p['experimenter'] = prop.experimenter + p['data'] = prop.data + prop_list.append(p) + q = {'port': queue.port, + 'properties': prop_list, + 'queue_id': queue.queue_id} + queue_list.append(q) + c = {'port': config.port, + 'queues': queue_list} + configs.append(c) + configs = {str(dp.id): configs} + + return configs + + def get_flow_stats(dp, waiters, flow={}): table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = int(flow.get('flags', 0))