Signed-off-by: ISHIDA Wataru <[email protected]>
---
 ryu/lib/packet/bgp/__init__.py |  131 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 130 insertions(+), 1 deletion(-)

diff --git a/ryu/lib/packet/bgp/__init__.py b/ryu/lib/packet/bgp/__init__.py
index 50c9571..8a5907b 100644
--- a/ryu/lib/packet/bgp/__init__.py
+++ b/ryu/lib/packet/bgp/__init__.py
@@ -25,6 +25,7 @@ RFC 4271 BGP-4
 import abc
 import six
 import struct
+import copy
 
 from ryu.ofproto.ofproto_parser import msg_pack_into
 from ryu.lib.stringify import StringifyMixin
@@ -120,6 +121,10 @@ BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16  # RFC 4360
 BGP_ATTR_TYPE_AS4_PATH = 17  # RFC 4893
 BGP_ATTR_TYPE_AS4_AGGREGATOR = 18  # RFC 4893
 
+BGP_ATTR_ORIGIN_IGP = 0x00
+BGP_ATTR_ORIGIN_EGP = 0x01
+BGP_ATTR_ORIGIN_INCOMPLETE = 0x02
+
 AS_TRANS = 23456  # RFC 4893
 
 # Well known commmunities  (RFC 1997)
@@ -647,6 +652,9 @@ class BGPOptParamCapabilityUnknown(_OptParamCapability):
 class BGPOptParamCapabilityRouteRefresh(_OptParamEmptyCapability):
     pass
 
+@_OptParamCapability.register_type(BGP_CAP_ENHANCED_ROUTE_REFRESH)
+class BGPOptParamCapabilityEnhancedRouteRefresh(_OptParamEmptyCapability):
+    pass
 
 @_OptParamCapability.register_type(BGP_CAP_FOUR_OCTET_AS_NUMBER)
 class BGPOptParamCapabilityFourOctetAsNumber(_OptParamCapability):
@@ -787,6 +795,41 @@ class _BGPPathAttributeAsPathCommon(_PathAttribute):
     _AS_PACK_STR = None
     _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE
 
+    @property
+    def path_seg_list(self):
+        return copy.deepcopy(self.value)
+
+    def get_as_path_len(self):
+        count = 0
+        for seg in self.value:
+            if isinstance(seg, list):
+                # Segment type 2 stored in list and all AS counted.
+                count += len(seg)
+            else:
+                # Segment type 1 stored in set and count as one.
+                count += 1
+
+        return count
+
+    def has_local_as(self, local_as):
+        """Check if *local_as* is already present on path list."""
+        for as_path_seg in self.value:
+            for as_num in as_path_seg:
+                if as_num == local_as:
+                    return True
+        return False
+
+    def has_matching_leftmost(self, remote_as):
+        """Check if leftmost AS matches *remote_as*."""
+        if not self.value or not remote_as:
+            return False
+
+        leftmost_seg = self.path_seg_list[0]
+        if leftmost_seg and leftmost_seg[0] == remote_as:
+            return True
+
+        return False
+
     @classmethod
     def parse_value(cls, buf):
         result = []
@@ -940,6 +983,12 @@ class BGPPathAttributeCommunities(_PathAttribute):
     _VALUE_PACK_STR = '!I'
     _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE
 
