2 * Copyright (C) 1999, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <net-snmp/net-snmp-config.h>
24 #include <net-snmp/net-snmp-includes.h>
37 #include "bgpd/bgpd.h"
38 #include "bgpd/bgp_table.h"
39 #include "bgpd/bgp_aspath.h"
40 #include "bgpd/bgp_attr.h"
41 #include "bgpd/bgp_route.h"
42 #include "bgpd/bgp_fsm.h"
44 /* BGP4-MIB described in RFC1657. */
45 #define BGP4MIB 1,3,6,1,2,1,15
48 #define BGPESTABLISHED 1
49 #define BGPBACKWARDTRANSITION 2
51 /* BGP MIB bgpVersion. */
54 /* BGP MIB bgpLocalAs. */
57 /* BGP MIB bgpPeerTable. */
58 #define BGPPEERIDENTIFIER 1
59 #define BGPPEERSTATE 2
60 #define BGPPEERADMINSTATUS 3
61 #define BGPPEERNEGOTIATEDVERSION 4
62 #define BGPPEERLOCALADDR 5
63 #define BGPPEERLOCALPORT 6
64 #define BGPPEERREMOTEADDR 7
65 #define BGPPEERREMOTEPORT 8
66 #define BGPPEERREMOTEAS 9
67 #define BGPPEERINUPDATES 10
68 #define BGPPEEROUTUPDATES 11
69 #define BGPPEERINTOTALMESSAGES 12
70 #define BGPPEEROUTTOTALMESSAGES 13
71 #define BGPPEERLASTERROR 14
72 #define BGPPEERFSMESTABLISHEDTRANSITIONS 15
73 #define BGPPEERFSMESTABLISHEDTIME 16
74 #define BGPPEERCONNECTRETRYINTERVAL 17
75 #define BGPPEERHOLDTIME 18
76 #define BGPPEERKEEPALIVE 19
77 #define BGPPEERHOLDTIMECONFIGURED 20
78 #define BGPPEERKEEPALIVECONFIGURED 21
79 #define BGPPEERMINROUTEADVERTISEMENTINTERVAL 22
80 #define BGPPEERINUPDATEELAPSEDTIME 23
82 /* BGP MIB bgpIdentifier. */
83 #define BGPIDENTIFIER 0
85 /* BGP MIB bgpRcvdPathAttrTable */
86 #define BGPPATHATTRPEER 1
87 #define BGPPATHATTRDESTNETWORK 2
88 #define BGPPATHATTRORIGIN 3
89 #define BGPPATHATTRASPATH 4
90 #define BGPPATHATTRNEXTHOP 5
91 #define BGPPATHATTRINTERASMETRIC 6
93 /* BGP MIB bgp4PathAttrTable. */
94 #define BGP4PATHATTRPEER 1
95 #define BGP4PATHATTRIPADDRPREFIXLEN 2
96 #define BGP4PATHATTRIPADDRPREFIX 3
97 #define BGP4PATHATTRORIGIN 4
98 #define BGP4PATHATTRASPATHSEGMENT 5
99 #define BGP4PATHATTRNEXTHOP 6
100 #define BGP4PATHATTRMULTIEXITDISC 7
101 #define BGP4PATHATTRLOCALPREF 8
102 #define BGP4PATHATTRATOMICAGGREGATE 9
103 #define BGP4PATHATTRAGGREGATORAS 10
104 #define BGP4PATHATTRAGGREGATORADDR 11
105 #define BGP4PATHATTRCALCLOCALPREF 12
106 #define BGP4PATHATTRBEST 13
107 #define BGP4PATHATTRUNKNOWN 14
109 /* SNMP value hack. */
110 #define INTEGER ASN_INTEGER
111 #define INTEGER32 ASN_INTEGER
112 #define COUNTER32 ASN_COUNTER
113 #define OCTET_STRING ASN_OCTET_STR
114 #define IPADDRESS ASN_IPADDRESS
115 #define GAUGE32 ASN_UNSIGNED
117 /* Declare static local variables for convenience. */
120 /* BGP-MIB instances. */
121 static oid bgp_oid
[] = {BGP4MIB
};
122 static oid bgp_trap_oid
[] = {BGP4MIB
, 0};
124 /* IP address 0.0.0.0. */
125 static struct in_addr bgp_empty_addr
= {.s_addr
= 0};
127 /* Hook functions. */
128 static uint8_t *bgpVersion(struct variable
*, oid
[], size_t *, int, size_t *,
130 static uint8_t *bgpLocalAs(struct variable
*, oid
[], size_t *, int, size_t *,
132 static uint8_t *bgpPeerTable(struct variable
*, oid
[], size_t *, int, size_t *,
134 static uint8_t *bgpRcvdPathAttrTable(struct variable
*, oid
[], size_t *, int,
135 size_t *, WriteMethod
**);
136 static uint8_t *bgpIdentifier(struct variable
*, oid
[], size_t *, int, size_t *,
138 static uint8_t *bgp4PathAttrTable(struct variable
*, oid
[], size_t *, int,
139 size_t *, WriteMethod
**);
140 /* static uint8_t *bgpTraps (); */
142 static struct variable bgp_variables
[] = {
144 {BGPVERSION
, OCTET_STRING
, RONLY
, bgpVersion
, 1, {1}},
146 {BGPLOCALAS
, INTEGER
, RONLY
, bgpLocalAs
, 1, {2}},
147 /* BGP peer table. */
148 {BGPPEERIDENTIFIER
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 1}},
149 {BGPPEERSTATE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 2}},
150 {BGPPEERADMINSTATUS
, INTEGER
, RWRITE
, bgpPeerTable
, 3, {3, 1, 3}},
151 {BGPPEERNEGOTIATEDVERSION
,
157 {BGPPEERLOCALADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 5}},
158 {BGPPEERLOCALPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 6}},
159 {BGPPEERREMOTEADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 7}},
160 {BGPPEERREMOTEPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 8}},
161 {BGPPEERREMOTEAS
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 9}},
162 {BGPPEERINUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 10}},
163 {BGPPEEROUTUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 11}},
164 {BGPPEERINTOTALMESSAGES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 12}},
165 {BGPPEEROUTTOTALMESSAGES
,
171 {BGPPEERLASTERROR
, OCTET_STRING
, RONLY
, bgpPeerTable
, 3, {3, 1, 14}},
172 {BGPPEERFSMESTABLISHEDTRANSITIONS
,
178 {BGPPEERFSMESTABLISHEDTIME
,
184 {BGPPEERCONNECTRETRYINTERVAL
,
190 {BGPPEERHOLDTIME
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 18}},
191 {BGPPEERKEEPALIVE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 19}},
192 {BGPPEERHOLDTIMECONFIGURED
,
198 {BGPPEERKEEPALIVECONFIGURED
,
204 {BGPPEERMINROUTEADVERTISEMENTINTERVAL
,
210 {BGPPEERINUPDATEELAPSEDTIME
,
216 /* BGP identifier. */
217 {BGPIDENTIFIER
, IPADDRESS
, RONLY
, bgpIdentifier
, 1, {4}},
218 /* BGP received path attribute table. */
219 {BGPPATHATTRPEER
, IPADDRESS
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 1}},
220 {BGPPATHATTRDESTNETWORK
,
223 bgpRcvdPathAttrTable
,
226 {BGPPATHATTRORIGIN
, INTEGER
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 3}},
230 bgpRcvdPathAttrTable
,
236 bgpRcvdPathAttrTable
,
239 {BGPPATHATTRINTERASMETRIC
,
242 bgpRcvdPathAttrTable
,
245 /* BGP-4 received path attribute table. */
246 {BGP4PATHATTRPEER
, IPADDRESS
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 1}},
247 {BGP4PATHATTRIPADDRPREFIXLEN
,
253 {BGP4PATHATTRIPADDRPREFIX
,
259 {BGP4PATHATTRORIGIN
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 4}},
260 {BGP4PATHATTRASPATHSEGMENT
,
266 {BGP4PATHATTRNEXTHOP
,
272 {BGP4PATHATTRMULTIEXITDISC
,
278 {BGP4PATHATTRLOCALPREF
,
284 {BGP4PATHATTRATOMICAGGREGATE
,
290 {BGP4PATHATTRAGGREGATORAS
,
296 {BGP4PATHATTRAGGREGATORADDR
,
302 {BGP4PATHATTRCALCLOCALPREF
,
308 {BGP4PATHATTRBEST
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 13}},
309 {BGP4PATHATTRUNKNOWN
,
318 static uint8_t *bgpVersion(struct variable
*v
, oid name
[], size_t *length
,
319 int exact
, size_t *var_len
,
320 WriteMethod
**write_method
)
322 static uint8_t version
;
324 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
328 /* Retrun BGP version. Zebra bgpd only support version 4. */
329 version
= (0x80 >> (BGP_VERSION_4
- 1));
331 /* Return octet string length 1. */
333 return (uint8_t *)&version
;
336 static uint8_t *bgpLocalAs(struct variable
*v
, oid name
[], size_t *length
,
337 int exact
, size_t *var_len
,
338 WriteMethod
**write_method
)
342 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
346 /* Get BGP structure. */
347 bgp
= bgp_get_default();
351 return SNMP_INTEGER(bgp
->as
);
354 static struct peer
*peer_lookup_addr_ipv4(struct in_addr
*src
)
358 struct listnode
*node
;
360 bgp
= bgp_get_default();
364 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
365 if (sockunion_family(&peer
->su
) != AF_INET
)
368 if (sockunion2ip(&peer
->su
) == src
->s_addr
)
375 static struct peer
*bgp_peer_lookup_next(struct in_addr
*src
)
379 struct peer
*next_peer
= NULL
;
380 struct listnode
*node
;
382 bgp
= bgp_get_default();
386 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
387 if (sockunion_family(&peer
->su
) != AF_INET
)
389 if (ntohl(sockunion2ip(&peer
->su
)) <= ntohl(src
->s_addr
))
393 || ntohl(sockunion2ip(&next_peer
->su
))
394 > ntohl(sockunion2ip(&peer
->su
))) {
400 src
->s_addr
= sockunion2ip(&next_peer
->su
);
407 /* 1.3.6.1.2.1.15.3.1.x = 10 */
408 #define PEERTAB_NAMELEN 10
410 static struct peer
*bgpPeerTable_lookup(struct variable
*v
, oid name
[],
411 size_t *length
, struct in_addr
*addr
,
414 struct peer
*peer
= NULL
;
415 size_t namelen
= v
? v
->namelen
: PEERTAB_NAMELEN
;
419 /* Check the length. */
420 if (*length
- namelen
!= sizeof(struct in_addr
))
423 oid2in_addr(name
+ namelen
, IN_ADDR_SIZE
, addr
);
425 peer
= peer_lookup_addr_ipv4(addr
);
428 len
= *length
- namelen
;
432 oid2in_addr(name
+ namelen
, len
, addr
);
434 peer
= bgp_peer_lookup_next(addr
);
439 oid_copy_addr(name
+ namelen
, addr
, sizeof(struct in_addr
));
440 *length
= sizeof(struct in_addr
) + namelen
;
447 /* BGP write methods. */
448 static int write_bgpPeerTable(int action
, uint8_t *var_val
,
449 uint8_t var_val_type
, size_t var_val_len
,
450 uint8_t *statP
, oid
*name
, size_t length
)
456 if (var_val_type
!= ASN_INTEGER
) {
457 return SNMP_ERR_WRONGTYPE
;
459 if (var_val_len
!= sizeof(long)) {
460 return SNMP_ERR_WRONGLENGTH
;
463 intval
= *(long *)var_val
;
465 memset(&addr
, 0, sizeof(struct in_addr
));
467 peer
= bgpPeerTable_lookup(NULL
, name
, &length
, &addr
, 1);
469 return SNMP_ERR_NOSUCHNAME
;
471 if (action
!= SNMP_MSG_INTERNAL_SET_COMMIT
)
472 return SNMP_ERR_NOERROR
;
474 zlog_info("%s: SNMP write .%ld = %ld", peer
->host
,
475 (long)name
[PEERTAB_NAMELEN
- 1], intval
);
477 switch (name
[PEERTAB_NAMELEN
- 1]) {
478 case BGPPEERADMINSTATUS
:
479 #define BGP_PeerAdmin_stop 1
480 #define BGP_PeerAdmin_start 2
481 /* When the peer is established, */
482 if (intval
== BGP_PeerAdmin_stop
)
483 BGP_EVENT_ADD(peer
, BGP_Stop
);
484 else if (intval
== BGP_PeerAdmin_start
)
487 return SNMP_ERR_NOSUCHNAME
;
489 case BGPPEERCONNECTRETRYINTERVAL
:
490 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
491 peer
->connect
= intval
;
492 peer
->v_connect
= intval
;
494 case BGPPEERHOLDTIMECONFIGURED
:
495 peer_flag_set(peer
, PEER_FLAG_TIMER
);
496 peer
->holdtime
= intval
;
497 peer
->v_holdtime
= intval
;
499 case BGPPEERKEEPALIVECONFIGURED
:
500 peer_flag_set(peer
, PEER_FLAG_TIMER
);
501 peer
->keepalive
= intval
;
502 peer
->v_keepalive
= intval
;
504 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
505 peer
->v_routeadv
= intval
;
508 return SNMP_ERR_NOERROR
;
511 static uint8_t *bgpPeerTable(struct variable
*v
, oid name
[], size_t *length
,
512 int exact
, size_t *var_len
,
513 WriteMethod
**write_method
)
515 static struct in_addr addr
;
519 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
522 memset(&addr
, 0, sizeof(struct in_addr
));
524 peer
= bgpPeerTable_lookup(v
, name
, length
, &addr
, exact
);
529 case BGPPEERIDENTIFIER
:
530 return SNMP_IPADDRESS(peer
->remote_id
);
533 return SNMP_INTEGER(peer
->status
);
535 case BGPPEERADMINSTATUS
:
536 *write_method
= write_bgpPeerTable
;
537 #define BGP_PeerAdmin_stop 1
538 #define BGP_PeerAdmin_start 2
539 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
540 return SNMP_INTEGER(BGP_PeerAdmin_stop
);
542 return SNMP_INTEGER(BGP_PeerAdmin_start
);
544 case BGPPEERNEGOTIATEDVERSION
:
545 return SNMP_INTEGER(BGP_VERSION_4
);
547 case BGPPEERLOCALADDR
:
549 return SNMP_IPADDRESS(peer
->su_local
->sin
.sin_addr
);
551 return SNMP_IPADDRESS(bgp_empty_addr
);
553 case BGPPEERLOCALPORT
:
556 ntohs(peer
->su_local
->sin
.sin_port
));
558 return SNMP_INTEGER(0);
560 case BGPPEERREMOTEADDR
:
562 return SNMP_IPADDRESS(peer
->su_remote
->sin
.sin_addr
);
564 return SNMP_IPADDRESS(bgp_empty_addr
);
566 case BGPPEERREMOTEPORT
:
569 ntohs(peer
->su_remote
->sin
.sin_port
));
571 return SNMP_INTEGER(0);
573 case BGPPEERREMOTEAS
:
574 return SNMP_INTEGER(peer
->as
);
576 case BGPPEERINUPDATES
:
577 ui
= atomic_load_explicit(&peer
->update_in
,
578 memory_order_relaxed
);
579 return SNMP_INTEGER(ui
);
581 case BGPPEEROUTUPDATES
:
582 uo
= atomic_load_explicit(&peer
->update_out
,
583 memory_order_relaxed
);
584 return SNMP_INTEGER(uo
);
586 case BGPPEERINTOTALMESSAGES
:
587 return SNMP_INTEGER(PEER_TOTAL_RX(peer
));
589 case BGPPEEROUTTOTALMESSAGES
:
590 return SNMP_INTEGER(PEER_TOTAL_TX(peer
));
592 case BGPPEERLASTERROR
: {
593 static uint8_t lasterror
[2];
594 lasterror
[0] = peer
->notify
.code
;
595 lasterror
[1] = peer
->notify
.subcode
;
597 return (uint8_t *)&lasterror
;
599 case BGPPEERFSMESTABLISHEDTRANSITIONS
:
600 return SNMP_INTEGER(peer
->established
);
602 case BGPPEERFSMESTABLISHEDTIME
:
603 if (peer
->uptime
== 0)
604 return SNMP_INTEGER(0);
606 return SNMP_INTEGER(bgp_clock() - peer
->uptime
);
608 case BGPPEERCONNECTRETRYINTERVAL
:
609 *write_method
= write_bgpPeerTable
;
610 return SNMP_INTEGER(peer
->v_connect
);
612 case BGPPEERHOLDTIME
:
613 return SNMP_INTEGER(peer
->v_holdtime
);
615 case BGPPEERKEEPALIVE
:
616 return SNMP_INTEGER(peer
->v_keepalive
);
618 case BGPPEERHOLDTIMECONFIGURED
:
619 *write_method
= write_bgpPeerTable
;
620 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
621 return SNMP_INTEGER(peer
->holdtime
);
623 return SNMP_INTEGER(peer
->v_holdtime
);
625 case BGPPEERKEEPALIVECONFIGURED
:
626 *write_method
= write_bgpPeerTable
;
627 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
628 return SNMP_INTEGER(peer
->keepalive
);
630 return SNMP_INTEGER(peer
->v_keepalive
);
632 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
633 *write_method
= write_bgpPeerTable
;
634 return SNMP_INTEGER(peer
->v_routeadv
);
636 case BGPPEERINUPDATEELAPSEDTIME
:
637 if (peer
->update_time
== 0)
638 return SNMP_INTEGER(0);
640 return SNMP_INTEGER(bgp_clock() - peer
->update_time
);
649 static uint8_t *bgpIdentifier(struct variable
*v
, oid name
[], size_t *length
,
650 int exact
, size_t *var_len
,
651 WriteMethod
**write_method
)
655 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
659 bgp
= bgp_get_default();
663 return SNMP_IPADDRESS(bgp
->router_id
);
666 static uint8_t *bgpRcvdPathAttrTable(struct variable
*v
, oid name
[],
667 size_t *length
, int exact
, size_t *var_len
,
668 WriteMethod
**write_method
)
670 /* Received Path Attribute Table. This table contains, one entry
671 per path to a network, path attributes received from all peers
672 running BGP version 3 or less. This table is obsolete, having
673 been replaced in functionality with the bgp4PathAttrTable. */
677 static struct bgp_path_info
*bgp4PathAttrLookup(struct variable
*v
, oid name
[],
678 size_t *length
, struct bgp
*bgp
,
679 struct prefix_ipv4
*addr
,
684 struct bgp_path_info
*path
;
685 struct bgp_path_info
*min
;
689 struct in_addr paddr
;
693 #define BGP_PATHATTR_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
696 if (*length
- v
->namelen
!= BGP_PATHATTR_ENTRY_OFFSET
)
699 /* Set OID offset for prefix. */
700 offset
= name
+ v
->namelen
;
701 oid2in_addr(offset
, IN_ADDR_SIZE
, &addr
->prefix
);
702 offset
+= IN_ADDR_SIZE
;
705 addr
->prefixlen
= *offset
;
709 su
.sin
.sin_family
= AF_INET
;
710 oid2in_addr(offset
, IN_ADDR_SIZE
, &su
.sin
.sin_addr
);
713 rn
= bgp_node_lookup(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
714 (struct prefix
*)addr
);
718 for (path
= bgp_node_get_bgp_path_info(rn
); path
;
720 if (sockunion_same(&path
->peer
->su
, &su
))
724 offset
= name
+ v
->namelen
;
725 offsetlen
= *length
- v
->namelen
;
729 rn
= bgp_table_top(bgp
->rib
[AFI_IP
][SAFI_UNICAST
]);
731 if (len
> IN_ADDR_SIZE
)
734 oid2in_addr(offset
, len
, &addr
->prefix
);
736 offset
+= IN_ADDR_SIZE
;
737 offsetlen
-= IN_ADDR_SIZE
;
740 addr
->prefixlen
= *offset
;
742 addr
->prefixlen
= len
* 8;
744 rn
= bgp_node_get(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
745 (struct prefix
*)addr
);
753 if (len
> IN_ADDR_SIZE
)
756 oid2in_addr(offset
, len
, &paddr
);
766 for (path
= bgp_node_get_bgp_path_info(rn
); path
;
768 if (path
->peer
->su
.sin
.sin_family
== AF_INET
769 && ntohl(paddr
.s_addr
)
770 < ntohl(path
->peer
->su
.sin
774 if (ntohl(path
->peer
->su
.sin
777 < ntohl(min
->peer
->su
.sin
788 v
->namelen
+ BGP_PATHATTR_ENTRY_OFFSET
;
790 offset
= name
+ v
->namelen
;
791 oid_copy_addr(offset
, &rn
->p
.u
.prefix4
,
793 offset
+= IN_ADDR_SIZE
;
794 *offset
= rn
->p
.prefixlen
;
796 oid_copy_addr(offset
,
797 &min
->peer
->su
.sin
.sin_addr
,
799 addr
->prefix
= rn
->p
.u
.prefix4
;
800 addr
->prefixlen
= rn
->p
.prefixlen
;
808 } while ((rn
= bgp_route_next(rn
)) != NULL
);
813 static uint8_t *bgp4PathAttrTable(struct variable
*v
, oid name
[],
814 size_t *length
, int exact
, size_t *var_len
,
815 WriteMethod
**write_method
)
818 struct bgp_path_info
*path
;
819 struct prefix_ipv4 addr
;
821 bgp
= bgp_get_default();
825 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
828 memset(&addr
, 0, sizeof(struct prefix_ipv4
));
830 path
= bgp4PathAttrLookup(v
, name
, length
, bgp
, &addr
, exact
);
835 case BGP4PATHATTRPEER
: /* 1 */
836 return SNMP_IPADDRESS(path
->peer
->su
.sin
.sin_addr
);
838 case BGP4PATHATTRIPADDRPREFIXLEN
: /* 2 */
839 return SNMP_INTEGER(addr
.prefixlen
);
841 case BGP4PATHATTRIPADDRPREFIX
: /* 3 */
842 return SNMP_IPADDRESS(addr
.prefix
);
844 case BGP4PATHATTRORIGIN
: /* 4 */
845 return SNMP_INTEGER(path
->attr
->origin
);
847 case BGP4PATHATTRASPATHSEGMENT
: /* 5 */
848 return aspath_snmp_pathseg(path
->attr
->aspath
, var_len
);
850 case BGP4PATHATTRNEXTHOP
: /* 6 */
851 return SNMP_IPADDRESS(path
->attr
->nexthop
);
853 case BGP4PATHATTRMULTIEXITDISC
: /* 7 */
854 return SNMP_INTEGER(path
->attr
->med
);
856 case BGP4PATHATTRLOCALPREF
: /* 8 */
857 return SNMP_INTEGER(path
->attr
->local_pref
);
859 case BGP4PATHATTRATOMICAGGREGATE
: /* 9 */
860 return SNMP_INTEGER(1);
862 case BGP4PATHATTRAGGREGATORAS
: /* 10 */
863 return SNMP_INTEGER(path
->attr
->aggregator_as
);
865 case BGP4PATHATTRAGGREGATORADDR
: /* 11 */
866 return SNMP_IPADDRESS(path
->attr
->aggregator_addr
);
868 case BGP4PATHATTRCALCLOCALPREF
: /* 12 */
869 return SNMP_INTEGER(-1);
871 case BGP4PATHATTRBEST
: /* 13 */
872 #define BGP4_PathAttrBest_false 1
873 #define BGP4_PathAttrBest_true 2
874 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
875 return SNMP_INTEGER(BGP4_PathAttrBest_true
);
877 return SNMP_INTEGER(BGP4_PathAttrBest_false
);
879 case BGP4PATHATTRUNKNOWN
: /* 14 */
888 static struct trap_object bgpTrapList
[] = {{3, {3, 1, BGPPEERLASTERROR
}},
889 {3, {3, 1, BGPPEERSTATE
}}};
891 static int bgpTrapEstablished(struct peer
*peer
)
895 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
897 ret
= inet_aton(peer
->host
, &addr
);
901 oid_copy_addr(index
, &addr
, IN_ADDR_SIZE
);
903 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
904 array_size(bgp_trap_oid
), bgp_oid
,
905 sizeof bgp_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
,
906 bgpTrapList
, array_size(bgpTrapList
), BGPESTABLISHED
);
910 static int bgpTrapBackwardTransition(struct peer
*peer
)
914 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
916 ret
= inet_aton(peer
->host
, &addr
);
920 oid_copy_addr(index
, &addr
, IN_ADDR_SIZE
);
922 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
923 array_size(bgp_trap_oid
), bgp_oid
,
924 sizeof bgp_oid
/ sizeof(oid
), index
, IN_ADDR_SIZE
,
925 bgpTrapList
, array_size(bgpTrapList
), BGPBACKWARDTRANSITION
);
929 static int bgp_snmp_init(struct thread_master
*tm
)
932 REGISTER_MIB("mibII/bgp", bgp_variables
, variable
, bgp_oid
);
936 static int bgp_snmp_module_init(void)
938 hook_register(peer_established
, bgpTrapEstablished
);
939 hook_register(peer_backward_transition
, bgpTrapBackwardTransition
);
940 hook_register(frr_late_init
, bgp_snmp_init
);
944 FRR_MODULE_SETUP(.name
= "bgpd_snmp", .version
= FRR_VERSION
,
945 .description
= "bgpd AgentX SNMP module",
946 .init
= bgp_snmp_module_init
)