mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-08 13:56:09 +02:00
packet/bgp: Implement the utility of Flow Specification for BGPSpeaker
Signed-off-by: Shinpei Muraoka <shinpei.muraoka@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
f12485e6de
commit
765a723fe6
@ -24,6 +24,7 @@ RFC 4271 BGP-4
|
||||
|
||||
import abc
|
||||
import base64
|
||||
import collections
|
||||
import copy
|
||||
import functools
|
||||
import io
|
||||
@ -2003,6 +2004,7 @@ class _FlowSpecNLRIBase(StringifyMixin, TypeDisp):
|
||||
_LENGTH_LONG_FMT = '!H'
|
||||
LENGTH_LONG_SIZE = struct.calcsize(_LENGTH_LONG_FMT)
|
||||
_LENGTH_THRESHOLD = 0xf000
|
||||
FLOWSPEC_FAMILY = ''
|
||||
|
||||
def __init__(self, length=0, rules=None):
|
||||
self.length = length
|
||||
@ -2084,12 +2086,36 @@ class _FlowSpecNLRIBase(StringifyMixin, TypeDisp):
|
||||
rules.sort(key=lambda x: x.type)
|
||||
return cls(rules=rules)
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
def _format(i):
|
||||
pairs = []
|
||||
i.rules.sort(key=lambda x: x.type)
|
||||
previous_type = None
|
||||
for r in i.rules:
|
||||
if r.type == previous_type:
|
||||
if r.to_str()[0] != '&':
|
||||
pairs[-1] += '|'
|
||||
pairs[-1] += r.to_str()
|
||||
else:
|
||||
pairs.append('%s:%s' % (r.COMPONENT_NAME, r.to_str()))
|
||||
previous_type = r.type
|
||||
|
||||
return ','.join(pairs)
|
||||
|
||||
return '%s(%s)' % (self.FLOWSPEC_FAMILY, _format(self))
|
||||
|
||||
@property
|
||||
def formatted_nlri_str(self):
|
||||
return self.prefix
|
||||
|
||||
|
||||
class FlowSpecIPv4NLRI(_FlowSpecNLRIBase):
|
||||
"""
|
||||
Flow Specification NLRI class for IPv4 [RFC 5575]
|
||||
"""
|
||||
ROUTE_FAMILY = RF_IPv4_FLOWSPEC
|
||||
FLOWSPEC_FAMILY = 'ipv4fs'
|
||||
|
||||
@classmethod
|
||||
def from_user(cls, **kwargs):
|
||||
@ -2199,6 +2225,7 @@ class FlowSpecVPNv4NLRI(_FlowSpecNLRIBase):
|
||||
# | NLRI value (variable) |
|
||||
# +-----------------------------------+
|
||||
ROUTE_FAMILY = RF_VPNv4_FLOWSPEC
|
||||
FLOWSPEC_FAMILY = 'vpnv4fs'
|
||||
|
||||
def __init__(self, length=0, route_dist=None, rules=None):
|
||||
super(FlowSpecVPNv4NLRI, self).__init__(length, rules)
|
||||
@ -2245,6 +2272,10 @@ class FlowSpecVPNv4NLRI(_FlowSpecNLRIBase):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
@ -2349,6 +2380,13 @@ class _FlowSpecPrefixBase(_FlowSpecComponentBase, IPAddrPrefix):
|
||||
rule.append(cls(int(length), addr))
|
||||
return rule
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return "%s/%s" % (self.addr, self.length)
|
||||
|
||||
def to_str(self):
|
||||
return self.value
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_DESTINATION_PREFIX)
|
||||
@ -2497,6 +2535,20 @@ class _FlowSpecNumeric(_FlowSpecOperatorBase):
|
||||
raise ValueError('Invalid params: %s="%s"' % (
|
||||
cls.COMPONENT_NAME, value))
|
||||
|
||||
def to_str(self):
|
||||
string = ""
|
||||
if self.operator & self.AND:
|
||||
string += "&"
|
||||
|
||||
operator = self.operator & (self.LT | self.GT | self.EQ)
|
||||
for k, v in self._comparison_conditions.items():
|
||||
if operator == v:
|
||||
string += k
|
||||
|
||||
string += str(self.value)
|
||||
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
def normalize_operator(cls, operator):
|
||||
if operator & (cls.LT | cls.GT | cls.EQ):
|
||||
@ -2523,6 +2575,8 @@ class _FlowSpecBitmask(_FlowSpecOperatorBase):
|
||||
'==': MATCH,
|
||||
}
|
||||
|
||||
_bitmask_flags = {}
|
||||
|
||||
@classmethod
|
||||
def _to_value(cls, value):
|
||||
try:
|
||||
@ -2531,6 +2585,24 @@ class _FlowSpecBitmask(_FlowSpecOperatorBase):
|
||||
raise ValueError('Invalid params: %s="%s"' % (
|
||||
cls.COMPONENT_NAME, value))
|
||||
|
||||
def to_str(self):
|
||||
string = ""
|
||||
if self.operator & self.AND:
|
||||
string += "&"
|
||||
|
||||
operator = self.operator & (self.NOT | self.MATCH)
|
||||
for k, v in self._comparison_conditions.items():
|
||||
if operator == v:
|
||||
string += k
|
||||
|
||||
plus = ""
|
||||
for k, v in self._bitmask_flags.items():
|
||||
if self.value & k:
|
||||
string += plus + v
|
||||
plus = "+"
|
||||
|
||||
return string
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(_FlowSpecComponentBase.TYPE_PROTOCOL)
|
||||
class FlowSpecIPProtocol(_FlowSpecNumeric):
|
||||
@ -2610,6 +2682,16 @@ class FlowSpecTCPFlags(_FlowSpecBitmask):
|
||||
SYN = 1 << 1
|
||||
FIN = 1 << 0
|
||||
|
||||
_bitmask_flags = collections.OrderedDict()
|
||||
_bitmask_flags[SYN] = 'SYN'
|
||||
_bitmask_flags[ACK] = 'ACK'
|
||||
_bitmask_flags[FIN] = 'FIN'
|
||||
_bitmask_flags[RST] = 'RST'
|
||||
_bitmask_flags[PUSH] = 'PUSH'
|
||||
_bitmask_flags[URGENT] = 'URGENT'
|
||||
_bitmask_flags[ECN] = 'ECN'
|
||||
_bitmask_flags[CWR] = 'CWR'
|
||||
|
||||
|
||||
@_FlowSpecComponentBase.register_type(
|
||||
_FlowSpecComponentBase.TYPE_PACKET_LENGTH)
|
||||
@ -2660,6 +2742,12 @@ class FlowSpecFragment(_FlowSpecBitmask):
|
||||
ISF = 1 << 1
|
||||
DF = 1 << 0
|
||||
|
||||
_bitmask_flags = collections.OrderedDict()
|
||||
_bitmask_flags[LF] = 'LF'
|
||||
_bitmask_flags[FF] = 'FF'
|
||||
_bitmask_flags[ISF] = 'ISF'
|
||||
_bitmask_flags[DF] = 'DF'
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class RouteTargetMembershipNLRI(StringifyMixin):
|
||||
@ -3870,6 +3958,7 @@ class BGPFlowSpecTrafficRateCommunity(_ExtendedCommunity):
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
_VALUE_PACK_STR = '!BHf'
|
||||
_VALUE_FIELDS = ['subtype', 'as_number', 'rate_info']
|
||||
ACTION_NAME = 'traffic_rate'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(BGPFlowSpecTrafficRateCommunity, self).__init__()
|
||||
@ -3919,6 +4008,7 @@ class BGPFlowSpecTrafficActionCommunity(_ExtendedCommunity):
|
||||
|
||||
_VALUE_PACK_STR = '!B5xB'
|
||||
_VALUE_FIELDS = ['subtype', 'action']
|
||||
ACTION_NAME = 'traffic_action'
|
||||
SAMPLE = 1 << 1
|
||||
TERMINAL = 1 << 0
|
||||
|
||||
@ -3940,6 +4030,7 @@ class BGPFlowSpecRedirectCommunity(BGPTwoOctetAsSpecificExtendedCommunity):
|
||||
local_administrator Local Administrator.
|
||||
========================== ===============================================
|
||||
"""
|
||||
ACTION_NAME = 'redirect'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(BGPTwoOctetAsSpecificExtendedCommunity, self).__init__()
|
||||
@ -3967,6 +4058,7 @@ class BGPFlowSpecTrafficMarkingCommunity(_ExtendedCommunity):
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
_VALUE_PACK_STR = '!B5xB'
|
||||
_VALUE_FIELDS = ['subtype', 'dscp']
|
||||
ACTION_NAME = 'traffic_marking'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(BGPFlowSpecTrafficMarkingCommunity, self).__init__()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user