+    # String constants of well-known-communities
+    NO_EXPORT = int('0xFFFFFF01', 16)
+    NO_ADVERTISE = int('0xFFFFFF02', 16)
+    NO_EXPORT_SUBCONFED = int('0xFFFFFF03', 16)
+    WELL_KNOW_COMMUNITIES = (NO_EXPORT, NO_ADVERTISE, NO_EXPORT_SUBCONFED)
+
     def __init__(self, communities,
                  flags=0, type_=None, length=None):
         super(BGPPathAttributeCommunities, self).__init__(flags=flags,
@@ -968,6 +1017,36 @@ class BGPPathAttributeCommunities(_PathAttribute):
             buf += bincomm
         return buf
 
+    @staticmethod
+    def is_no_export(comm_attr):
+        """Returns True if given value matches well-known community NO_EXPORT
+         attribute value.
+         """
+        return comm_attr == Community.NO_EXPORT
+
+    @staticmethod
+    def is_no_advertise(comm_attr):
+        """Returns True if given value matches well-known community
+        NO_ADVERTISE attribute value.
+        """
+        return comm_attr == Community.NO_ADVERTISE
+
+    @staticmethod
+    def is_no_export_subconfed(comm_attr):
+        """Returns True if given value matches well-known community
+         NO_EXPORT_SUBCONFED attribute value.
+         """
+        return comm_attr == Community.NO_EXPORT_SUBCONFED
+
+    def has_comm_attr(self, attr):
+        """Returns True if given community attribute is present."""
+
+        for comm_attr in self.communities:
+            if comm_attr == attr:
+                return True
+
+        return False
+
 
 # Extended Communities
 # RFC 4360
@@ -1424,6 +1503,8 @@ class BGPUpdate(BGPMessage):
     ========================== ===============================================
     """
 
+    _MIN_LEN = BGPMessage._HDR_LEN
+
     def __init__(self, type_=BGP_MSG_UPDATE,
                  withdrawn_routes_len=None,
                  withdrawn_routes=[],
@@ -1435,9 +1516,18 @@ class BGPUpdate(BGPMessage):
         self.withdrawn_routes_len = withdrawn_routes_len
         self.withdrawn_routes = withdrawn_routes
         self.total_path_attribute_len = total_path_attribute_len
-        self.path_attributes = path_attributes
+        self.pathattr_map = {}
+        for attr in path_attributes:
+            self.pathattr_map[attr.type] = attr
         self.nlri = nlri
 
+    @property
+    def path_attributes(self):
+        return self.pathattr_map.values()
+
+    def get_path_attr(self, attr_name):
+        return self.pathattr_map.get(attr_name)
+
     @classmethod
     def parser(cls, buf):
         offset = 0
@@ -1554,6 +1644,41 @@ class BGPNotification(BGPMessage):
     _PACK_STR = '!BB'
     _MIN_LEN = BGPMessage._HDR_LEN + struct.calcsize(_PACK_STR)
 
+    _REASONS = {
+        (1, 1): 'Message Header Error: not synchronised',
+        (1, 2): 'Message Header Error: bad message len',
+        (1, 3): 'Message Header Error: bad message type',
+        (2, 1): 'Open Message Error: unsupported version',
+        (2, 2): 'Open Message Error: bad peer AS',
+        (2, 3): 'Open Message Error: bad BGP identifier',
+        (2, 4): 'Open Message Error: unsupported optional param',
+        (2, 5): 'Open Message Error: authentication failure',
+        (2, 6): 'Open Message Error: unacceptable hold time',
+        (2, 7): 'Open Message Error: Unsupported Capability',
+        (2, 8): 'Open Message Error: Unassigned',
+        (3, 1): 'Update Message Error: malformed attribute list',
+        (3, 2): 'Update Message Error: unrecognized well-known attr',
+        (3, 3): 'Update Message Error: missing well-known attr',
+        (3, 4): 'Update Message Error: attribute flags error',
+        (3, 5): 'Update Message Error: attribute length error',
+        (3, 6): 'Update Message Error: invalid origin attr',
+        (3, 7): 'Update Message Error: as routing loop',
+        (3, 8): 'Update Message Error: invalid next hop attr',
+        (3, 9): 'Update Message Error: optional attribute error',
+        (3, 10): 'Update Message Error: invalid network field',
+        (3, 11): 'Update Message Error: malformed AS_PATH',
+        (4, 1): 'Hold Timer Expired',
+        (5, 1): 'Finite State Machine Error',
+        (6, 1): 'Cease: Maximum Number of Prefixes Reached',
+        (6, 2): 'Cease: Administrative Shutdown',
+        (6, 3): 'Cease: Peer De-configured',
+        (6, 4): 'Cease: Administrative Reset',
+        (6, 5): 'Cease: Connection Rejected',
+        (6, 6): 'Cease: Other Configuration Change',
+        (6, 7): 'Cease: Connection Collision Resolution',
+        (6, 8): 'Cease: Out of Resources',
+    }
+
     def __init__(self,
                  error_code,
                  error_subcode,
@@ -1582,6 +1707,10 @@ class BGPNotification(BGPMessage):
         msg += self.data
         return msg
 
+    @property
+    def reason(self):
+        return self._REASONS.get((self.error_code, self.error_subcode))
+
 
 @BGPMessage.register_type(BGP_MSG_ROUTE_REFRESH)
 class BGPRouteRefresh(BGPMessage):
-- 
1.7.9.5


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to