[^/]+)$") @classmethod
**** CubicPower OpenStack Study ****
def filter_supported(cls):
return True
**** CubicPower OpenStack Study ****
def _set_param(self, filter_dict, body, key, create, convert_to=None):
if key in filter_dict:
if filter_dict[key]:
if convert_to:
body[key] = convert_to(filter_dict[key])
else:
body[key] = filter_dict[key]
elif not create:
body[key] = ""
**** CubicPower OpenStack Study ****
def _generate_body(self, filter_dict, apply_ports=None, create=True):
body = {}
if create:
# action : pass, drop (mandatory)
if filter_dict['action'].lower() in ext_pf.ALLOW_ACTIONS:
body['action'] = self.PFC_ALLOW_ACTION
else:
body['action'] = self.PFC_DROP_ACTION
# priority : mandatory
body['priority'] = filter_dict['priority']
for key in ['src_mac', 'dst_mac', 'src_port', 'dst_port']:
self._set_param(filter_dict, body, key, create)
for key in ['src_cidr', 'dst_cidr']:
# CIDR must contain netmask even if it is an address.
convert_to = lambda x: str(netaddr.IPNetwork(x))
self._set_param(filter_dict, body, key, create, convert_to)
# protocol : decimal (0-255)
if 'protocol' in filter_dict:
if (not filter_dict['protocol'] or
# In the case of ARP, ip_proto should be set to wildcard.
# eth_type is set during adding an entry to DB layer.
filter_dict['protocol'].lower() == ext_pf.PROTO_NAME_ARP):
if not create:
body['protocol'] = ""
elif filter_dict['protocol'].lower() == constants.PROTO_NAME_ICMP:
body['protocol'] = constants.PROTO_NUM_ICMP
elif filter_dict['protocol'].lower() == constants.PROTO_NAME_TCP:
body['protocol'] = constants.PROTO_NUM_TCP
elif filter_dict['protocol'].lower() == constants.PROTO_NAME_UDP:
body['protocol'] = constants.PROTO_NUM_UDP
else:
body['protocol'] = int(filter_dict['protocol'], 0)
# eth_type : hex (0x0-0xFFFF)
self._set_param(filter_dict, body, 'eth_type', create, hex)
# apply_ports
if apply_ports:
# each element of apply_ports is a tuple of (neutron_id, ofc_id),
body['apply_ports'] = []
for p in apply_ports:
try:
body['apply_ports'].append(self._extract_ofc_port_id(p[1]))
except InvalidOFCIdFormat:
pass
return body
**** CubicPower OpenStack Study ****
def _validate_filter_common(self, filter_dict):
# Currently PFC support only IPv4 CIDR.
for field in ['src_cidr', 'dst_cidr']:
if (not filter_dict.get(field) or
filter_dict[field] == attributes.ATTR_NOT_SPECIFIED):
continue
net = netaddr.IPNetwork(filter_dict[field])
if net.version != 4:
raise ext_pf.PacketFilterIpVersionNonSupported(
version=net.version, field=field, value=filter_dict[field])
if ('priority' in filter_dict and
not (self.MIN_PRIORITY <= filter_dict['priority']
<= self.MAX_PRIORITY)):
raise ext_pf.PacketFilterInvalidPriority(
min=self.MIN_PRIORITY, max=self.MAX_PRIORITY)
**** CubicPower OpenStack Study ****
def _validate_duplicate_priority(self, context, filter_dict):
plugin = manager.NeutronManager.get_plugin()
filters = {'network_id': [filter_dict['network_id']],
'priority': [filter_dict['priority']]}
ret = plugin.get_packet_filters(context, filters=filters,
fields=['id'])
if ret:
raise ext_pf.PacketFilterDuplicatedPriority(
priority=filter_dict['priority'])
**** CubicPower OpenStack Study ****
def validate_filter_create(self, context, filter_dict):
self._validate_filter_common(filter_dict)
self._validate_duplicate_priority(context, filter_dict)
**** CubicPower OpenStack Study ****
def validate_filter_update(self, context, filter_dict):
for field in self.CREATE_ONLY_FIELDS:
if field in filter_dict:
raise ext_pf.PacketFilterUpdateNotSupported(field=field)
self._validate_filter_common(filter_dict)
@call_log.log
**** CubicPower OpenStack Study ****
def create_filter(self, ofc_network_id, filter_dict,
portinfo=None, filter_id=None, apply_ports=None):
body = self._generate_body(filter_dict, apply_ports, create=True)
res = self.client.post(self.filters_path, body=body)
# filter_id passed from a caller is not used.
# ofc_filter_id is generated by PFC because the prefix of
# filter_id has special meaning and it is internally used.
ofc_filter_id = res['id']
return self.filter_path % ofc_filter_id
@call_log.log
**** CubicPower OpenStack Study ****
def update_filter(self, ofc_filter_id, filter_dict):
body = self._generate_body(filter_dict, create=False)
self.client.put(ofc_filter_id, body)
@call_log.log
**** CubicPower OpenStack Study ****
def delete_filter(self, ofc_filter_id):
return self.client.delete(ofc_filter_id)
**** CubicPower OpenStack Study ****
def _extract_ofc_filter_id(self, ofc_filter_id):
match = self.match_ofc_filter_id.match(ofc_filter_id)
if match:
return match.group('filter_id')
raise InvalidOFCIdFormat(resource='filter', ofc_id=ofc_filter_id)
**** CubicPower OpenStack Study ****
def convert_ofc_filter_id(self, context, ofc_filter_id):
# PFC Packet Filter is supported after the format of mapping tables
# are changed, so it is enough just to return ofc_filter_id
return ofc_filter_id
**** CubicPower OpenStack Study ****
class PFCRouterDriverMixin(object):
router_supported = True
router_nat_supported = False
**** CubicPower OpenStack Study ****
def create_router(self, ofc_tenant_id, router_id, description):
path = '%s/routers' % ofc_tenant_id
res = self.client.post(path, body=None)
ofc_router_id = res['id']
return path + '/' + ofc_router_id
**** CubicPower OpenStack Study ****
def delete_router(self, ofc_router_id):
return self.client.delete(ofc_router_id)
**** CubicPower OpenStack Study ****
def add_router_interface(self, ofc_router_id, ofc_net_id,
ip_address=None, mac_address=None):
# ip_address : / (e.g., 10.0.0.0/24) path = '%s/interfaces' % ofc_router_id
body = {'net_id': self._extract_ofc_network_id(ofc_net_id)}
if ip_address:
body['ip_address'] = ip_address
if mac_address:
body['mac_address'] = mac_address
res = self.client.post(path, body=body)
return path + '/' + res['id']
**** CubicPower OpenStack Study ****
def update_router_interface(self, ofc_router_inf_id,
ip_address=None, mac_address=None):
# ip_address : / (e.g., 10.0.0.0/24) if not ip_address and not mac_address:
return
body = {}
if ip_address:
body['ip_address'] = ip_address
if mac_address:
body['mac_address'] = mac_address
return self.client.put(ofc_router_inf_id, body=body)
**** CubicPower OpenStack Study ****
def delete_router_interface(self, ofc_router_inf_id):
return self.client.delete(ofc_router_inf_id)
**** CubicPower OpenStack Study ****
def list_router_routes(self, ofc_router_id):
path = '%s/routes' % ofc_router_id
ret = self.client.get(path)
# Prepend ofc_router_id to route_id
for r in ret['routes']:
r['id'] = ofc_router_id + '/routes/' + r['id']
return ret['routes']
**** CubicPower OpenStack Study ****
def add_router_route(self, ofc_router_id, destination, nexthop):
path = '%s/routes' % ofc_router_id
body = {'destination': destination,
'nexthop': nexthop}
ret = self.client.post(path, body=body)
return path + '/' + ret['id']
**** CubicPower OpenStack Study ****
def delete_router_route(self, ofc_router_route_id):
return self.client.delete(ofc_router_route_id)
**** CubicPower OpenStack Study ****
class PFCV3Driver(PFCDriverBase):
**** CubicPower OpenStack Study ****
def create_tenant(self, description, tenant_id):
ofc_tenant_id = self._generate_pfc_id(tenant_id)
return "/tenants/" + ofc_tenant_id
**** CubicPower OpenStack Study ****
def delete_tenant(self, ofc_tenant_id):
pass
**** CubicPower OpenStack Study ****
class PFCV4Driver(PFCDriverBase):
pass
**** CubicPower OpenStack Study ****
class PFCV5Driver(PFCRouterDriverMixin, PFCDriverBase):
pass
**** CubicPower OpenStack Study ****
class PFCV51Driver(PFCFilterDriverMixin, PFCV5Driver):
pass