This feature has worked fine in CSR1000v(bmpclient) as below.

(1) result of displaying in bmpstation

$ ryu-manager bmpstation.py
loading app bmpstation.py
instantiating app bmpstation.py of BMPStation

...(snip)

2015 Apr 04 08:02:51 | 192.168.10.1 | 65010,10.0.0.3 | 
BMPRouteMonitoring={'path_attributes': {'ORIGIN': '?', 'MULTI_EXIT_DISC': 100, 
'AS_PATH': [[65010]], 'MP_REACH_NLRI': {'nexthop': '192.168.101.101', 'nlri': 
[{'prefix': '192.168.1.0/30', 'label_list': [31], 'route_dist': '65010:101'}, 
{'prefix': '192.168.2.0/30', 'label_list': [32], 'route_dist': '65010:101'}]}, 
'EXTENDED_COMMUNITIES': ['65010:101']}, 'received_time': '1970/01/01 09:00:00', 
'message_type': 'BGP_Update'}

2015 Apr 04 08:02:51 | 192.168.10.1 | 65010,10.0.0.3 | 
BMPRouteMonitoring={'path_attributes': {'ORIGIN': '?', 'MULTI_EXIT_DISC': 100, 
'AS_PATH': [[65010, 65001]], 'MP_REACH_NLRI': {'nexthop': '192.168.101.101', 
'nlri': [{'prefix': '0.0.0.0/0', 'label_list': [30], 'route_dist': 
'65010:101'}]}, 'EXTENDED_COMMUNITIES': ['65010:101']}, 'received_time': 
'1970/01/01 09:00:00', 'message_type': 'BGP_Update'}

(2) show routing tables in bmpclient

CSR1000v#sh bgp vpnv4 unicast all
BGP table version is 417, local router ID is 10.0.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 65010:101 (default for vrf customer1)
 *>  0.0.0.0          192.168.101.101        100             0 65010 65001 ?
 *>  10.0.0.3/32      0.0.0.0                  0         32768 ?
 *>  192.168.1.0/30   192.168.101.101        100             0 65010 ?
 *>  192.168.2.0/30   192.168.101.101        100             0 65010 ?

Signed-off-by: Toshiki Tsuboi <[email protected]>
---
 ryu/app/bmpstation.py | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git a/ryu/app/bmpstation.py b/ryu/app/bmpstation.py
index ce31309..c60a1ce 100644
--- a/ryu/app/bmpstation.py
+++ b/ryu/app/bmpstation.py
@@ -22,6 +22,20 @@ from ryu.base import app_manager
 from ryu.lib import hub
 from ryu.lib.hub import StreamServer
 from ryu.lib.packet import bmp
+from ryu.lib.packet import bgp
+
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_NEXT_HOP
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_COMMUNITIES
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MP_REACH_NLRI
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MP_UNREACH_NLRI
+from ryu.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES
+from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP
+from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP
+from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE
 
 
 class BMPStation(app_manager.RyuApp):
@@ -89,6 +103,7 @@ class BMPStation(app_manager.RyuApp):
                                                                msg))
                     self.output_fd.flush()
                     buf = rest
+                    self.print_BMP(msg, addr, t)
 
                 required_len = bmp.BMPMessage._HDR_LEN
 
@@ -96,3 +111,176 @@ class BMPStation(app_manager.RyuApp):
                           addr[1])
 
         sock.close()
