summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYAMAMOTO Takashi <yamamoto@valinux.co.jp>2013-10-22 14:27:29 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2013-10-23 12:04:26 +0900
commit89b2c6aaf16e8145d246e9c44ff757ecd4b8ef7b (patch)
tree68b4b473889768d672c9ffcc65c57dc8bc3ae7c7
parentab6850cc518230956aee5affc90f6b182e7928d6 (diff)
bgp: implement communities attribute
Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/lib/packet/bgp.py36
-rw-r--r--ryu/tests/unit/packet/test_bgp.py5
2 files changed, 40 insertions, 1 deletions
diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index 002e6901..226aeb27 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
@@ -21,7 +21,6 @@ RFC 4271 BGP-4
# todo
# - notify data
# - notify subcode constants
-# - RFC 1997 BGP Communities Attribute
# - RFC 3107 Carrying Label Information in BGP-4
# - RFC 4360 BGP Extended Communities Attribute
# - RFC 4364 BGP/MPLS IP Virtual Private Networks (VPNs)
@@ -72,6 +71,7 @@ BGP_ATTR_TYPE_MULTI_EXIT_DISC = 4 # uint32 metric
BGP_ATTR_TYPE_LOCAL_PREF = 5 # uint32
BGP_ATTR_TYPE_ATOMIC_AGGREGATE = 6 # 0 bytes
BGP_ATTR_TYPE_AGGREGATOR = 7 # AS number and IPv4 address
+BGP_ATTR_TYPE_COMMUNITIES = 8 # RFC 1997
BGP_ATTR_TYPE_MP_REACH_NLRI = 14 # RFC 4760
BGP_ATTR_TYPE_MP_UNREACH_NLRI = 15 # RFC 4760
BGP_ATTR_TYPE_AS4_PATH = 17 # RFC 4893
@@ -584,6 +584,40 @@ class BGPPathAttributeAs4Aggregator(_BGPPathAttributeAggregatorCommon):
_VALUE_PACK_STR = '!I4s'
+@_PathAttribute.register_type(BGP_ATTR_TYPE_COMMUNITIES)
+class BGPPathAttributeCommunities(_PathAttribute):
+ _VALUE_PACK_STR = '!I'
+ _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE
+
+ def __init__(self, communities,
+ flags=0, type_=None, length=None):
+ super(BGPPathAttributeCommunities, self).__init__(flags=flags,
+ type_=type_,
+ length=length)
+ self.communities = communities
+
+ @classmethod
+ def parse_value(cls, buf):
+ rest = buf
+ communities = []
+ elem_size = struct.calcsize(cls._VALUE_PACK_STR)
+ while len(rest) >= elem_size:
+ (comm, ) = struct.unpack_from(cls._VALUE_PACK_STR, buffer(rest))
+ communities.append(comm)
+ rest = rest[elem_size:]
+ return {
+ 'communities': communities,
+ }
+
+ def serialize_value(self):
+ buf = bytearray()
+ for comm in self.communities:
+ bincomm = bytearray()
+ msg_pack_into(self._VALUE_PACK_STR, bincomm, 0, comm)
+ buf += bincomm
+ return buf
+
+
@_PathAttribute.register_type(BGP_ATTR_TYPE_MP_REACH_NLRI)
class BGPPathAttributeMpReachNLRI(_PathAttribute):
_VALUE_PACK_STR = '!HBB' # afi, safi, next hop len
diff --git a/ryu/tests/unit/packet/test_bgp.py b/ryu/tests/unit/packet/test_bgp.py
index f614b212..e2ffc0ba 100644
--- a/ryu/tests/unit/packet/test_bgp.py
+++ b/ryu/tests/unit/packet/test_bgp.py
@@ -81,6 +81,10 @@ class Test_bgp(unittest.TestCase):
bgp._BinAddrPrefix(32, 'efgh\0\0'),
bgp._BinAddrPrefix(16, 'ij\0\0\0\0'),
]
+ communities = [
+ bgp.BGP_COMMUNITY_NO_EXPORT,
+ bgp.BGP_COMMUNITY_NO_ADVERTISE,
+ ]
path_attributes = [
bgp.BGPPathAttributeOrigin(value=1),
bgp.BGPPathAttributeAsPath(value=[[1000], set([1001, 1002]),
@@ -91,6 +95,7 @@ class Test_bgp(unittest.TestCase):
bgp.BGPPathAttributeAtomicAggregate(),
bgp.BGPPathAttributeAggregator(as_number=40000,
addr='192.0.2.99'),
+ bgp.BGPPathAttributeCommunities(communities=communities),
bgp.BGPPathAttributeAs4Path(value=[[1000000], set([1000001, 1002]),
[1003, 1000004]]),
bgp.BGPPathAttributeAs4Aggregator(as_number=100040000,