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. */
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
;
359 struct listnode
*bgpnode
;
361 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
362 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
363 if (sockunion_family(&peer
->su
) != AF_INET
)
366 if (sockunion2ip(&peer
->su
) == src
->s_addr
)
374 static struct peer
*bgp_peer_lookup_next(struct in_addr
*src
)
378 struct peer
*next_peer
= NULL
;
379 struct listnode
*node
;
380 struct listnode
*bgpnode
;
382 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
383 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
384 if (sockunion_family(&peer
->su
) != AF_INET
)
386 if (ntohl(sockunion2ip(&peer
->su
)) <= ntohl(src
->s_addr
))
390 || ntohl(sockunion2ip(&next_peer
->su
))
391 > ntohl(sockunion2ip(&peer
->su
))) {
398 src
->s_addr
= sockunion2ip(&next_peer
->su
);
405 /* 1.3.6.1.2.1.15.3.1.x = 10 */
406 #define PEERTAB_NAMELEN 10
408 static struct peer
*bgpPeerTable_lookup(struct variable
*v
, oid name
[],
409 size_t *length
, struct in_addr
*addr
,
412 struct peer
*peer
= NULL
;
413 size_t namelen
= v
? v
->namelen
: PEERTAB_NAMELEN
;
417 /* Check the length. */
418 if (*length
- namelen
!= sizeof(struct in_addr
))
421 oid2in_addr(name
+ namelen
, IN_ADDR_SIZE
, addr
);
423 peer
= peer_lookup_addr_ipv4(addr
);
426 len
= *length
- namelen
;
430 oid2in_addr(name
+ namelen
, len
, addr
);
432 peer
= bgp_peer_lookup_next(addr
);
437 oid_copy_addr(name
+ namelen
, addr
, sizeof(struct in_addr
));
438 *length
= sizeof(struct in_addr
) + namelen
;
445 /* BGP write methods. */
446 static int write_bgpPeerTable(int action
, uint8_t *var_val
,
447 uint8_t var_val_type
, size_t var_val_len
,
448 uint8_t *statP
, oid
*name
, size_t length
)
454 if (var_val_type
!= ASN_INTEGER
) {
455 return SNMP_ERR_WRONGTYPE
;
457 if (var_val_len
!= sizeof(long)) {
458 return SNMP_ERR_WRONGLENGTH
;
461 intval
= *(long *)var_val
;
463 memset(&addr
, 0, sizeof(struct in_addr
));
465 peer
= bgpPeerTable_lookup(NULL
, name
, &length
, &addr
, 1);
467 return SNMP_ERR_NOSUCHNAME
;
469 if (action
!= SNMP_MSG_INTERNAL_SET_COMMIT
)
470 return SNMP_ERR_NOERROR
;
472 zlog_info("%s: SNMP write .%ld = %ld", peer
->host
,
473 (long)name
[PEERTAB_NAMELEN
- 1], intval
);
475 switch (name
[PEERTAB_NAMELEN
- 1]) {
476 case BGPPEERADMINSTATUS
:
477 #define BGP_PeerAdmin_stop 1
478 #define BGP_PeerAdmin_start 2
479 /* When the peer is established, */
480 if (intval
== BGP_PeerAdmin_stop
)
481 BGP_EVENT_ADD(peer
, BGP_Stop
);
482 else if (intval
== BGP_PeerAdmin_start
)
485 return SNMP_ERR_NOSUCHNAME
;
487 case BGPPEERCONNECTRETRYINTERVAL
:
488 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
489 peer
->connect
= intval
;
490 peer
->v_connect
= intval
;
492 case BGPPEERHOLDTIMECONFIGURED
:
493 peer_flag_set(peer
, PEER_FLAG_TIMER
);
494 peer
->holdtime
= intval
;
495 peer
->v_holdtime
= intval
;
497 case BGPPEERKEEPALIVECONFIGURED
:
498 peer_flag_set(peer
, PEER_FLAG_TIMER
);
499 peer
->keepalive
= intval
;
500 peer
->v_keepalive
= intval
;
502 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
503 peer
->v_routeadv
= intval
;
506 return SNMP_ERR_NOERROR
;
509 static uint8_t *bgpPeerTable(struct variable
*v
, oid name
[], size_t *length
,
510 int exact
, size_t *var_len
,
511 WriteMethod
**write_method
)
513 static struct in_addr addr
;
517 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
520 memset(&addr
, 0, sizeof(struct in_addr
));
522 peer
= bgpPeerTable_lookup(v
, name
, length
, &addr
, exact
);
527 case BGPPEERIDENTIFIER
:
528 return SNMP_IPADDRESS(peer
->remote_id
);
530 return SNMP_INTEGER(peer
->status
);
531 case BGPPEERADMINSTATUS
:
532 *write_method
= write_bgpPeerTable
;
533 #define BGP_PeerAdmin_stop 1
534 #define BGP_PeerAdmin_start 2
535 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
536 return SNMP_INTEGER(BGP_PeerAdmin_stop
);
538 return SNMP_INTEGER(BGP_PeerAdmin_start
);
539 case BGPPEERNEGOTIATEDVERSION
:
540 return SNMP_INTEGER(BGP_VERSION_4
);
541 case BGPPEERLOCALADDR
:
543 return SNMP_IPADDRESS(peer
->su_local
->sin
.sin_addr
);
545 return SNMP_IPADDRESS(bgp_empty_addr
);
546 case BGPPEERLOCALPORT
:
549 ntohs(peer
->su_local
->sin
.sin_port
));
551 return SNMP_INTEGER(0);
552 case BGPPEERREMOTEADDR
:
554 return SNMP_IPADDRESS(peer
->su_remote
->sin
.sin_addr
);
556 return SNMP_IPADDRESS(bgp_empty_addr
);
557 case BGPPEERREMOTEPORT
:
560 ntohs(peer
->su_remote
->sin
.sin_port
));
562 return SNMP_INTEGER(0);
563 case BGPPEERREMOTEAS
:
564 return SNMP_INTEGER(peer
->as
);
565 case BGPPEERINUPDATES
:
566 ui
= atomic_load_explicit(&peer
->update_in
,
567 memory_order_relaxed
);
568 return SNMP_INTEGER(ui
);
569 case BGPPEEROUTUPDATES
:
570 uo
= atomic_load_explicit(&peer
->update_out
,
571 memory_order_relaxed
);
572 return SNMP_INTEGER(uo
);
573 case BGPPEERINTOTALMESSAGES
:
574 return SNMP_INTEGER(PEER_TOTAL_RX(peer
));
575 case BGPPEEROUTTOTALMESSAGES
:
576 return SNMP_INTEGER(PEER_TOTAL_TX(peer
));
577 case BGPPEERLASTERROR
: {
578 static uint8_t lasterror
[2];
579 lasterror
[0] = peer
->notify
.code
;
580 lasterror
[1] = peer
->notify
.subcode
;
582 return (uint8_t *)&lasterror
;
584 case BGPPEERFSMESTABLISHEDTRANSITIONS
:
585 return SNMP_INTEGER(peer
->established
);
586 case BGPPEERFSMESTABLISHEDTIME
:
587 if (peer
->uptime
== 0)
588 return SNMP_INTEGER(0);
590 return SNMP_INTEGER(bgp_clock() - peer
->uptime
);
591 case BGPPEERCONNECTRETRYINTERVAL
:
592 *write_method
= write_bgpPeerTable
;
593 return SNMP_INTEGER(peer
->v_connect
);
594 case BGPPEERHOLDTIME
:
595 return SNMP_INTEGER(peer
->v_holdtime
);
596 case BGPPEERKEEPALIVE
:
597 return SNMP_INTEGER(peer
->v_keepalive
);
598 case BGPPEERHOLDTIMECONFIGURED
:
599 *write_method
= write_bgpPeerTable
;
600 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
601 return SNMP_INTEGER(peer
->holdtime
);
603 return SNMP_INTEGER(peer
->v_holdtime
);
604 case BGPPEERKEEPALIVECONFIGURED
:
605 *write_method
= write_bgpPeerTable
;
606 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
607 return SNMP_INTEGER(peer
->keepalive
);
609 return SNMP_INTEGER(peer
->v_keepalive
);
610 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
611 *write_method
= write_bgpPeerTable
;
612 return SNMP_INTEGER(peer
->v_routeadv
);
613 case BGPPEERINUPDATEELAPSEDTIME
:
614 if (peer
->update_time
== 0)
615 return SNMP_INTEGER(0);
617 return SNMP_INTEGER(bgp_clock() - peer
->update_time
);
624 static uint8_t *bgpIdentifier(struct variable
*v
, oid name
[], size_t *length
,
625 int exact
, size_t *var_len
,
626 WriteMethod
**write_method
)
630 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
634 bgp
= bgp_get_default();
638 return SNMP_IPADDRESS(bgp
->router_id
);
641 static uint8_t *bgpRcvdPathAttrTable(struct variable
*v
, oid name
[],
642 size_t *length
, int exact
, size_t *var_len
,
643 WriteMethod
**write_method
)
645 /* Received Path Attribute Table. This table contains, one entry
646 per path to a network, path attributes received from all peers
647 running BGP version 3 or less. This table is obsolete, having
648 been replaced in functionality with the bgp4PathAttrTable. */
652 static struct bgp_path_info
*bgp4PathAttrLookup(struct variable
*v
, oid name
[],
653 size_t *length
, struct bgp
*bgp
,
654 struct prefix_ipv4
*addr
,
659 struct bgp_path_info
*path
;
660 struct bgp_path_info
*min
;
661 struct bgp_dest
*dest
;
664 struct in_addr paddr
;
668 #define BGP_PATHATTR_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
671 if (*length
- v
->namelen
!= BGP_PATHATTR_ENTRY_OFFSET
)
674 /* Set OID offset for prefix. */
675 offset
= name
+ v
->namelen
;
676 oid2in_addr(offset
, IN_ADDR_SIZE
, &addr
->prefix
);
677 offset
+= IN_ADDR_SIZE
;
680 addr
->prefixlen
= *offset
;
684 su
.sin
.sin_family
= AF_INET
;
685 oid2in_addr(offset
, IN_ADDR_SIZE
, &su
.sin
.sin_addr
);
688 dest
= bgp_node_lookup(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
689 (struct prefix
*)addr
);
691 bgp_dest_unlock_node(dest
);
693 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
695 if (sockunion_same(&path
->peer
->su
, &su
))
699 offset
= name
+ v
->namelen
;
700 offsetlen
= *length
- v
->namelen
;
704 dest
= bgp_table_top(bgp
->rib
[AFI_IP
][SAFI_UNICAST
]);
706 if (len
> IN_ADDR_SIZE
)
709 oid2in_addr(offset
, len
, &addr
->prefix
);
711 offset
+= IN_ADDR_SIZE
;
712 offsetlen
-= IN_ADDR_SIZE
;
715 addr
->prefixlen
= *offset
;
717 addr
->prefixlen
= len
* 8;
719 dest
= bgp_node_get(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
720 (struct prefix
*)addr
);
728 if (len
> IN_ADDR_SIZE
)
731 oid2in_addr(offset
, len
, &paddr
);
733 paddr
.s_addr
= INADDR_ANY
;
741 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
743 if (path
->peer
->su
.sin
.sin_family
== AF_INET
744 && ntohl(paddr
.s_addr
)
745 < ntohl(path
->peer
->su
.sin
749 if (ntohl(path
->peer
->su
.sin
752 < ntohl(min
->peer
->su
.sin
762 const struct prefix
*rn_p
=
763 bgp_dest_get_prefix(dest
);
766 v
->namelen
+ BGP_PATHATTR_ENTRY_OFFSET
;
768 offset
= name
+ v
->namelen
;
769 oid_copy_addr(offset
, &rn_p
->u
.prefix4
,
771 offset
+= IN_ADDR_SIZE
;
772 *offset
= rn_p
->prefixlen
;
774 oid_copy_addr(offset
,
775 &min
->peer
->su
.sin
.sin_addr
,
777 addr
->prefix
= rn_p
->u
.prefix4
;
778 addr
->prefixlen
= rn_p
->prefixlen
;
780 bgp_dest_unlock_node(dest
);
785 paddr
.s_addr
= INADDR_ANY
;
786 } while ((dest
= bgp_route_next(dest
)) != NULL
);
791 static uint8_t *bgp4PathAttrTable(struct variable
*v
, oid name
[],
792 size_t *length
, int exact
, size_t *var_len
,
793 WriteMethod
**write_method
)
796 struct bgp_path_info
*path
;
797 struct prefix_ipv4 addr
;
799 bgp
= bgp_get_default();
803 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
806 memset(&addr
, 0, sizeof(struct prefix_ipv4
));
808 path
= bgp4PathAttrLookup(v
, name
, length
, bgp
, &addr
, exact
);
813 case BGP4PATHATTRPEER
: /* 1 */
814 return SNMP_IPADDRESS(path
->peer
->su
.sin
.sin_addr
);
815 case BGP4PATHATTRIPADDRPREFIXLEN
: /* 2 */
816 return SNMP_INTEGER(addr
.prefixlen
);
817 case BGP4PATHATTRIPADDRPREFIX
: /* 3 */
818 return SNMP_IPADDRESS(addr
.prefix
);
819 case BGP4PATHATTRORIGIN
: /* 4 */
820 return SNMP_INTEGER(path
->attr
->origin
);
821 case BGP4PATHATTRASPATHSEGMENT
: /* 5 */
822 return aspath_snmp_pathseg(path
->attr
->aspath
, var_len
);
823 case BGP4PATHATTRNEXTHOP
: /* 6 */
824 return SNMP_IPADDRESS(path
->attr
->nexthop
);
825 case BGP4PATHATTRMULTIEXITDISC
: /* 7 */
826 return SNMP_INTEGER(path
->attr
->med
);
827 case BGP4PATHATTRLOCALPREF
: /* 8 */
828 return SNMP_INTEGER(path
->attr
->local_pref
);
829 case BGP4PATHATTRATOMICAGGREGATE
: /* 9 */
830 return SNMP_INTEGER(1);
831 case BGP4PATHATTRAGGREGATORAS
: /* 10 */
832 return SNMP_INTEGER(path
->attr
->aggregator_as
);
833 case BGP4PATHATTRAGGREGATORADDR
: /* 11 */
834 return SNMP_IPADDRESS(path
->attr
->aggregator_addr
);
835 case BGP4PATHATTRCALCLOCALPREF
: /* 12 */
836 return SNMP_INTEGER(-1);
837 case BGP4PATHATTRBEST
: /* 13 */
838 #define BGP4_PathAttrBest_false 1
839 #define BGP4_PathAttrBest_true 2
840 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
841 return SNMP_INTEGER(BGP4_PathAttrBest_true
);
843 return SNMP_INTEGER(BGP4_PathAttrBest_false
);
844 case BGP4PATHATTRUNKNOWN
: /* 14 */
852 static struct trap_object bgpTrapList
[] = {{3, {3, 1, BGPPEERLASTERROR
}},
853 {3, {3, 1, BGPPEERSTATE
}}};
855 static int bgpTrapEstablished(struct peer
*peer
)
859 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
861 /* Check if this peer just went to Established */
862 if ((peer
->ostatus
!= OpenConfirm
) || !(peer_established(peer
)))
865 ret
= inet_aton(peer
->host
, &addr
);
869 oid_copy_addr(index
, &addr
, IN_ADDR_SIZE
);
871 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
872 array_size(bgp_trap_oid
), bgp_oid
,
873 sizeof(bgp_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
,
874 bgpTrapList
, array_size(bgpTrapList
), BGPESTABLISHED
);
878 static int bgpTrapBackwardTransition(struct peer
*peer
)
882 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
884 ret
= inet_aton(peer
->host
, &addr
);
888 oid_copy_addr(index
, &addr
, IN_ADDR_SIZE
);
890 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
891 array_size(bgp_trap_oid
), bgp_oid
,
892 sizeof(bgp_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
,
893 bgpTrapList
, array_size(bgpTrapList
), BGPBACKWARDTRANSITION
);
897 static int bgp_snmp_init(struct thread_master
*tm
)
900 REGISTER_MIB("mibII/bgp", bgp_variables
, variable
, bgp_oid
);
904 static int bgp_snmp_module_init(void)
906 hook_register(peer_status_changed
, bgpTrapEstablished
);
907 hook_register(peer_backward_transition
, bgpTrapBackwardTransition
);
908 hook_register(frr_late_init
, bgp_snmp_init
);
912 FRR_MODULE_SETUP(.name
= "bgpd_snmp", .version
= FRR_VERSION
,
913 .description
= "bgpd AgentX SNMP module",
914 .init
= bgp_snmp_module_init
)