summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/lib/packet/bmp.py49
-rw-r--r--ryu/tests/unit/packet/test_bmp.py21
2 files changed, 56 insertions, 14 deletions
diff --git a/ryu/lib/packet/bmp.py b/ryu/lib/packet/bmp.py
index 0b4c3b84..1320dd2e 100644
--- a/ryu/lib/packet/bmp.py
+++ b/ryu/lib/packet/bmp.py
@@ -60,6 +60,8 @@ BMP_STAT_TYPE_INV_UPDATE_DUE_TO_ORIGINATOR_ID = 5
BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP = 6
BMP_STAT_TYPE_ADJ_RIB_IN = 7
BMP_STAT_TYPE_LOC_RIB = 8
+BMP_STAT_TYPE_ADJ_RIB_OUT = 14
+BMP_STAT_TYPE_EXPORT_RIB = 15
BMP_PEER_DOWN_REASON_UNKNOWN = 0
BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION = 1
@@ -157,7 +159,8 @@ class BMPPeerMessage(BMPMessage):
type Type field. one of BMP\_MSG\_ constants.
peer_type The type of the peer.
is_post_policy Indicate the message reflects the post-policy
- Adj-RIB-In
+ is_adj_rib_out Indicate the message reflects Adj-RIB-Out (defaults
+ to Adj-RIB-In)
peer_distinguisher Use for L3VPN router which can have multiple
instance.
peer_address The remote IP address associated with the TCP
@@ -179,12 +182,13 @@ class BMPPeerMessage(BMPMessage):
def __init__(self, peer_type, is_post_policy, peer_distinguisher,
peer_address, peer_as, peer_bgp_id, timestamp,
- version=VERSION, type_=None, len_=None):
+ version=VERSION, type_=None, len_=None, is_adj_rib_out=False):
super(BMPPeerMessage, self).__init__(version=version,
len_=len_,
type_=type_)
self.peer_type = peer_type
self.is_post_policy = is_post_policy
+ self.is_adj_rib_out = is_adj_rib_out
self.peer_distinguisher = peer_distinguisher
self.peer_address = peer_address
self.peer_as = peer_as
@@ -200,6 +204,11 @@ class BMPPeerMessage(BMPMessage):
rest = buf[struct.calcsize(cls._PEER_HDR_PACK_STR):]
+ if peer_flags & (1 << 4):
+ is_adj_rib_out = True
+ else:
+ is_adj_rib_out = False
+
if peer_flags & (1 << 6):
is_post_policy = True
else:
@@ -221,12 +230,16 @@ class BMPPeerMessage(BMPMessage):
"peer_address": peer_address,
"peer_as": peer_as,
"peer_bgp_id": peer_bgp_id,
- "timestamp": timestamp
+ "timestamp": timestamp,
+ "is_adj_rib_out": is_adj_rib_out,
}, rest
def serialize_tail(self):
flags = 0
+ if self.is_adj_rib_out:
+ flags |= (1 << 4)
+
if self.is_post_policy:
flags |= (1 << 6)
@@ -275,7 +288,7 @@ class BMPRouteMonitoring(BMPPeerMessage):
def __init__(self, bgp_update, peer_type, is_post_policy,
peer_distinguisher, peer_address, peer_as, peer_bgp_id,
timestamp, version=VERSION, type_=BMP_MSG_ROUTE_MONITORING,
- len_=None):
+ len_=None, is_adj_rib_out=False):
super(BMPRouteMonitoring,
self).__init__(peer_type=peer_type,
is_post_policy=is_post_policy,
@@ -286,7 +299,8 @@ class BMPRouteMonitoring(BMPPeerMessage):
timestamp=timestamp,
len_=len_,
type_=type_,
- version=version)
+ version=version,
+ is_adj_rib_out=is_adj_rib_out)
self.bgp_update = bgp_update
@classmethod
@@ -335,7 +349,8 @@ class BMPStatisticsReport(BMPPeerMessage):
def __init__(self, stats, peer_type, is_post_policy, peer_distinguisher,
peer_address, peer_as, peer_bgp_id, timestamp,
- version=VERSION, type_=BMP_MSG_STATISTICS_REPORT, len_=None):
+ version=VERSION, type_=BMP_MSG_STATISTICS_REPORT, len_=None,
+ is_adj_rib_out=False):
super(BMPStatisticsReport,
self).__init__(peer_type=peer_type,
is_post_policy=is_post_policy,
@@ -346,7 +361,8 @@ class BMPStatisticsReport(BMPPeerMessage):
timestamp=timestamp,
len_=len_,
type_=type_,
- version=version)
+ version=version,
+ is_adj_rib_out=is_adj_rib_out)
self.stats = stats
@classmethod
@@ -381,7 +397,9 @@ class BMPStatisticsReport(BMPPeerMessage):
type_ == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP:
value, = struct.unpack_from('!I', six.binary_type(value))
elif type_ == BMP_STAT_TYPE_ADJ_RIB_IN or \
- type_ == BMP_STAT_TYPE_LOC_RIB:
+ type_ == BMP_STAT_TYPE_LOC_RIB or \
+ type_ == BMP_STAT_TYPE_ADJ_RIB_OUT or \
+ type_ == BMP_STAT_TYPE_EXPORT_RIB:
value, = struct.unpack_from('!Q', six.binary_type(value))
buf = buf[cls._MIN_LEN + len_:]
@@ -410,7 +428,9 @@ class BMPStatisticsReport(BMPPeerMessage):
t == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP:
valuepackstr = 'I'
elif t == BMP_STAT_TYPE_ADJ_RIB_IN or \
- t == BMP_STAT_TYPE_LOC_RIB:
+ t == BMP_STAT_TYPE_LOC_RIB or \
+ t == BMP_STAT_TYPE_ADJ_RIB_OUT or \
+ t == BMP_STAT_TYPE_EXPORT_RIB:
valuepackstr = 'Q'
else:
continue
@@ -440,7 +460,8 @@ class BMPPeerDownNotification(BMPPeerMessage):
def __init__(self, reason, data, peer_type, is_post_policy,
peer_distinguisher, peer_address, peer_as, peer_bgp_id,
timestamp, version=VERSION,
- type_=BMP_MSG_PEER_DOWN_NOTIFICATION, len_=None):
+ type_=BMP_MSG_PEER_DOWN_NOTIFICATION, len_=None,
+ is_adj_rib_out=False):
super(BMPPeerDownNotification,
self).__init__(peer_type=peer_type,
@@ -452,7 +473,8 @@ class BMPPeerDownNotification(BMPPeerMessage):
timestamp=timestamp,
len_=len_,
type_=type_,
- version=version)
+ version=version,
+ is_adj_rib_out=is_adj_rib_out)
self.reason = reason
self.data = data
@@ -537,7 +559,7 @@ class BMPPeerUpNotification(BMPPeerMessage):
peer_type, is_post_policy, peer_distinguisher,
peer_address, peer_as, peer_bgp_id, timestamp,
version=VERSION, type_=BMP_MSG_PEER_UP_NOTIFICATION,
- len_=None):
+ len_=None, is_adj_rib_out=False):
super(BMPPeerUpNotification,
self).__init__(peer_type=peer_type,
is_post_policy=is_post_policy,
@@ -548,7 +570,8 @@ class BMPPeerUpNotification(BMPPeerMessage):
timestamp=timestamp,
len_=len_,
type_=type_,
- version=version)
+ version=version,
+ is_adj_rib_out=is_adj_rib_out)
self.local_address = local_address
self.local_port = local_port
self.remote_port = remote_port
diff --git a/ryu/tests/unit/packet/test_bmp.py b/ryu/tests/unit/packet/test_bmp.py
index f93b8014..d0bffecf 100644
--- a/ryu/tests/unit/packet/test_bmp.py
+++ b/ryu/tests/unit/packet/test_bmp.py
@@ -54,12 +54,31 @@ class Test_bmp(unittest.TestCase):
eq_(msg.to_jsondict(), msg2.to_jsondict())
eq_(rest, b'')
+ def test_route_monitoring_adj_rib_out(self):
+ update = bgp.BGPUpdate()
+ msg = bmp.BMPRouteMonitoring(bgp_update=update,
+ peer_type=bmp.BMP_PEER_TYPE_GLOBAL,
+ is_post_policy=True,
+ is_adj_rib_out=True,
+ peer_distinguisher=0,
+ peer_address='192.0.2.1',
+ peer_as=30000,
+ peer_bgp_id='192.0.2.1',
+ timestamp=self._time())
+ binmsg = msg.serialize()
+ msg2, rest = bmp.BMPMessage.parser(binmsg)
+ eq_(msg.to_jsondict(), msg2.to_jsondict())
+ eq_(rest, b'')
+
def test_statistics_report(self):
stats = [{'type': bmp.BMP_STAT_TYPE_REJECTED, 'value': 100},
{'type': bmp.BMP_STAT_TYPE_DUPLICATE_PREFIX, 'value': 200},
{'type': bmp.BMP_STAT_TYPE_DUPLICATE_WITHDRAW, 'value': 300},
{'type': bmp.BMP_STAT_TYPE_ADJ_RIB_IN, 'value': 100000},
- {'type': bmp.BMP_STAT_TYPE_LOC_RIB, 'value': 500000}]
+ {'type': bmp.BMP_STAT_TYPE_LOC_RIB, 'value': 500000},
+ {'type': bmp.BMP_STAT_TYPE_ADJ_RIB_OUT, 'value': 95000},
+ {'type': bmp.BMP_STAT_TYPE_EXPORT_RIB, 'value': 50000},
+ {'type': bmp.BMP_STAT_TYPE_EXPORT_RIB, 'value': 50000}]
msg = bmp.BMPStatisticsReport(stats=stats,
peer_type=bmp.BMP_PEER_TYPE_GLOBAL,
is_post_policy=True,