ofctl_rest: support OFPQueueStats message

this patch makes ofctl_rest enable use of OFPQueueStats message.

usage)

  URI:    /stats/queue/<dpid>
  method: GET

e.g.)

  $ curl -X GET http://localhost:8080/stats/queue/1
  {
    "1": [
      {
        "port_no": 1,
        "queue_id": 0,
        "tx_bytes": 0,
        "tx_packets": 0,
        "tx_errors": 0,
        "duration_sec": 4294963425,
        "duration_nsec": 3912967296
      },
      {
        "port_no": 1,
        "queue_id": 1,
        "tx_bytes": 0,
        "tx_packets": 0,
        "tx_errors": 0,
        "duration_sec": 4294963425,
        "duration_nsec": 3912967296
      }
    ]
  }

NOTE: The "duration_sec" and "duration_nsec" fields are for OF1.3(or later).

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-01-19 10:45:10 +09:00 committed by FUJITA Tomonori
parent be94c50ce6
commit fe0d068f86
3 changed files with 48 additions and 2 deletions

View File

@ -55,6 +55,9 @@ LOG = logging.getLogger('ryu.app.ofctl_rest')
# get ports stats of the switch
# GET /stats/port/<dpid>
#
# get queues stats of the switch
# GET /stats/queue/<dpid>
#
# get meter features stats of the switch
# GET /stats/meterfeatures/<dpid>
#
@ -196,6 +199,24 @@ class StatsController(ControllerBase):
body = json.dumps(ports)
return (Response(content_type='application/json', body=body))
def get_queue_stats(self, req, dpid, **_kwargs):
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
queues = ofctl_v1_0.get_queue_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
queues = ofctl_v1_2.get_queue_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
queues = ofctl_v1_3.get_queue_stats(dp, 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):
dp = self.dpset.get(int(dpid))
if dp is None:
@ -556,6 +577,11 @@ class RestStatsApi(app_manager.RyuApp):
controller=StatsController, action='get_port_stats',
conditions=dict(method=['GET']))
uri = path + '/queue/{dpid}'
mapper.connect('stats', uri,
controller=StatsController, action='get_queue_stats',
conditions=dict(method=['GET']))
uri = path + '/meterfeatures/{dpid}'
mapper.connect('stats', uri,
controller=StatsController, action='get_meter_features',
@ -625,6 +651,7 @@ class RestStatsApi(app_manager.RyuApp):
ofp_event.EventOFPDescStatsReply,
ofp_event.EventOFPFlowStatsReply,
ofp_event.EventOFPPortStatsReply,
ofp_event.EventOFPQueueStatsReply,
ofp_event.EventOFPMeterStatsReply,
ofp_event.EventOFPMeterFeaturesStatsReply,
ofp_event.EventOFPMeterConfigStatsReply,

View File

@ -270,6 +270,25 @@ def get_desc_stats(dp, waiters):
return desc
def get_queue_stats(dp, waiters):
stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, 0, dp.ofproto.OFPP_ALL,
dp.ofproto.OFPQ_ALL)
msgs = []
send_stats_request(dp, stats, waiters, msgs)
s = []
for msg in msgs:
stats = msg.body
for stat in stats:
s.append({'port_no': stat.port_no,
'queue_id': stat.queue_id,
'tx_bytes': stat.tx_bytes,
'tx_errors': stat.tx_errors,
'tx_packets': stat.tx_packets})
desc = {str(dp.id): s}
return desc
def get_flow_stats(dp, waiters, flow={}):
match = to_match(dp, flow.get('match', {}))
table_id = int(flow.get('table_id', 0xff))

View File

@ -410,8 +410,8 @@ def get_desc_stats(dp, waiters):
def get_queue_stats(dp, waiters):
ofp = dp.ofproto
stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, 0, ofp.OFPP_ANY,
ofp.OFPQ_ALL)
stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, ofp.OFPP_ANY,
ofp.OFPQ_ALL, 0)
msgs = []
send_stats_request(dp, stats, waiters, msgs)