mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-12 00:03:24 +02:00
packet/bgp: Support IPv6 Flow Spec
Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
64b9dfcdd6
commit
bb38fb2f30
@ -574,7 +574,9 @@ RF_IPv4_MPLS = RouteFamily(addr_family.IP, subaddr_family.MPLS_LABEL)
|
||||
RF_IPv6_MPLS = RouteFamily(addr_family.IP6, subaddr_family.MPLS_LABEL)
|
||||
RF_L2_EVPN = RouteFamily(addr_family.L2VPN, subaddr_family.EVPN)
|
||||
RF_IPv4_FLOWSPEC = RouteFamily(addr_family.IP, subaddr_family.IP_FLOWSPEC)
|
||||
RF_IPv6_FLOWSPEC = RouteFamily(addr_family.IP6, subaddr_family.IP_FLOWSPEC)
|
||||
RF_VPNv4_FLOWSPEC = RouteFamily(addr_family.IP, subaddr_family.VPN_FLOWSPEC)
|
||||
RF_VPNv6_FLOWSPEC = RouteFamily(addr_family.IP6, subaddr_family.VPN_FLOWSPEC)
|
||||
RF_RTC_UC = RouteFamily(addr_family.IP,
|
||||
subaddr_family.ROUTE_TARGET_CONSTRAINTS)
|
||||
|
||||
@ -587,7 +589,9 @@ _rf_map = {
|
||||
(addr_family.IP6, subaddr_family.MPLS_LABEL): RF_IPv6_MPLS,
|
||||
(addr_family.L2VPN, subaddr_family.EVPN): RF_L2_EVPN,
|
||||
(addr_family.IP, subaddr_family.IP_FLOWSPEC): RF_IPv4_FLOWSPEC,
|
||||
(addr_family.IP6, subaddr_family.IP_FLOWSPEC): RF_IPv6_FLOWSPEC,
|
||||
(addr_family.IP, subaddr_family.VPN_FLOWSPEC): RF_VPNv4_FLOWSPEC,
|
||||
(addr_family.IP6, subaddr_family.VPN_FLOWSPEC): RF_VPNv6_FLOWSPEC,
|
||||
(addr_family.IP, subaddr_family.ROUTE_TARGET_CONSTRAINTS): RF_RTC_UC
|
||||
}
|
||||
|
||||
@ -2035,7 +2039,8 @@ class _FlowSpecNLRIBase(StringifyMixin, TypeDisp):
|
||||
rules = []
|
||||
|
||||
while rest:
|
||||
subcls, rest = _FlowSpecComponentBase.parse_header(rest)
|
||||
subcls, rest = _FlowSpecComponentBase.parse_header(
|
||||
rest, cls.ROUTE_FAMILY.afi)
|
||||
|
||||
while rest:
|
||||
rule, rest = subcls.parse_body(rest)
|
||||
@ -2080,7 +2085,8 @@ class _FlowSpecNLRIBase(StringifyMixin, TypeDisp):
|
||||
def _from_user(cls, **kwargs):
|
||||
rules = []
|
||||
for k, v in kwargs.items():
|
||||
subcls = _FlowSpecComponentBase.lookup_type_name(k)
|
||||
subcls = _FlowSpecComponentBase.lookup_type_name(
|
||||
k, cls.ROUTE_FAMILY.afi)
|
||||
rule = subcls.from_str(str(v))
|
||||
rules.extend(rule)
|
||||
rules.sort(key=lambda x: x.type)
|
||||
@ -2236,7 +2242,8 @@ class FlowSpecVPNv4NLRI(_FlowSpecNLRIBase):
|
||||
def _from_user(cls, route_dist, **kwargs):
|
||||
rules = []
|
||||
for k, v in kwargs.items():
|
||||
subcls = _FlowSpecComponentBase.lookup_type_name(k)
|
||||
subcls = _FlowSpecComponentBase.lookup_type_name(
|
||||
k, cls.ROUTE_FAMILY.afi)
|
||||
rule = subcls.from_str(str(v))
|
||||
rules.extend(rule)
|
||||
rules.sort(key=lambda x: x.type)
|
||||
@ -2277,6 +2284,107 @@ class FlowSpecVPNv4NLRI(_FlowSpecNLRIBase):
|
||||
return '%s:%s' % (self.route_dist, self.prefix)
|
||||
|
||||
|
||||
class FlowSpecIPv6NLRI(_FlowSpecNLRIBase):
|
||||
"""
|
||||
Flow Specification NLRI class for IPv6 [RFC draft-ietf-idr-flow-spec-v6-08]
|
||||
"""
|
||||
ROUTE_FAMILY = RF_IPv6_FLOWSPEC
|
||||
FLOWSPEC_FAMILY = 'ipv6fs'
|
||||
|
||||
@classmethod
|
||||
def from_user(cls, **kwargs):
|
||||
"""
|
||||
Utility method for creating a NLRI instance.
|
||||
|
||||
This function returns a NLRI instance from human readable format value.
|
||||
|
||||
:param kwargs: The following arguments are available.
|
||||
|
||||
=========== ============= ========= ==============================
|
||||
Argument Value Operator Description
|
||||
=========== ============= ========= ==============================
|
||||
dst_prefix IPv6 Prefix Nothing Destination Prefix.
|
||||
src_prefix IPv6 Prefix Nothing Source Prefix.
|
||||
next_header Integer Numeric Next Header.
|
||||
port Integer Numeric Port number.
|
||||
dst_port Integer Numeric Destination port number.
|
||||
src_port Integer Numeric Source port number.
|
||||
icmp_type Integer Numeric ICMP type.
|
||||
icmp_code Integer Numeric ICMP code.
|
||||
tcp_flags Fixed string Bitmask TCP flags.
|
||||
Supported values are
|
||||
``CWR``, ``ECN``, ``URGENT``,
|
||||
``ACK``, ``PUSH``, ``RST``,
|
||||
``SYN`` and ``FIN``.
|
||||
packet_len Integer Numeric Packet length.
|
||||
dscp Integer Numeric Differentiated Services
|
||||
Code Point.
|
||||
fragment Fixed string Bitmask Fragment.
|
||||
Supported values are
|
||||
``ISF`` (Is a fragment),
|
||||
``FF`` (First fragment) and
|
||||
``LF`` (Last fragment)
|
||||
flow_label Intefer Numeric Flow Label.
|
||||
=========== ============= ========= ==============================
|
||||
|
||||
.. Note::
|
||||
|
||||
For ``dst_prefix`` and ``src_prefix``, you can give "offset" value
|
||||
like this: ``2001::2/128/32``. At this case, ``offset`` is 32.
|
||||
``offset`` can be omitted, then ``offset`` is treated as 0.
|
||||
"""
|
||||
return cls._from_user(**kwargs)
|
||||
|
||||
|
||||
class FlowSpecVPNv6NLRI(_FlowSpecNLRIBase):
|
||||
"""
|
||||
Flow Specification NLRI class for VPNv6 [draft-ietf-idr-flow-spec-v6-08]
|
||||
"""
|
||||
|
||||
# flow-spec NLRI:
|
||||
# +-----------------------------------+
|
||||
# | length (0xnn or 0xfn nn) |
|
||||
# +-----------------------------------+
|
||||
# | RD (8 octets) |
|
||||
# +-----------------------------------+
|
||||
# | NLRI value (variable) |
|
||||
# +-----------------------------------+
|
||||
ROUTE_FAMILY = RF_VPNv6_FLOWSPEC
|
||||
FLOWSPEC_FAMILY = 'vpnv6fs'
|
||||
|
||||
def __init__(self, length=0, route_dist=None, rules=None):
|
||||
super(FlowSpecVPNv6NLRI, self).__init__(length, rules)
|
||||
assert route_dist is not None
|
||||
self.route_dist = route_dist
|
||||
|
||||
@classmethod
|
||||
def _from_user(cls, route_dist, **kwargs):
|
||||
rules = []
|
||||
for k, v in kwargs.items():
|
||||
subcls = _FlowSpecComponentBase.lookup_type_name(
|
||||
k, cls.ROUTE_FAMILY.afi)
|
||||
rule = subcls.from_str(str(v))
|
||||
rules.extend(rule)
|
||||
rules.sort(key=lambda x: x.type)
|
||||
return cls(route_dist=route_dist, rules=rules)
|
||||
|
||||
@classmethod
|
||||
def from_user(cls, route_dist, **kwargs):
|
||||
"""
|
||||
Utility method for creating a NLRI instance.
|
||||
|
||||
This function returns a NLRI instance from human readable format value.
|
||||
|
||||
:param route_dist: Route Distinguisher.
|
||||
:param kwargs: See :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv6NLRI`
|
||||
"""
|
||||
return cls._from_user(route_dist, **kwargs)
|
||||
|
||||
@property
|
||||
def formatted_nlri_str(self):
|
||||
return '%s:%s' % (self.route_dist, self.prefix)
|
||||
|
||||
|
||||
class _FlowSpecComponentBase(StringifyMixin, TypeDisp):
|
||||
"""
|
||||
Base class for Flow Specification NLRI component
|
||||
@ -2286,6 +2394,55 @@ class _FlowSpecComponentBase(StringifyMixin, TypeDisp):
|
||||
_BASE_STR = '!B'
|
||||
_BASE_STR_SIZE = struct.calcsize(_BASE_STR)
|
||||
|
||||
# Dictionary of COMPONENT_NAME to subclass.
|
||||
# e.g.)
|
||||
# _NAMES = {'dst_prefix': FlowSpecDestPrefix, ...}
|
||||
_NAMES = {}
|
||||
|
||||
def __init__(self, type_=None):
|
||||
if type_ is None:
|
||||
type_, _ = self._rev_lookup_type(self.__class__)
|
||||
self.type = type_
|
||||
|
||||
@classmethod
|
||||
def register_type(cls, type_, afi):
|
||||
cls._TYPES = cls._TYPES.copy()
|
||||
cls._NAMES = cls._NAMES.copy()
|
||||
|
||||
def _register_type(subcls):
|
||||
cls._TYPES[(type_, afi)] = subcls
|
||||
cls._NAMES[(subcls.COMPONENT_NAME, afi)] = subcls
|
||||
cls._REV_TYPES = None
|
||||
return subcls
|
||||
|
||||
return _register_type
|
||||
|
||||
@classmethod
|
||||
def lookup_type_name(cls, type_name, afi):
|
||||
return cls._NAMES[(type_name, afi)]
|
||||
|
||||
@classmethod
|
||||
def _lookup_type(cls, type_, afi):
|
||||
try:
|
||||
return cls._TYPES[(type_, afi)]
|
||||
except KeyError:
|
||||
return cls._UNKNOWN_TYPE
|
||||
|
||||
@classmethod
|
||||
def parse_header(cls, rest, afi):
|
||||
(type_,) = struct.unpack_from(
|
||||
cls._BASE_STR, six.binary_type(rest))
|
||||
rest = rest[cls._BASE_STR_SIZE:]
|
||||
return cls._lookup_type(type_, afi), rest
|
||||
|
||||
def serialize_header(self):
|
||||
return struct.pack(self._BASE_STR, self.type)
|
||||
|
||||
|
||||
class _FlowSpecIPv4Component(_FlowSpecComponentBase):
|
||||
"""
|
||||
Base class for Flow Specification for IPv4 NLRI component
|
||||
"""
|
||||
TYPE_DESTINATION_PREFIX = 0x01
|
||||
TYPE_SOURCE_PREFIX = 0x02
|
||||
TYPE_PROTOCOL = 0x03
|
||||
@ -2299,42 +2456,24 @@ class _FlowSpecComponentBase(StringifyMixin, TypeDisp):
|
||||
TYPE_DIFFSERV_CODE_POINT = 0x0b
|
||||
TYPE_FRAGMENT = 0x0c
|
||||
|
||||
# Dictionary of COMPONENT_NAME to subclass.
|
||||
# e.g.)
|
||||
# _NAMES = {'dst_prefix': FlowSpecDestPrefix, ...}
|
||||
_NAMES = {}
|
||||
|
||||
def __init__(self, type_=None):
|
||||
if type_ is None:
|
||||
type_ = self._rev_lookup_type(self.__class__)
|
||||
self.type = type_
|
||||
|
||||
@classmethod
|
||||
def register_type(cls, type_):
|
||||
cls._TYPES = cls._TYPES.copy()
|
||||
cls._NAMES = cls._NAMES.copy()
|
||||
|
||||
def _register_type(subcls):
|
||||
cls._TYPES[type_] = subcls
|
||||
cls._NAMES[subcls.COMPONENT_NAME] = subcls
|
||||
cls._REV_TYPES = None
|
||||
return subcls
|
||||
|
||||
return _register_type
|
||||
|
||||
@classmethod
|
||||
def lookup_type_name(cls, type_name):
|
||||
return cls._NAMES[type_name]
|
||||
|
||||
@classmethod
|
||||
def parse_header(cls, rest):
|
||||
(type_,) = struct.unpack_from(
|
||||
cls._BASE_STR, six.binary_type(rest))
|
||||
rest = rest[cls._BASE_STR_SIZE:]
|
||||
return cls._lookup_type(type_), rest
|
||||
|
||||
def serialize_header(self):
|
||||
return struct.pack(self._BASE_STR, self.type)
|
||||
class _FlowSpecIPv6Component(_FlowSpecComponentBase):
|
||||
"""
|
||||
Base class for Flow Specification for IPv6 NLRI component
|
||||
"""
|
||||
TYPE_DESTINATION_PREFIX = 0x01
|
||||
TYPE_SOURCE_PREFIX = 0x02
|
||||
TYPE_NEXT_HEADER = 0x03
|
||||
TYPE_PORT = 0x04
|
||||
TYPE_DESTINATION_PORT = 0x05
|
||||
TYPE_SOURCE_PORT = 0x06
|
||||
TYPE_ICMP = 0x07
|
||||
TYPE_ICMP_CODE = 0x08
|
||||
TYPE_TCP_FLAGS = 0x09
|
||||
TYPE_PACKET_LENGTH = 0x0a
|
||||
TYPE_DIFFSERV_CODE_POINT = 0x0b
|
||||
TYPE_FRAGMENT = 0x0c
|
||||
TYPE_FLOW_LABEL = 0x0d
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_unknown_type()
|
||||
@ -2355,7 +2494,7 @@ class FlowSpecComponentUnknown(_FlowSpecComponentBase):
|
||||
return self.buf
|
||||
|
||||
|
||||
class _FlowSpecPrefixBase(_FlowSpecComponentBase, IPAddrPrefix):
|
||||
class _FlowSpecPrefixBase(_FlowSpecIPv4Component, IPAddrPrefix):
|
||||
"""
|
||||
Prefix base class for Flow Specification NLRI component
|
||||
"""
|
||||
@ -2388,8 +2527,63 @@ class _FlowSpecPrefixBase(_FlowSpecComponentBase, IPAddrPrefix):
|
||||
return self.value
|
||||
|
||||
|
||||
class _FlowSpecIPv6PrefixBase(_FlowSpecIPv6Component, IP6AddrPrefix):
|
||||
"""
|
||||
Prefix base class for Flow Specification NLRI component
|
||||
"""
|
||||
_PACK_STR = '!BB' # length, offset
|
||||
|
||||
def __init__(self, length, addr, offset=0, type_=None):
|
||||
super(_FlowSpecIPv6PrefixBase, self).__init__(type_)
|
||||
self.length = length
|
||||
self.offset = offset
|
||||
prefix = "%s/%s" % (addr, length)
|
||||
self.addr = str(netaddr.ip.IPNetwork(prefix).network)
|
||||
|
||||
@classmethod
|
||||
def parser(cls, buf):
|
||||
(length, offset) = struct.unpack_from(
|
||||
cls._PACK_STR, six.binary_type(buf))
|
||||
rest = buf[struct.calcsize(cls._PACK_STR):]
|
||||
byte_length = (length + 7) // 8
|
||||
addr = cls._from_bin(rest[:byte_length])
|
||||
rest = rest[byte_length:]
|
||||
return cls(length=length, offset=offset, addr=addr), rest
|
||||
|
||||
@classmethod
|
||||
def parse_body(cls, buf):
|
||||
return cls.parser(buf)
|
||||
|
||||
def serialize(self):
|
||||
byte_length = (self.length + 7) // 8
|
||||
bin_addr = self._to_bin(self.addr)[:byte_length]
|
||||
buf = bytearray()
|
||||
msg_pack_into(self._PACK_STR, buf, 0, self.length, self.offset)
|
||||
return buf + bin_addr
|
||||
|
||||
def serialize_body(self):
|
||||
return self.serialize()
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, value):
|
||||
rule = []
|
||||
values = value.split('/')
|
||||
if len(values) == 3:
|
||||
rule.append(cls(int(values[1]), values[0], offset=int(values[2])))
|
||||
else:
|
||||
rule.append(cls(int(values[1]), values[0]))
|
||||
return rule
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return "%s/%s/%s" % (self.addr, self.length, self.offset)
|
||||
|
||||
def to_str(self):
|
||||
return self.value
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_DESTINATION_PREFIX)
|
||||
_FlowSpecIPv4Component.TYPE_DESTINATION_PREFIX, addr_family.IP)
|
||||
class FlowSpecDestPrefix(_FlowSpecPrefixBase):
|
||||
"""
|
||||
Destination Prefix for Flow Specification NLRI component
|
||||
@ -2398,7 +2592,7 @@ class FlowSpecDestPrefix(_FlowSpecPrefixBase):
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_SOURCE_PREFIX)
|
||||
_FlowSpecIPv4Component.TYPE_SOURCE_PREFIX, addr_family.IP)
|
||||
class FlowSpecSrcPrefix(_FlowSpecPrefixBase):
|
||||
"""
|
||||
Source Prefix for Flow Specification NLRI component
|
||||
@ -2406,6 +2600,24 @@ class FlowSpecSrcPrefix(_FlowSpecPrefixBase):
|
||||
COMPONENT_NAME = 'src_prefix'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_DESTINATION_PREFIX, addr_family.IP6)
|
||||
class FlowSpecIPv6DestPrefix(_FlowSpecIPv6PrefixBase):
|
||||
"""
|
||||
IPv6 destination Prefix for Flow Specification NLRI component
|
||||
"""
|
||||
COMPONENT_NAME = 'dst_prefix'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_SOURCE_PREFIX, addr_family.IP6)
|
||||
class FlowSpecIPv6SrcPrefix(_FlowSpecIPv6PrefixBase):
|
||||
"""
|
||||
IPv6 source Prefix for Flow Specification NLRI component
|
||||
"""
|
||||
COMPONENT_NAME = 'src_prefix'
|
||||
|
||||
|
||||
class _FlowSpecOperatorBase(_FlowSpecComponentBase):
|
||||
"""Operator base class for Flow Specification NLRI component
|
||||
|
||||
@ -2604,7 +2816,8 @@ class _FlowSpecBitmask(_FlowSpecOperatorBase):
|
||||
return string
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_PROTOCOL)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_PROTOCOL, addr_family.IP)
|
||||
class FlowSpecIPProtocol(_FlowSpecNumeric):
|
||||
"""IP Protocol for Flow Specification NLRI component
|
||||
|
||||
@ -2613,7 +2826,20 @@ class FlowSpecIPProtocol(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'ip_proto'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_PORT)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_NEXT_HEADER, addr_family.IP6)
|
||||
class FlowSpecNextHeader(_FlowSpecNumeric):
|
||||
"""Next Header value in IPv6 packets
|
||||
|
||||
Set the IP protocol number at value
|
||||
"""
|
||||
COMPONENT_NAME = 'next_header'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_PORT, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_PORT, addr_family.IP6)
|
||||
class FlowSpecPort(_FlowSpecNumeric):
|
||||
"""Port number for Flow Specification NLRI component
|
||||
|
||||
@ -2623,7 +2849,9 @@ class FlowSpecPort(_FlowSpecNumeric):
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_DESTINATION_PORT)
|
||||
_FlowSpecIPv4Component.TYPE_DESTINATION_PORT, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_DESTINATION_PORT, addr_family.IP6)
|
||||
class FlowSpecDestPort(_FlowSpecNumeric):
|
||||
"""Destination port number for Flow Specification NLRI component
|
||||
|
||||
@ -2632,7 +2860,10 @@ class FlowSpecDestPort(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'dst_port'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_SOURCE_PORT)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_SOURCE_PORT, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_SOURCE_PORT, addr_family.IP6)
|
||||
class FlowSpecSrcPort(_FlowSpecNumeric):
|
||||
"""Source port number for Flow Specification NLRI component
|
||||
|
||||
@ -2641,7 +2872,10 @@ class FlowSpecSrcPort(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'src_port'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_ICMP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_ICMP, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_ICMP, addr_family.IP6)
|
||||
class FlowSpecIcmpType(_FlowSpecNumeric):
|
||||
"""ICMP type for Flow Specification NLRI component
|
||||
|
||||
@ -2650,7 +2884,10 @@ class FlowSpecIcmpType(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'icmp_type'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_ICMP_CODE)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_ICMP_CODE, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_ICMP_CODE, addr_family.IP6)
|
||||
class FlowSpecIcmpCode(_FlowSpecNumeric):
|
||||
"""ICMP code Flow Specification NLRI component
|
||||
|
||||
@ -2659,7 +2896,10 @@ class FlowSpecIcmpCode(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'icmp_code'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_TCP_FLAGS)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_TCP_FLAGS, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_TCP_FLAGS, addr_family.IP6)
|
||||
class FlowSpecTCPFlags(_FlowSpecBitmask):
|
||||
"""TCP flags for Flow Specification NLRI component
|
||||
|
||||
@ -2694,7 +2934,9 @@ class FlowSpecTCPFlags(_FlowSpecBitmask):
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_PACKET_LENGTH)
|
||||
_FlowSpecIPv4Component.TYPE_PACKET_LENGTH, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_PACKET_LENGTH, addr_family.IP6)
|
||||
class FlowSpecPacketLen(_FlowSpecNumeric):
|
||||
"""Packet length for Flow Specification NLRI component
|
||||
|
||||
@ -2704,7 +2946,9 @@ class FlowSpecPacketLen(_FlowSpecNumeric):
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_DIFFSERV_CODE_POINT)
|
||||
_FlowSpecIPv4Component.TYPE_DIFFSERV_CODE_POINT, addr_family.IP)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_DIFFSERV_CODE_POINT, addr_family.IP6)
|
||||
class FlowSpecDSCP(_FlowSpecNumeric):
|
||||
"""Diffserv Code Point for Flow Specification NLRI component
|
||||
|
||||
@ -2713,7 +2957,8 @@ class FlowSpecDSCP(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'dscp'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_FRAGMENT)
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv4Component.TYPE_FRAGMENT, addr_family.IP)
|
||||
class FlowSpecFragment(_FlowSpecBitmask):
|
||||
"""Fragment for Flow Specification NLRI component
|
||||
|
||||
@ -2749,6 +2994,43 @@ class FlowSpecFragment(_FlowSpecBitmask):
|
||||
_bitmask_flags[DF] = 'DF'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_FRAGMENT, addr_family.IP6)
|
||||
class FlowSpecIPv6Fragment(_FlowSpecBitmask):
|
||||
"""Fragment for Flow Specification for IPv6 NLRI component
|
||||
|
||||
========== ===============================================
|
||||
Attribute Description
|
||||
========== ===============================================
|
||||
LF Last fragment
|
||||
FF First fragment
|
||||
ISF Is a fragment
|
||||
========== ===============================================
|
||||
"""
|
||||
COMPONENT_NAME = 'fragment'
|
||||
|
||||
# bitmask format
|
||||
# 0 1 2 3 4 5 6 7
|
||||
# +---+---+---+---+---+---+---+---+
|
||||
# | Reserved |LF |FF |IsF| 0 |
|
||||
# +---+---+---+---+---+---+---+---+
|
||||
|
||||
LF = 1 << 3
|
||||
FF = 1 << 2
|
||||
ISF = 1 << 1
|
||||
|
||||
_bitmask_flags = collections.OrderedDict()
|
||||
_bitmask_flags[LF] = 'LF'
|
||||
_bitmask_flags[FF] = 'FF'
|
||||
_bitmask_flags[ISF] = 'ISF'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecIPv6Component.TYPE_FLOW_LABEL, addr_family.IP6)
|
||||
class FlowSpecIPv6FlowLabel(_FlowSpecNumeric):
|
||||
COMPONENT_NAME = 'flow_label'
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class RouteTargetMembershipNLRI(StringifyMixin):
|
||||
"""Route Target Membership NLRI.
|
||||
@ -2860,7 +3142,9 @@ _ADDR_CLASSES = {
|
||||
_addr_class_key(RF_IPv6_VPN): LabelledVPNIP6AddrPrefix,
|
||||
_addr_class_key(RF_L2_EVPN): EvpnNLRI,
|
||||
_addr_class_key(RF_IPv4_FLOWSPEC): FlowSpecIPv4NLRI,
|
||||
_addr_class_key(RF_IPv6_FLOWSPEC): FlowSpecIPv6NLRI,
|
||||
_addr_class_key(RF_VPNv4_FLOWSPEC): FlowSpecVPNv4NLRI,
|
||||
_addr_class_key(RF_VPNv6_FLOWSPEC): FlowSpecVPNv6NLRI,
|
||||
_addr_class_key(RF_RTC_UC): RouteTargetMembershipNLRI,
|
||||
}
|
||||
|
||||
@ -4077,6 +4361,9 @@ class BGPFlowSpecTrafficMarkingCommunity(_ExtendedCommunity):
|
||||
return struct.pack(self._VALUE_PACK_STR, self.subtype, self.dscp)
|
||||
|
||||
|
||||
# TODO
|
||||
# Implement "Redirect-IPv6" [draft-ietf-idr-flow-spec-v6-08]
|
||||
|
||||
@_ExtendedCommunity.register_unknown_type()
|
||||
class BGPUnknownExtendedCommunity(_ExtendedCommunity):
|
||||
_VALUE_PACK_STR = '!7s' # opaque value
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user