Avoid invalid dpid and simplify the checking of ofctl version

Signed-off-by: Takeshi <a86487817@gmail.com>
Reviewed-by: Yusuke Iwase <iwase.yusuke0@gmail.com>
This commit is contained in:
Takeshi 2015-04-04 01:06:01 +08:00 committed by FUJITA Tomonori
parent c330ba18f7
commit 6973cde0cf

View File

@ -35,6 +35,13 @@ from ryu.app.wsgi import ControllerBase, WSGIApplication
LOG = logging.getLogger('ryu.app.ofctl_rest')
# supported ofctl versions in this restful app
supported_ofctl = {
ofproto_v1_0.OFP_VERSION: ofctl_v1_0,
ofproto_v1_2.OFP_VERSION: ofctl_v1_2,
ofproto_v1_3.OFP_VERSION: ofctl_v1_3,
}
# REST API
#
@ -143,16 +150,21 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_desc_stats(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
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:
desc = _ofctl.get_desc_stats(dp, self.waiters)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
desc = ofctl_v1_0.get_desc_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
desc = ofctl_v1_2.get_desc_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
desc = ofctl_v1_3.get_desc_stats(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -161,25 +173,34 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_flow_stats(self, req, dpid, **_kwargs):
if req.body == '':
flow = {}
else:
try:
flow = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
flows = ofctl_v1_0.get_flow_stats(dp, self.waiters, flow)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
flows = ofctl_v1_2.get_flow_stats(dp, self.waiters, flow)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
flows = ofctl_v1_3.get_flow_stats(dp, self.waiters, flow)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
flows = _ofctl.get_flow_stats(dp, self.waiters, flow)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -188,25 +209,33 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_aggregate_flow_stats(self, req, dpid, **_kwargs):
if req.body == '':
flow = {}
else:
try:
flow = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
flows = ofctl_v1_0.get_aggregate_flow_stats(dp, self.waiters, flow)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
flows = ofctl_v1_2.get_aggregate_flow_stats(dp, self.waiters, flow)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
flows = ofctl_v1_3.get_aggregate_flow_stats(dp, self.waiters, flow)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
flows = _ofctl.get_aggregate_flow_stats(dp, self.waiters, flow)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -215,16 +244,22 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_port_stats(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
ports = ofctl_v1_0.get_port_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ports = ofctl_v1_2.get_port_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ports = ofctl_v1_3.get_port_stats(dp, self.waiters)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
ports = _ofctl.get_port_stats(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -233,16 +268,22 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_queue_stats(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
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)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
queues = _ofctl.get_queue_stats(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -251,127 +292,172 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def get_meter_features(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
meters = ofctl_v1_3.get_meter_features(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_meter_features'):
meters = _ofctl.get_meter_features(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(meters)
return Response(content_type='application/json', body=body)
def get_meter_config(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
meters = ofctl_v1_3.get_meter_config(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_meter_config'):
meters = _ofctl.get_meter_config(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(meters)
return Response(content_type='application/json', body=body)
def get_meter_stats(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
meters = ofctl_v1_3.get_meter_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_meter_stats'):
meters = _ofctl.get_meter_stats(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(meters)
return Response(content_type='application/json', body=body)
def get_group_features(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
groups = ofctl_v1_2.get_group_features(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
groups = ofctl_v1_3.get_group_features(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_group_features'):
groups = _ofctl.get_group_features(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(groups)
return Response(content_type='application/json', body=body)
def get_group_desc(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
groups = ofctl_v1_2.get_group_desc(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
groups = ofctl_v1_3.get_group_desc(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_group_desc'):
groups = _ofctl.get_group_desc(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(groups)
return Response(content_type='application/json', body=body)
def get_group_stats(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
groups = ofctl_v1_2.get_group_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
groups = ofctl_v1_3.get_group_stats(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'get_group_stats'):
groups = _ofctl.get_group_stats(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
body = json.dumps(groups)
return Response(content_type='application/json', body=body)
def get_port_desc(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
groups = ofctl_v1_0.get_port_desc(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
groups = ofctl_v1_2.get_port_desc(dp, self.waiters)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
groups = ofctl_v1_3.get_port_desc(dp, self.waiters)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
groups = _ofctl.get_port_desc(dp, self.waiters)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -380,14 +466,22 @@ class StatsController(ControllerBase):
return Response(content_type='application/json', body=body)
def mod_flow_entry(self, req, cmd, **_kwargs):
try:
flow = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
dpid = flow.get('dpid')
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
@ -404,12 +498,10 @@ class StatsController(ControllerBase):
else:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
ofctl_v1_0.mod_flow_entry(dp, flow, cmd)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ofctl_v1_2.mod_flow_entry(dp, flow, cmd)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.mod_flow_entry(dp, flow, cmd)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
_ofctl.mod_flow_entry(dp, flow, cmd)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -417,18 +509,24 @@ class StatsController(ControllerBase):
return Response(status=200)
def delete_flow_entry(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
flow = {'table_id': dp.ofproto.OFPTT_ALL}
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
ofctl_v1_0.delete_flow_entry(dp)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ofctl_v1_2.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
_ofctl.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
@ -436,14 +534,22 @@ class StatsController(ControllerBase):
return Response(status=200)
def mod_meter_entry(self, req, cmd, **_kwargs):
try:
flow = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
dpid = flow.get('dpid')
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
@ -456,34 +562,39 @@ class StatsController(ControllerBase):
else:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.mod_meter_entry(dp, flow, cmd)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'mod_meter_entry'):
_ofctl.mod_meter_entry(dp, flow, cmd)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
return Response(status=200)
def mod_group_entry(self, req, cmd, **_kwargs):
try:
group = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
dpid = group.get('dpid')
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
if cmd == 'add':
cmd = dp.ofproto.OFPGC_ADD
elif cmd == 'modify':
@ -493,27 +604,41 @@ class StatsController(ControllerBase):
else:
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ofctl_v1_2.mod_group_entry(dp, group, cmd)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.mod_group_entry(dp, group, cmd)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'mod_group_entry'):
_ofctl.mod_group_entry(dp, group, cmd)
else:
LOG.debug('Unsupported OF protocol')
LOG.debug('Unsupported OF protocol or \
request not supported in this OF protocol version')
return Response(status=501)
return Response(status=200)
def mod_port_behavior(self, req, cmd, **_kwargs):
try:
port_config = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
dpid = port_config.get('dpid')
port_no = int(port_config.get('port_no', 0))
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
port_no = port_config.get('port_no', 0)
if type(port_no) == str and not port_no.isdigit():
LOG.debug('invalid port_no %s', port_no)
return Response(status=400)
port_info = self.dpset.port_state[int(dpid)].get(port_no)
if port_info:
port_config.setdefault('hw_addr', port_info.hw_addr)
port_config.setdefault('advertise', port_info.advertised)
@ -521,40 +646,49 @@ class StatsController(ControllerBase):
return Response(status=404)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
if cmd != 'modify':
return Response(status=404)
if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
ofctl_v1_0.mod_port_behavior(dp, port_config)
elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ofctl_v1_2.mod_port_behavior(dp, port_config)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.mod_port_behavior(dp, port_config)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None:
_ofctl.mod_port_behavior(dp, port_config)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)
return Response(status=200)
def send_experimenter(self, req, dpid, **_kwargs):
if type(dpid) == str and not dpid.isdigit():
LOG.debug('invalid dpid %s', dpid)
return Response(status=400)
dp = self.dpset.get(int(dpid))
if dp is None:
return Response(status=404)
try:
exp = ast.literal_eval(req.body)
except SyntaxError:
LOG.debug('invalid syntax %s', req.body)
return Response(status=400)
if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
ofctl_v1_2.send_experimenter(dp, exp)
elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
ofctl_v1_3.send_experimenter(dp, exp)
elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
LOG.debug('Request not supported in this OF protocol version')
return Response(status=501)
_ofp_version = dp.ofproto.OFP_VERSION
_ofctl = supported_ofctl.get(_ofp_version, None)
if _ofctl is not None and hasattr(_ofctl, 'send_experimenter'):
_ofctl.send_experimenter(dp, exp)
else:
LOG.debug('Unsupported OF protocol')
return Response(status=501)