+
+    def print_BMP(self, msg, addr, t):
+        if isinstance(msg, bmp.BMPInitiation):
+            self.logger.info("%s | %s | BMPInitiation\n", t, addr[0])
+        elif isinstance(msg, bmp.BMPPeerUpNotification):
+            bmp_result = self.print_BMPPeerUpNotification(msg, addr)
+            self.logger.info("%s | %s | %s,%s | BMPPeerUpNotification=%s\n",
+                             t, addr[0], msg.peer_as, msg.peer_bgp_id,
+                             bmp_result)
+        elif isinstance(msg, bmp.BMPRouteMonitoring):
+            bmp_result = self.print_BMPRouteMonitoring(msg, addr)
+            self.logger.info("%s | %s | %s,%s | BMPRouteMonitoring=%s\n",
+                             t, addr[0], msg.peer_as, msg.peer_bgp_id,
+                             bmp_result)
+        elif isinstance(msg, bmp.BMPPeerDownNotification):
+            bmp_result = self.print_BMPPeerDownNotification(msg, addr)
+            self.logger.info("%s | %s | %s,%s | BMPPeerDownNotification=%s\n",
+                             t, addr[0], msg.peer_as, msg.peer_bgp_id,
+                             bmp_result)
+
+    def print_BMPPeerUpNotification(self, msg, addr):
+        bmp_result = {}
+        bgp_t = time.strftime("%Y/%m/%d %H:%M:%S",
+                              time.localtime(int(msg.timestamp)))
+        bmp_result['received_time'] = bgp_t
+        bmp_result['message_type'] = "PeerUpNotification"
+        return bmp_result
+
+    def print_BMPPeerDownNotification(self, msg, addr):
+        bmp_result = {}
+        bgp_t = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
+        bmp_result['received_time'] = bgp_t
+        bmp_result['message_type'] = "PeerDownNotification"
+        return bmp_result
+
+    def print_BMPRouteMonitoring(self, msg, addr):
+        bgp_t = time.strftime("%Y/%m/%d %H:%M:%S",
+                              time.localtime(int(msg.timestamp)))
+        if isinstance(msg.bgp_update, bgp.BGPRouteRefresh):
+            result = self.extract_BGP_RouteRefresh(msg, addr, bgp_t)
+        elif isinstance(msg.bgp_update, bgp.BGPUpdate):
+            result = self.extract_BGP_Update(msg, addr, bgp_t)
+        return result
+
+    def extract_BGP_RouteRefresh(self, msg, addr, bgp_t):
+        bmp_result = {}
+        bmp_result['received_time'] = bgp_t
+        bmp_result['message_type'] = "BGP_RouteRefresh"
+        return bmp_result
+
+    def extract_BGP_Update(self, msg, addr, bgp_t):
+        bmp_result = {}
+        bmp_result['received_time'] = bgp_t
+        update_msg = msg.bgp_update
+        if msg.bgp_update.withdrawn_routes:
+            bmp_result = self.extract_bgp4_withdraw(update_msg, bmp_result)
+        elif msg.bgp_update.nlri:
+            bmp_result = self.extract_bgp4_nlri(update_msg, bmp_result)
+        else:
+            bmp_result = self.extract_PathAttributes(update_msg, bmp_result)
+
+        return bmp_result
+
+    def extract_bgp4_withdraw(self, update_msg, bmp_result):
+        # Path Attributes #
+        bmp_result = self.extract_PathAttributes(update_msg, bmp_result)
+
+        # Withdrawn Routes #
+        del_nlri_list = []
+        for del_nlri in update_msg.withdrawn_routes:
+            nlri = {}
+            nlri['prefix'] = del_nlri.prefix
+            del_nlri_list.append(nlri)
+        bmp_result['Withdrawn Routes'] = del_nlri_list
+        bmp_result['message_type'] = "BGP_Update(withdraw)"
+
+        return bmp_result
+
+    def extract_bgp4_nlri(self, update_msg, bmp_result):
+        # Path Attributes #
+        bmp_result = self.extract_PathAttributes(update_msg, bmp_result)
+
+        # NLRI #
+        add_nlri_list = []
+        for add_nlri in update_msg.nlri:
+            nlri = {}
+            nlri['prefix'] = add_nlri.prefix
+            add_nlri_list.append(nlri)
+        bmp_result['NLRI'] = add_nlri_list
+        bmp_result['message_type'] = "BGP_Update"
+
+        return bmp_result
+
+    def extract_PathAttributes(self, update_msg, bmp_result):
+        path_attributes = {}
+        # ORIGIN #
+        origin = update_msg.get_path_attr(BGP_ATTR_TYPE_ORIGIN)
+        if origin:
+            if origin.value == BGP_ATTR_ORIGIN_IGP:
+                origin_value = 'i'
+            elif origin.value == BGP_ATTR_ORIGIN_EGP:
+                origin_value = 'e'
+            elif origin.value == BGP_ATTR_ORIGIN_INCOMPLETE:
+                origin_value = '?'
+            path_attributes['ORIGIN'] = origin_value
+
+        # AS_PATH #
+        aspath = update_msg.get_path_attr(BGP_ATTR_TYPE_AS_PATH)
+        if aspath:
+            path_attributes['AS_PATH'] = aspath.path_seg_list
+
+        # NEXT_HOP #
+        nexthop = update_msg.get_path_attr(BGP_ATTR_TYPE_NEXT_HOP)
+        if nexthop:
+            path_attributes['NEXT_HOP'] = nexthop.value
+
+        # MULTI_EXIT_DISC #
+        med = update_msg.get_path_attr(BGP_ATTR_TYPE_MULTI_EXIT_DISC)
+        if med:
+            path_attributes['MULTI_EXIT_DISC'] = med.value
+
+        # LOCAL_PREF #
+        localpref = update_msg.get_path_attr(BGP_ATTR_TYPE_LOCAL_PREF)
+        if localpref:
+            path_attributes['LOCAL_PREF'] = localpref.value
+
+        # COMMUNITIES #
+        communities = update_msg.get_path_attr(BGP_ATTR_TYPE_COMMUNITIES)
+        if communities:
+            path_attributes['COMMUNITIES'] = communities.value
+
+        # MP_REACH_NLRI #
+        mp_reach_nlri_attr = update_msg.get_path_attr(
+            BGP_ATTR_TYPE_MP_REACH_NLRI
+        )
+        if mp_reach_nlri_attr:
+            bmp_result['message_type'] = "BGP_Update"
+            mp_reach_nlri = {}
+            add_nlri_list = []
+            for add_nlri in mp_reach_nlri_attr.nlri:
+                nlri = {}
+                nlri['prefix'] = add_nlri.prefix
+                nlri['route_dist'] = add_nlri.route_dist
+                nlri['label_list'] = add_nlri.label_list
+                add_nlri_list.append(nlri)
+            mp_reach_nlri['nexthop'] = mp_reach_nlri_attr.next_hop
+            mp_reach_nlri['nlri'] = add_nlri_list
+            path_attributes['MP_REACH_NLRI'] = mp_reach_nlri
+
+        # MP_UNREACH_NLRI #
+        mp_unreach_nlri_attr = update_msg.get_path_attr(
+            BGP_ATTR_TYPE_MP_UNREACH_NLRI
+        )
+        if mp_unreach_nlri_attr:
+            bmp_result['message_type'] = "BGP_Update(withdraw)"
+            mp_unreach_nlri = {}
+            del_nlri_list = []
+            for del_nlri in mp_unreach_nlri_attr.withdrawn_routes:
+                nlri = {}
+                nlri['prefix'] = del_nlri.prefix
+                nlri['route_dist'] = del_nlri.route_dist
+                nlri['label_list'] = del_nlri.label_list
+                del_nlri_list.append(nlri)
+            mp_unreach_nlri['nlri'] = del_nlri_list
+            path_attributes['MP_UNREACH_NLRI'] = mp_unreach_nlri
+
+        # EXTENDED_COMMUNITIES #
+        extComm = update_msg.get_path_attr(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES)
+        if extComm:
+            path_attributes['EXTENDED_COMMUNITIES'] = extComm.rt_list
+
+        bmp_result['path_attributes'] = path_attributes
+        return bmp_result
-- 
1.9.5 (Apple Git-50.3)
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to