Advertisement
Guest User

Untitled

a guest
Oct 6th, 2015
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 28.74 KB | None | 0 0
  1. # Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
  2. #
  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
  6. #
  7. #    http://www.apache.org/licenses/LICENSE-2.0
  8. #
  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
  12. # implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15.  
  16. import logging
  17.  
  18. import json
  19. import ast
  20. from webob import Response
  21.  
  22. from ryu.base import app_manager
  23. from ryu.controller import ofp_event
  24. from ryu.controller import dpset
  25. from ryu.controller.handler import MAIN_DISPATCHER
  26. from ryu.controller.handler import set_ev_cls
  27. from ryu.ofproto import ofproto_v1_0
  28. from ryu.ofproto import ofproto_v1_2
  29. from ryu.ofproto import ofproto_v1_3
  30. from ryu.lib import ofctl_v1_0
  31. from ryu.lib import ofctl_v1_2
  32. from ryu.lib import ofctl_v1_3
  33. from ryu.app.wsgi import ControllerBase, WSGIApplication
  34.  
  35.  
  36. LOG = logging.getLogger('ryu.app.ofctl_rest')
  37.  
  38. # supported ofctl versions in this restful app
  39. supported_ofctl = {
  40.     ofproto_v1_0.OFP_VERSION: ofctl_v1_0,
  41.     ofproto_v1_2.OFP_VERSION: ofctl_v1_2,
  42.     ofproto_v1_3.OFP_VERSION: ofctl_v1_3,
  43. }
  44.  
  45. # REST API
  46. #
  47.  
  48. # Retrieve the switch stats
  49. #
  50. # get the list of all switches
  51. # GET /stats/switches
  52. #
  53. # get the desc stats of the switch
  54. # GET /stats/desc/<dpid>
  55. #
  56. # get flows stats of the switch
  57. # GET /stats/flow/<dpid>
  58. #
  59. # get flows stats of the switch filtered by the fields
  60. # POST /stats/flow/<dpid>
  61. #
  62. # get aggregate flows stats of the switch
  63. # GET /stats/aggregateflow/<dpid>
  64. #
  65. # get aggregate flows stats of the switch filtered by the fields
  66. # POST /stats/aggregateflow/<dpid>
  67. #
  68. # get ports stats of the switch
  69. # GET /stats/port/<dpid>
  70. #
  71. # get queues stats of the switch
  72. # GET /stats/queue/<dpid>
  73. #
  74. # get meter features stats of the switch
  75. # GET /stats/meterfeatures/<dpid>
  76. #
  77. # get meter config stats of the switch
  78. # GET /stats/meterconfig/<dpid>
  79. #
  80. # get meters stats of the switch
  81. # GET /stats/meter/<dpid>
  82. #
  83. # get group features stats of the switch
  84. # GET /stats/groupfeatures/<dpid>
  85. #
  86. # get groups desc stats of the switch
  87. # GET /stats/groupdesc/<dpid>
  88. #
  89. # get groups stats of the switch
  90. # GET /stats/group/<dpid>
  91. #
  92. # get ports description of the switch
  93. # GET /stats/portdesc/<dpid>
  94.  
  95. # Update the switch stats
  96. #
  97. # add a flow entry
  98. # POST /stats/flowentry/add
  99. #
  100. # modify all matching flow entries
  101. # POST /stats/flowentry/modify
  102. #
  103. # modify flow entry strictly matching wildcards and priority
  104. # POST /stats/flowentry/modify_strict
  105. #
  106. # delete all matching flow entries
  107. # POST /stats/flowentry/delete
  108. #
  109. # delete flow entry strictly matching wildcards and priority
  110. # POST /stats/flowentry/delete_strict
  111. #
  112. # delete all flow entries of the switch
  113. # DELETE /stats/flowentry/clear/<dpid>
  114. #
  115. # add a meter entry
  116. # POST /stats/meterentry/add
  117. #
  118. # modify a meter entry
  119. # POST /stats/meterentry/modify
  120. #
  121. # delete a meter entry
  122. # POST /stats/meterentry/delete
  123. #
  124. # add a group entry
  125. # POST /stats/groupentry/add
  126. #
  127. # modify a group entry
  128. # POST /stats/groupentry/modify
  129. #
  130. # delete a group entry
  131. # POST /stats/groupentry/delete
  132. #
  133. # modify behavior of the physical port
  134. # POST /stats/portdesc/modify
  135. #
  136. #
  137. # send a experimeter message
  138. # POST /stats/experimenter/<dpid>
  139.  
  140.  
  141. class StatsController(ControllerBase):
  142.     def __init__(self, req, link, data, **config):
  143.         super(StatsController, self).__init__(req, link, data, **config)
  144.         self.dpset = data['dpset']
  145.         self.waiters = data['waiters']
  146.  
  147.     def get_dpids(self, req, **_kwargs):
  148.         dps = list(self.dpset.dps.keys())
  149.         body = json.dumps(dps, ensure_ascii=True, indent=3, sort_keys=True)
  150.         return Response(content_type='application/json', body=body)
  151.  
  152.     def get_desc_stats(self, req, dpid, **_kwargs):
  153.  
  154.         if type(dpid) == str and not dpid.isdigit():
  155.             LOG.debug('invalid dpid %s', dpid)
  156.             return Response(status=400)
  157.  
  158.         dp = self.dpset.get(int(dpid))
  159.  
  160.         if dp is None:
  161.             return Response(status=404)
  162.         _ofp_version = dp.ofproto.OFP_VERSION
  163.  
  164.         _ofctl = supported_ofctl.get(_ofp_version, None)
  165.         if _ofctl is not None:
  166.             desc = _ofctl.get_desc_stats(dp, self.waiters)
  167.  
  168.         else:
  169.             LOG.debug('Unsupported OF protocol')
  170.             return Response(status=501)
  171.  
  172.         body = json.dumps(desc, ensure_ascii=True, indent=3, sort_keys=True)
  173.         return Response(content_type='application/json', body=body)
  174.  
  175.     def get_flow_stats(self, req, dpid, **_kwargs):
  176.  
  177.         if req.body == '':
  178.             flow = {}
  179.  
  180.         else:
  181.  
  182.             try:
  183.                 flow = ast.literal_eval(req.body)
  184.  
  185.             except SyntaxError:
  186.                 LOG.debug('invalid syntax %s', req.body)
  187.                 return Response(status=400)
  188.  
  189.         if type(dpid) == str and not dpid.isdigit():
  190.             LOG.debug('invalid dpid %s', dpid)
  191.             return Response(status=400)
  192.  
  193.         dp = self.dpset.get(int(dpid))
  194.  
  195.         if dp is None:
  196.             return Response(status=404)
  197.  
  198.         _ofp_version = dp.ofproto.OFP_VERSION
  199.  
  200.         _ofctl = supported_ofctl.get(_ofp_version, None)
  201.         if _ofctl is not None:
  202.             flows = _ofctl.get_flow_stats(dp, self.waiters, flow)
  203.  
  204.         else:
  205.             LOG.debug('Unsupported OF protocol')
  206.             return Response(status=501)
  207.  
  208.         body = json.dumps(flows, ensure_ascii=True, indent=3, sort_keys=True)
  209.         return Response(content_type='application/json', body=body)
  210.  
  211.     def get_aggregate_flow_stats(self, req, dpid, **_kwargs):
  212.  
  213.         if req.body == '':
  214.             flow = {}
  215.  
  216.         else:
  217.             try:
  218.                 flow = ast.literal_eval(req.body)
  219.  
  220.             except SyntaxError:
  221.                 LOG.debug('invalid syntax %s', req.body)
  222.                 return Response(status=400)
  223.  
  224.         if type(dpid) == str and not dpid.isdigit():
  225.             LOG.debug('invalid dpid %s', dpid)
  226.             return Response(status=400)
  227.  
  228.         dp = self.dpset.get(int(dpid))
  229.  
  230.         if dp is None:
  231.             return Response(status=404)
  232.  
  233.         _ofp_version = dp.ofproto.OFP_VERSION
  234.  
  235.         _ofctl = supported_ofctl.get(_ofp_version, None)
  236.         if _ofctl is not None:
  237.             flows = _ofctl.get_aggregate_flow_stats(dp, self.waiters, flow)
  238.  
  239.         else:
  240.             LOG.debug('Unsupported OF protocol')
  241.             return Response(status=501)
  242.  
  243.         body = json.dumps(flows, ensure_ascii=True, indent=3, sort_keys=True)
  244.         return Response(content_type='application/json', body=body)
  245.  
  246.     def get_port_stats(self, req, dpid, **_kwargs):
  247.  
  248.         if type(dpid) == str and not dpid.isdigit():
  249.             LOG.debug('invalid dpid %s', dpid)
  250.             return Response(status=400)
  251.  
  252.         dp = self.dpset.get(int(dpid))
  253.  
  254.         if dp is None:
  255.             return Response(status=404)
  256.  
  257.         _ofp_version = dp.ofproto.OFP_VERSION
  258.  
  259.         _ofctl = supported_ofctl.get(_ofp_version, None)
  260.         if _ofctl is not None:
  261.             ports = _ofctl.get_port_stats(dp, self.waiters)
  262.  
  263.         else:
  264.             LOG.debug('Unsupported OF protocol')
  265.             return Response(status=501)
  266.  
  267.         body = json.dumps(ports, ensure_ascii=True, indent=3, sort_keys=True)
  268.         return Response(content_type='application/json', body=body)
  269.  
  270.     def get_queue_stats(self, req, dpid, **_kwargs):
  271.  
  272.         if type(dpid) == str and not dpid.isdigit():
  273.             LOG.debug('invalid dpid %s', dpid)
  274.             return Response(status=400)
  275.  
  276.         dp = self.dpset.get(int(dpid))
  277.  
  278.         if dp is None:
  279.             return Response(status=404)
  280.  
  281.         _ofp_version = dp.ofproto.OFP_VERSION
  282.  
  283.         _ofctl = supported_ofctl.get(_ofp_version, None)
  284.         if _ofctl is not None:
  285.             queues = _ofctl.get_queue_stats(dp, self.waiters)
  286.  
  287.         else:
  288.             LOG.debug('Unsupported OF protocol')
  289.             return Response(status=501)
  290.  
  291.         body = json.dumps(queues, ensure_ascii=True, indent=3, sort_keys=True)
  292.         return Response(content_type='application/json', body=body)
  293.  
  294.     def get_meter_features(self, req, dpid, **_kwargs):
  295.  
  296.         if type(dpid) == str and not dpid.isdigit():
  297.             LOG.debug('invalid dpid %s', dpid)
  298.             return Response(status=400)
  299.  
  300.         dp = self.dpset.get(int(dpid))
  301.  
  302.         if dp is None:
  303.             return Response(status=404)
  304.  
  305.         _ofp_version = dp.ofproto.OFP_VERSION
  306.         _ofctl = supported_ofctl.get(_ofp_version, None)
  307.  
  308.         if _ofctl is not None and hasattr(_ofctl, 'get_meter_features'):
  309.             meters = _ofctl.get_meter_features(dp, self.waiters)
  310.  
  311.         else:
  312.             LOG.debug('Unsupported OF protocol or \
  313.                request not supported in this OF protocol version')
  314.             return Response(status=501)
  315.  
  316.         body = json.dumps(meters, ensure_ascii=True, indent=3, sort_keys=True)
  317.         return Response(content_type='application/json', body=body)
  318.  
  319.     def get_meter_config(self, req, dpid, **_kwargs):
  320.  
  321.         if type(dpid) == str and not dpid.isdigit():
  322.             LOG.debug('invalid dpid %s', dpid)
  323.             return Response(status=400)
  324.  
  325.         dp = self.dpset.get(int(dpid))
  326.  
  327.         if dp is None:
  328.             return Response(status=404)
  329.  
  330.         _ofp_version = dp.ofproto.OFP_VERSION
  331.         _ofctl = supported_ofctl.get(_ofp_version, None)
  332.  
  333.         if _ofctl is not None and hasattr(_ofctl, 'get_meter_config'):
  334.             meters = _ofctl.get_meter_config(dp, self.waiters)
  335.  
  336.         else:
  337.             LOG.debug('Unsupported OF protocol or \
  338.                request not supported in this OF protocol version')
  339.             return Response(status=501)
  340.  
  341.         body = json.dumps(meters, ensure_ascii=True, indent=3, sort_keys=True)
  342.         return Response(content_type='application/json', body=body)
  343.  
  344.     def get_meter_stats(self, req, dpid, **_kwargs):
  345.  
  346.         if type(dpid) == str and not dpid.isdigit():
  347.             LOG.debug('invalid dpid %s', dpid)
  348.             return Response(status=400)
  349.  
  350.         dp = self.dpset.get(int(dpid))
  351.  
  352.         if dp is None:
  353.             return Response(status=404)
  354.  
  355.         _ofp_version = dp.ofproto.OFP_VERSION
  356.         _ofctl = supported_ofctl.get(_ofp_version, None)
  357.  
  358.         if _ofctl is not None and hasattr(_ofctl, 'get_meter_stats'):
  359.             meters = _ofctl.get_meter_stats(dp, self.waiters)
  360.  
  361.         else:
  362.             LOG.debug('Unsupported OF protocol or \
  363.                request not supported in this OF protocol version')
  364.             return Response(status=501)
  365.  
  366.         body = json.dumps(meters, ensure_ascii=True, indent=3, sort_keys=True)
  367.         return Response(content_type='application/json', body=body)
  368.  
  369.     def get_group_features(self, req, dpid, **_kwargs):
  370.  
  371.         if type(dpid) == str and not dpid.isdigit():
  372.             LOG.debug('invalid dpid %s', dpid)
  373.             return Response(status=400)
  374.  
  375.         dp = self.dpset.get(int(dpid))
  376.  
  377.         if dp is None:
  378.             return Response(status=404)
  379.  
  380.         _ofp_version = dp.ofproto.OFP_VERSION
  381.         _ofctl = supported_ofctl.get(_ofp_version, None)
  382.  
  383.         if _ofctl is not None and hasattr(_ofctl, 'get_group_features'):
  384.             groups = _ofctl.get_group_features(dp, self.waiters)
  385.  
  386.         else:
  387.             LOG.debug('Unsupported OF protocol or \
  388.                request not supported in this OF protocol version')
  389.             return Response(status=501)
  390.  
  391.         body = json.dumps(groups, ensure_ascii=True, indent=3, sort_keys=True)
  392.         return Response(content_type='application/json', body=body)
  393.  
  394.     def get_group_desc(self, req, dpid, **_kwargs):
  395.  
  396.         if type(dpid) == str and not dpid.isdigit():
  397.             LOG.debug('invalid dpid %s', dpid)
  398.             return Response(status=400)
  399.  
  400.         dp = self.dpset.get(int(dpid))
  401.  
  402.         if dp is None:
  403.             return Response(status=404)
  404.  
  405.         _ofp_version = dp.ofproto.OFP_VERSION
  406.         _ofctl = supported_ofctl.get(_ofp_version, None)
  407.  
  408.         if _ofctl is not None and hasattr(_ofctl, 'get_group_desc'):
  409.             groups = _ofctl.get_group_desc(dp, self.waiters)
  410.  
  411.         else:
  412.             LOG.debug('Unsupported OF protocol or \
  413.                request not supported in this OF protocol version')
  414.             return Response(status=501)
  415.  
  416.         body = json.dumps(groups, ensure_ascii=True, indent=3, sort_keys=True)
  417.         return Response(content_type='application/json', body=body)
  418.  
  419.     def get_group_stats(self, req, dpid, **_kwargs):
  420.  
  421.         if type(dpid) == str and not dpid.isdigit():
  422.             LOG.debug('invalid dpid %s', dpid)
  423.             return Response(status=400)
  424.  
  425.         dp = self.dpset.get(int(dpid))
  426.  
  427.         if dp is None:
  428.             return Response(status=404)
  429.  
  430.         _ofp_version = dp.ofproto.OFP_VERSION
  431.         _ofctl = supported_ofctl.get(_ofp_version, None)
  432.  
  433.         if _ofctl is not None and hasattr(_ofctl, 'get_group_stats'):
  434.             groups = _ofctl.get_group_stats(dp, self.waiters)
  435.  
  436.         else:
  437.             LOG.debug('Unsupported OF protocol or \
  438.                request not supported in this OF protocol version')
  439.             return Response(status=501)
  440.  
  441.         body = json.dumps(groups, ensure_ascii=True, indent=3, sort_keys=True)
  442.         return Response(content_type='application/json', body=body)
  443.  
  444.     def get_port_desc(self, req, dpid, **_kwargs):
  445.  
  446.         if type(dpid) == str and not dpid.isdigit():
  447.             LOG.debug('invalid dpid %s', dpid)
  448.             return Response(status=400)
  449.  
  450.         dp = self.dpset.get(int(dpid))
  451.  
  452.         if dp is None:
  453.             return Response(status=404)
  454.  
  455.         _ofp_version = dp.ofproto.OFP_VERSION
  456.  
  457.         _ofctl = supported_ofctl.get(_ofp_version, None)
  458.         if _ofctl is not None:
  459.             groups = _ofctl.get_port_desc(dp, self.waiters)
  460.  
  461.         else:
  462.             LOG.debug('Unsupported OF protocol')
  463.             return Response(status=501)
  464.  
  465.         body = json.dumps(groups, ensure_ascii=True, indent=3, sort_keys=True)
  466.         return Response(content_type='application/json', body=body)
  467.  
  468.     def mod_flow_entry(self, req, cmd, **_kwargs):
  469.  
  470.         try:
  471.             flow = ast.literal_eval(req.body)
  472.  
  473.         except SyntaxError:
  474.             LOG.debug('invalid syntax %s', req.body)
  475.             return Response(status=400)
  476.  
  477.         dpid = flow.get('dpid')
  478.  
  479.         if type(dpid) == str and not dpid.isdigit():
  480.             LOG.debug('invalid dpid %s', dpid)
  481.             return Response(status=400)
  482.  
  483.         dp = self.dpset.get(int(dpid))
  484.  
  485.         if dp is None:
  486.             return Response(status=404)
  487.  
  488.         if cmd == 'add':
  489.             cmd = dp.ofproto.OFPFC_ADD
  490.         elif cmd == 'modify':
  491.             cmd = dp.ofproto.OFPFC_MODIFY
  492.         elif cmd == 'modify_strict':
  493.             cmd = dp.ofproto.OFPFC_MODIFY_STRICT
  494.         elif cmd == 'delete':
  495.             cmd = dp.ofproto.OFPFC_DELETE
  496.         elif cmd == 'delete_strict':
  497.             cmd = dp.ofproto.OFPFC_DELETE_STRICT
  498.         else:
  499.             return Response(status=404)
  500.  
  501.         _ofp_version = dp.ofproto.OFP_VERSION
  502.         _ofctl = supported_ofctl.get(_ofp_version, None)
  503.         if _ofctl is not None:
  504.             _ofctl.mod_flow_entry(dp, flow, cmd)
  505.         else:
  506.             LOG.debug('Unsupported OF protocol')
  507.             return Response(status=501)
  508.  
  509.         return Response(status=200)
  510.  
  511.     def delete_flow_entry(self, req, dpid, **_kwargs):
  512.  
  513.         if type(dpid) == str and not dpid.isdigit():
  514.             LOG.debug('invalid dpid %s', dpid)
  515.             return Response(status=400)
  516.  
  517.         dp = self.dpset.get(int(dpid))
  518.  
  519.         if dp is None:
  520.             return Response(status=404)
  521.  
  522.         _ofp_version = dp.ofproto.OFP_VERSION
  523.  
  524.         if ofproto_v1_0.OFP_VERSION == _ofp_version:
  525.             flow = {}
  526.         else:
  527.             flow = {'table_id': dp.ofproto.OFPTT_ALL}
  528.  
  529.         _ofctl = supported_ofctl.get(_ofp_version, None)
  530.         if _ofctl is not None:
  531.             _ofctl.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
  532.  
  533.         else:
  534.             LOG.debug('Unsupported OF protocol')
  535.             return Response(status=501)
  536.  
  537.         return Response(status=200)
  538.  
  539.     def mod_meter_entry(self, req, cmd, **_kwargs):
  540.  
  541.         try:
  542.             flow = ast.literal_eval(req.body)
  543.  
  544.         except SyntaxError:
  545.             LOG.debug('invalid syntax %s', req.body)
  546.             return Response(status=400)
  547.  
  548.         dpid = flow.get('dpid')
  549.  
  550.         if type(dpid) == str and not dpid.isdigit():
  551.             LOG.debug('invalid dpid %s', dpid)
  552.             return Response(status=400)
  553.  
  554.         dp = self.dpset.get(int(dpid))
  555.  
  556.         if dp is None:
  557.             return Response(status=404)
  558.  
  559.         if cmd == 'add':
  560.             cmd = dp.ofproto.OFPMC_ADD
  561.         elif cmd == 'modify':
  562.             cmd = dp.ofproto.OFPMC_MODIFY
  563.         elif cmd == 'delete':
  564.             cmd = dp.ofproto.OFPMC_DELETE
  565.         else:
  566.             return Response(status=404)
  567.  
  568.         _ofp_version = dp.ofproto.OFP_VERSION
  569.         _ofctl = supported_ofctl.get(_ofp_version, None)
  570.  
  571.         if _ofctl is not None and hasattr(_ofctl, 'mod_meter_entry'):
  572.             _ofctl.mod_meter_entry(dp, flow, cmd)
  573.  
  574.         else:
  575.             LOG.debug('Unsupported OF protocol or \
  576.                request not supported in this OF protocol version')
  577.             return Response(status=501)
  578.  
  579.         return Response(status=200)
  580.  
  581.     def mod_group_entry(self, req, cmd, **_kwargs):
  582.  
  583.         try:
  584.             group = ast.literal_eval(req.body)
  585.  
  586.         except SyntaxError:
  587.             LOG.debug('invalid syntax %s', req.body)
  588.             return Response(status=400)
  589.  
  590.         dpid = group.get('dpid')
  591.  
  592.         if type(dpid) == str and not dpid.isdigit():
  593.             LOG.debug('invalid dpid %s', dpid)
  594.             return Response(status=400)
  595.  
  596.         dp = self.dpset.get(int(dpid))
  597.  
  598.         if dp is None:
  599.             return Response(status=404)
  600.  
  601.         if cmd == 'add':
  602.             cmd = dp.ofproto.OFPGC_ADD
  603.         elif cmd == 'modify':
  604.             cmd = dp.ofproto.OFPGC_MODIFY
  605.         elif cmd == 'delete':
  606.             cmd = dp.ofproto.OFPGC_DELETE
  607.         else:
  608.             return Response(status=404)
  609.  
  610.         _ofp_version = dp.ofproto.OFP_VERSION
  611.         _ofctl = supported_ofctl.get(_ofp_version, None)
  612.  
  613.         if _ofctl is not None and hasattr(_ofctl, 'mod_group_entry'):
  614.             _ofctl.mod_group_entry(dp, group, cmd)
  615.  
  616.         else:
  617.             LOG.debug('Unsupported OF protocol or \
  618.                request not supported in this OF protocol version')
  619.             return Response(status=501)
  620.  
  621.         return Response(status=200)
  622.  
  623.     def mod_port_behavior(self, req, cmd, **_kwargs):
  624.  
  625.         try:
  626.             port_config = ast.literal_eval(req.body)
  627.  
  628.         except SyntaxError:
  629.             LOG.debug('invalid syntax %s', req.body)
  630.             return Response(status=400)
  631.  
  632.         dpid = port_config.get('dpid')
  633.  
  634.         if type(dpid) == str and not dpid.isdigit():
  635.             LOG.debug('invalid dpid %s', dpid)
  636.             return Response(status=400)
  637.  
  638.         port_no = port_config.get('port_no', 0)
  639.         if type(port_no) == str and not port_no.isdigit():
  640.             LOG.debug('invalid port_no %s', port_no)
  641.             return Response(status=400)
  642.  
  643.         port_info = self.dpset.port_state[int(dpid)].get(port_no)
  644.  
  645.         if port_info:
  646.             port_config.setdefault('hw_addr', port_info.hw_addr)
  647.             port_config.setdefault('advertise', port_info.advertised)
  648.         else:
  649.             return Response(status=404)
  650.  
  651.         dp = self.dpset.get(int(dpid))
  652.  
  653.         if dp is None:
  654.             return Response(status=404)
  655.  
  656.         if cmd != 'modify':
  657.             return Response(status=404)
  658.  
  659.         _ofp_version = dp.ofproto.OFP_VERSION
  660.  
  661.         _ofctl = supported_ofctl.get(_ofp_version, None)
  662.         if _ofctl is not None:
  663.             _ofctl.mod_port_behavior(dp, port_config)
  664.  
  665.         else:
  666.             LOG.debug('Unsupported OF protocol')
  667.             return Response(status=501)
  668.  
  669.         return Response(status=200)
  670.  
  671.     def send_experimenter(self, req, dpid, **_kwargs):
  672.  
  673.         if type(dpid) == str and not dpid.isdigit():
  674.             LOG.debug('invalid dpid %s', dpid)
  675.             return Response(status=400)
  676.  
  677.         dp = self.dpset.get(int(dpid))
  678.  
  679.         if dp is None:
  680.             return Response(status=404)
  681.  
  682.         try:
  683.             exp = ast.literal_eval(req.body)
  684.  
  685.         except SyntaxError:
  686.             LOG.debug('invalid syntax %s', req.body)
  687.             return Response(status=400)
  688.  
  689.         _ofp_version = dp.ofproto.OFP_VERSION
  690.         _ofctl = supported_ofctl.get(_ofp_version, None)
  691.  
  692.         if _ofctl is not None and hasattr(_ofctl, 'send_experimenter'):
  693.             _ofctl.send_experimenter(dp, exp)
  694.  
  695.         else:
  696.             LOG.debug('Unsupported OF protocol')
  697.             return Response(status=501)
  698.  
  699.         return Response(status=200)
  700.  
  701.     #receive_neww_msg: receive a simple msg via REST API
  702.     def receive_new_msg(self, req, **_kwargs):
  703.         try:
  704.             msg = ast.literal_eval(req.body) #json body
  705.             print "this is the msg:"
  706.             print msg
  707.  
  708.             #data = json.loads(msg)
  709.  
  710.             print "this is the data after load"
  711.             #print data
  712.  
  713.             """print "DPID %s",data[dpid]
  714.            print "IpDestination %s", data[ip_dst]
  715.            print "IpSource %s", data[ip_src]
  716.            print "TCP_in_port %s", data[tcp_src]
  717.            print "TCP_out_port %s", data[tcp_dst]
  718.            print "Number of TCP retransmissions for this flow: %s", data[tcp_num]"""
  719.  
  720.         except SyntaxError:
  721.             LOG.debug('invalid syntax %s', req.body)
  722.             return Response(status=400)
  723.  
  724.  
  725.  
  726. class RestStatsApi(app_manager.RyuApp):
  727.     OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION,
  728.                     ofproto_v1_2.OFP_VERSION,
  729.                     ofproto_v1_3.OFP_VERSION]
  730.     _CONTEXTS = {
  731.         'dpset': dpset.DPSet,
  732.         'wsgi': WSGIApplication
  733.     }
  734.  
  735.     def __init__(self, *args, **kwargs):
  736.         super(RestStatsApi, self).__init__(*args, **kwargs)
  737.         self.dpset = kwargs['dpset']
  738.         wsgi = kwargs['wsgi']
  739.         self.waiters = {}
  740.         self.data = {}
  741.         self.data['dpset'] = self.dpset
  742.         self.data['waiters'] = self.waiters
  743.         mapper = wsgi.mapper
  744.  
  745.         wsgi.registory['StatsController'] = self.data
  746.         path = '/stats'
  747.         uri = path + '/switches'
  748.         mapper.connect('stats', uri,
  749.                        controller=StatsController, action='get_dpids',
  750.                        conditions=dict(method=['GET']))
  751.  
  752.         uri = path + '/desc/{dpid}'
  753.         mapper.connect('stats', uri,
  754.                        controller=StatsController, action='get_desc_stats',
  755.                        conditions=dict(method=['GET']))
  756.  
  757.         uri = path + '/flow/{dpid}'
  758.         mapper.connect('stats', uri,
  759.                        controller=StatsController, action='get_flow_stats',
  760.                        conditions=dict(method=['GET', 'POST']))
  761.  
  762.         uri = path + '/aggregateflow/{dpid}'
  763.         mapper.connect('stats', uri,
  764.                        controller=StatsController,
  765.                        action='get_aggregate_flow_stats',
  766.                        conditions=dict(method=['GET', 'POST']))
  767.  
  768.         uri = path + '/port/{dpid}'
  769.         mapper.connect('stats', uri,
  770.                        controller=StatsController, action='get_port_stats',
  771.                        conditions=dict(method=['GET']))
  772.  
  773.         uri = path + '/queue/{dpid}'
  774.         mapper.connect('stats', uri,
  775.                        controller=StatsController, action='get_queue_stats',
  776.                        conditions=dict(method=['GET']))
  777.  
  778.         uri = path + '/meterfeatures/{dpid}'
  779.         mapper.connect('stats', uri,
  780.                        controller=StatsController, action='get_meter_features',
  781.                        conditions=dict(method=['GET']))
  782.  
  783.         uri = path + '/meterconfig/{dpid}'
  784.         mapper.connect('stats', uri,
  785.                        controller=StatsController, action='get_meter_config',
  786.                        conditions=dict(method=['GET']))
  787.  
  788.         uri = path + '/meter/{dpid}'
  789.         mapper.connect('stats', uri,
  790.                        controller=StatsController, action='get_meter_stats',
  791.                        conditions=dict(method=['GET']))
  792.  
  793.         uri = path + '/groupfeatures/{dpid}'
  794.         mapper.connect('stats', uri,
  795.                        controller=StatsController, action='get_group_features',
  796.                        conditions=dict(method=['GET']))
  797.  
  798.         uri = path + '/groupdesc/{dpid}'
  799.         mapper.connect('stats', uri,
  800.                        controller=StatsController, action='get_group_desc',
  801.                        conditions=dict(method=['GET']))
  802.  
  803.         uri = path + '/group/{dpid}'
  804.         mapper.connect('stats', uri,
  805.                        controller=StatsController, action='get_group_stats',
  806.                        conditions=dict(method=['GET']))
  807.  
  808.         uri = path + '/portdesc/{dpid}'
  809.         mapper.connect('stats', uri,
  810.                        controller=StatsController, action='get_port_desc',
  811.                        conditions=dict(method=['GET']))
  812.  
  813.         uri = path + '/flowentry/{cmd}'
  814.         mapper.connect('stats', uri,
  815.                        controller=StatsController, action='mod_flow_entry',
  816.                        conditions=dict(method=['POST']))
  817.  
  818.         uri = path + '/flowentry/clear/{dpid}'
  819.         mapper.connect('stats', uri,
  820.                        controller=StatsController, action='delete_flow_entry',
  821.                        conditions=dict(method=['DELETE']))
  822.  
  823.         uri = path + '/meterentry/{cmd}'
  824.         mapper.connect('stats', uri,
  825.                        controller=StatsController, action='mod_meter_entry',
  826.                        conditions=dict(method=['POST']))
  827.  
  828.         uri = path + '/groupentry/{cmd}'
  829.         mapper.connect('stats', uri,
  830.                        controller=StatsController, action='mod_group_entry',
  831.                        conditions=dict(method=['POST']))
  832.  
  833.         uri = path + '/portdesc/{cmd}'
  834.         mapper.connect('stats', uri,
  835.                        controller=StatsController, action='mod_port_behavior',
  836.                        conditions=dict(method=['POST']))
  837.  
  838.         uri = path + '/experimenter/{dpid}'
  839.         mapper.connect('stats', uri,
  840.                        controller=StatsController, action='send_experimenter',
  841.                        conditions=dict(method=['POST']))
  842.         #my function
  843.         uri = path + '/my_stats'
  844.         mapper.connect('stats', uri,
  845.                        controller=StatsController, action='receive_new_msg',
  846.                        conditions=dict(method=['POST']))
  847.  
  848.  
  849.     @set_ev_cls([ofp_event.EventOFPStatsReply,
  850.                  ofp_event.EventOFPDescStatsReply,
  851.                  ofp_event.EventOFPFlowStatsReply,
  852.                  ofp_event.EventOFPAggregateStatsReply,
  853.                  ofp_event.EventOFPPortStatsReply,
  854.                  ofp_event.EventOFPQueueStatsReply,
  855.                  ofp_event.EventOFPMeterStatsReply,
  856.                  ofp_event.EventOFPMeterFeaturesStatsReply,
  857.                  ofp_event.EventOFPMeterConfigStatsReply,
  858.                  ofp_event.EventOFPGroupStatsReply,
  859.                  ofp_event.EventOFPGroupFeaturesStatsReply,
  860.                  ofp_event.EventOFPGroupDescStatsReply,
  861.                  ofp_event.EventOFPPortDescStatsReply
  862.                  ], MAIN_DISPATCHER)
  863.     def stats_reply_handler(self, ev):
  864.         msg = ev.msg
  865.         dp = msg.datapath
  866.  
  867.         if dp.id not in self.waiters:
  868.             return
  869.         if msg.xid not in self.waiters[dp.id]:
  870.             return
  871.         lock, msgs = self.waiters[dp.id][msg.xid]
  872.         msgs.append(msg)
  873.  
  874.         flags = 0
  875.         if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
  876.             flags = dp.ofproto.OFPSF_REPLY_MORE
  877.         elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
  878.             flags = dp.ofproto.OFPSF_REPLY_MORE
  879.         elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
  880.             flags = dp.ofproto.OFPMPF_REPLY_MORE
  881.  
  882.         if msg.flags & flags:
  883.             return
  884.         del self.waiters[dp.id][msg.xid]
  885.         lock.set()
  886.  
  887.     @set_ev_cls([ofp_event.EventOFPSwitchFeatures], MAIN_DISPATCHER)
  888.     def features_reply_handler(self, ev):
  889.         msg = ev.msg
  890.         dp = msg.datapath
  891.  
  892.         if dp.id not in self.waiters:
  893.             return
  894.         if msg.xid not in self.waiters[dp.id]:
  895.             return
  896.         lock, msgs = self.waiters[dp.id][msg.xid]
  897.         msgs.append(msg)
  898.  
  899.         del self.waiters[dp.id][msg.xid]
  900.         lock.set()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement