diff options
author | Shinpei Muraoka <shinpei.muraoka@gmail.com> | 2017-03-24 17:10:45 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-03-28 10:00:03 +0900 |
commit | 765a723fe6c846473ced0f909cf839db8a61dbb8 (patch) | |
tree | 1816df969b1bfb923c7302435881f7c7c6fc3471 | |
parent | f12485e6de514f8a9af9317347150f6018accc0e (diff) |
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>
-rw-r--r-- | ryu/lib/packet/bgp.py | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py index 1a5bd65e..454a3f66 100644 --- a/ryu/lib/packet/bgp.py +++ b/ryu/lib/packet/bgp.py @@ -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__() |