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>
35 #include "lib/version.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"
43 #include "bgpd/bgp_mplsvpn_snmp.h"
45 /* BGP4-MIB described in RFC1657. */
46 #define BGP4MIB 1,3,6,1,2,1,15
49 #define BGPESTABLISHED 1
50 #define BGPBACKWARDTRANSITION 2
52 /* BGP MIB bgpVersion. */
55 /* BGP MIB bgpLocalAs. */
58 /* BGP MIB bgpPeerTable. */
59 #define BGPPEERIDENTIFIER 1
60 #define BGPPEERSTATE 2
61 #define BGPPEERADMINSTATUS 3
62 #define BGPPEERNEGOTIATEDVERSION 4
63 #define BGPPEERLOCALADDR 5
64 #define BGPPEERLOCALPORT 6
65 #define BGPPEERREMOTEADDR 7
66 #define BGPPEERREMOTEPORT 8
67 #define BGPPEERREMOTEAS 9
68 #define BGPPEERINUPDATES 10
69 #define BGPPEEROUTUPDATES 11
70 #define BGPPEERINTOTALMESSAGES 12
71 #define BGPPEEROUTTOTALMESSAGES 13
72 #define BGPPEERLASTERROR 14
73 #define BGPPEERFSMESTABLISHEDTRANSITIONS 15
74 #define BGPPEERFSMESTABLISHEDTIME 16
75 #define BGPPEERCONNECTRETRYINTERVAL 17
76 #define BGPPEERHOLDTIME 18
77 #define BGPPEERKEEPALIVE 19
78 #define BGPPEERHOLDTIMECONFIGURED 20
79 #define BGPPEERKEEPALIVECONFIGURED 21
80 #define BGPPEERMINROUTEADVERTISEMENTINTERVAL 22
81 #define BGPPEERINUPDATEELAPSEDTIME 23
83 /* BGP MIB bgpIdentifier. */
84 #define BGPIDENTIFIER 0
86 /* BGP MIB bgpRcvdPathAttrTable */
87 #define BGPPATHATTRPEER 1
88 #define BGPPATHATTRDESTNETWORK 2
89 #define BGPPATHATTRORIGIN 3
90 #define BGPPATHATTRASPATH 4
91 #define BGPPATHATTRNEXTHOP 5
92 #define BGPPATHATTRINTERASMETRIC 6
94 /* BGP MIB bgp4PathAttrTable. */
95 #define BGP4PATHATTRPEER 1
96 #define BGP4PATHATTRIPADDRPREFIXLEN 2
97 #define BGP4PATHATTRIPADDRPREFIX 3
98 #define BGP4PATHATTRORIGIN 4
99 #define BGP4PATHATTRASPATHSEGMENT 5
100 #define BGP4PATHATTRNEXTHOP 6
101 #define BGP4PATHATTRMULTIEXITDISC 7
102 #define BGP4PATHATTRLOCALPREF 8
103 #define BGP4PATHATTRATOMICAGGREGATE 9
104 #define BGP4PATHATTRAGGREGATORAS 10
105 #define BGP4PATHATTRAGGREGATORADDR 11
106 #define BGP4PATHATTRCALCLOCALPREF 12
107 #define BGP4PATHATTRBEST 13
108 #define BGP4PATHATTRUNKNOWN 14
110 /* SNMP value hack. */
111 #define INTEGER ASN_INTEGER
112 #define INTEGER32 ASN_INTEGER
113 #define COUNTER32 ASN_COUNTER
114 #define OCTET_STRING ASN_OCTET_STR
115 #define IPADDRESS ASN_IPADDRESS
116 #define GAUGE32 ASN_UNSIGNED
118 /* Declare static local variables for convenience. */
121 /* BGP-MIB instances. */
122 static oid bgp_oid
[] = {BGP4MIB
};
123 static oid bgp_trap_oid
[] = {BGP4MIB
, 0};
125 /* IP address 0.0.0.0. */
126 static struct in_addr bgp_empty_addr
= {.s_addr
= 0};
128 /* Hook functions. */
129 static uint8_t *bgpVersion(struct variable
*, oid
[], size_t *, int, size_t *,
131 static uint8_t *bgpLocalAs(struct variable
*, oid
[], size_t *, int, size_t *,
133 static uint8_t *bgpPeerTable(struct variable
*, oid
[], size_t *, int, size_t *,
135 static uint8_t *bgpRcvdPathAttrTable(struct variable
*, oid
[], size_t *, int,
136 size_t *, WriteMethod
**);
137 static uint8_t *bgpIdentifier(struct variable
*, oid
[], size_t *, int, size_t *,
139 static uint8_t *bgp4PathAttrTable(struct variable
*, oid
[], size_t *, int,
140 size_t *, WriteMethod
**);
141 /* static uint8_t *bgpTraps (); */
143 static struct variable bgp_variables
[] = {
145 {BGPVERSION
, OCTET_STRING
, RONLY
, bgpVersion
, 1, {1}},
147 {BGPLOCALAS
, INTEGER
, RONLY
, bgpLocalAs
, 1, {2}},
148 /* BGP peer table. */
149 {BGPPEERIDENTIFIER
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 1}},
150 {BGPPEERSTATE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 2}},
151 {BGPPEERADMINSTATUS
, INTEGER
, RWRITE
, bgpPeerTable
, 3, {3, 1, 3}},
152 {BGPPEERNEGOTIATEDVERSION
,
158 {BGPPEERLOCALADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 5}},
159 {BGPPEERLOCALPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 6}},
160 {BGPPEERREMOTEADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 7}},
161 {BGPPEERREMOTEPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 8}},
162 {BGPPEERREMOTEAS
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 9}},
163 {BGPPEERINUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 10}},
164 {BGPPEEROUTUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 11}},
165 {BGPPEERINTOTALMESSAGES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 12}},
166 {BGPPEEROUTTOTALMESSAGES
,
172 {BGPPEERLASTERROR
, OCTET_STRING
, RONLY
, bgpPeerTable
, 3, {3, 1, 14}},
173 {BGPPEERFSMESTABLISHEDTRANSITIONS
,
179 {BGPPEERFSMESTABLISHEDTIME
,
185 {BGPPEERCONNECTRETRYINTERVAL
,
191 {BGPPEERHOLDTIME
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 18}},
192 {BGPPEERKEEPALIVE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 19}},
193 {BGPPEERHOLDTIMECONFIGURED
,
199 {BGPPEERKEEPALIVECONFIGURED
,
205 {BGPPEERMINROUTEADVERTISEMENTINTERVAL
,
211 {BGPPEERINUPDATEELAPSEDTIME
,
217 /* BGP identifier. */
218 {BGPIDENTIFIER
, IPADDRESS
, RONLY
, bgpIdentifier
, 1, {4}},
219 /* BGP received path attribute table. */
220 {BGPPATHATTRPEER
, IPADDRESS
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 1}},
221 {BGPPATHATTRDESTNETWORK
,
224 bgpRcvdPathAttrTable
,
227 {BGPPATHATTRORIGIN
, INTEGER
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 3}},
231 bgpRcvdPathAttrTable
,
237 bgpRcvdPathAttrTable
,
240 {BGPPATHATTRINTERASMETRIC
,
243 bgpRcvdPathAttrTable
,
246 /* BGP-4 received path attribute table. */
247 {BGP4PATHATTRPEER
, IPADDRESS
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 1}},
248 {BGP4PATHATTRIPADDRPREFIXLEN
,
254 {BGP4PATHATTRIPADDRPREFIX
,
260 {BGP4PATHATTRORIGIN
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 4}},
261 {BGP4PATHATTRASPATHSEGMENT
,
267 {BGP4PATHATTRNEXTHOP
,
273 {BGP4PATHATTRMULTIEXITDISC
,
279 {BGP4PATHATTRLOCALPREF
,
285 {BGP4PATHATTRATOMICAGGREGATE
,
291 {BGP4PATHATTRAGGREGATORAS
,
297 {BGP4PATHATTRAGGREGATORADDR
,
303 {BGP4PATHATTRCALCLOCALPREF
,
309 {BGP4PATHATTRBEST
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 13}},
310 {BGP4PATHATTRUNKNOWN
,
319 static uint8_t *bgpVersion(struct variable
*v
, oid name
[], size_t *length
,
320 int exact
, size_t *var_len
,
321 WriteMethod
**write_method
)
323 static uint8_t version
;
325 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
329 /* Retrun BGP version. Zebra bgpd only support version 4. */
330 version
= (0x80 >> (BGP_VERSION_4
- 1));
332 /* Return octet string length 1. */
337 static uint8_t *bgpLocalAs(struct variable
*v
, oid name
[], size_t *length
,
338 int exact
, size_t *var_len
,
339 WriteMethod
**write_method
)
343 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
347 /* Get BGP structure. */
348 bgp
= bgp_get_default();
352 return SNMP_INTEGER(bgp
->as
);
355 static struct peer
*peer_lookup_addr_ipv4(struct in_addr
*src
)
359 struct listnode
*node
;
360 struct listnode
*bgpnode
;
362 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
363 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
364 if (sockunion_family(&peer
->su
) != AF_INET
)
367 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
;
381 struct listnode
*bgpnode
;
383 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
384 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
385 if (sockunion_family(&peer
->su
) != AF_INET
)
387 if (ntohl(sockunion2ip(&peer
->su
)) <= ntohl(src
->s_addr
))
391 || ntohl(sockunion2ip(&next_peer
->su
))
392 > ntohl(sockunion2ip(&peer
->su
))) {
399 src
->s_addr
= sockunion2ip(&next_peer
->su
);
406 /* 1.3.6.1.2.1.15.3.1.x = 10 */
407 #define PEERTAB_NAMELEN 10
409 static struct peer
*bgpPeerTable_lookup(struct variable
*v
, oid name
[],
410 size_t *length
, struct in_addr
*addr
,
413 struct peer
*peer
= NULL
;
414 size_t namelen
= v
? v
->namelen
: PEERTAB_NAMELEN
;
418 /* Check the length. */
419 if (*length
- namelen
!= sizeof(struct in_addr
))
422 oid2in_addr(name
+ namelen
, IN_ADDR_SIZE
, addr
);
424 peer
= peer_lookup_addr_ipv4(addr
);
427 len
= *length
- namelen
;
431 oid2in_addr(name
+ namelen
, len
, addr
);
433 peer
= bgp_peer_lookup_next(addr
);
438 oid_copy_in_addr(name
+ namelen
, addr
);
439 *length
= sizeof(struct in_addr
) + namelen
;
446 /* BGP write methods. */
447 static int write_bgpPeerTable(int action
, uint8_t *var_val
,
448 uint8_t var_val_type
, size_t var_val_len
,
449 uint8_t *statP
, oid
*name
, size_t length
)
455 if (var_val_type
!= ASN_INTEGER
) {
456 return SNMP_ERR_WRONGTYPE
;
458 if (var_val_len
!= sizeof(long)) {
459 return SNMP_ERR_WRONGLENGTH
;
462 intval
= *(long *)var_val
;
464 memset(&addr
, 0, sizeof(struct in_addr
));
466 peer
= bgpPeerTable_lookup(NULL
, name
, &length
, &addr
, 1);
468 return SNMP_ERR_NOSUCHNAME
;
470 if (action
!= SNMP_MSG_INTERNAL_SET_COMMIT
)
471 return SNMP_ERR_NOERROR
;
473 zlog_info("%s: SNMP write .%ld = %ld", peer
->host
,
474 (long)name
[PEERTAB_NAMELEN
- 1], intval
);
476 switch (name
[PEERTAB_NAMELEN
- 1]) {
477 case BGPPEERADMINSTATUS
:
478 #define BGP_PeerAdmin_stop 1
479 #define BGP_PeerAdmin_start 2
480 /* When the peer is established, */
481 if (intval
== BGP_PeerAdmin_stop
)
482 BGP_EVENT_ADD(peer
, BGP_Stop
);
483 else if (intval
== BGP_PeerAdmin_start
)
486 return SNMP_ERR_NOSUCHNAME
;
488 case BGPPEERCONNECTRETRYINTERVAL
:
489 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
490 peer
->connect
= intval
;
491 peer
->v_connect
= intval
;
493 case BGPPEERHOLDTIMECONFIGURED
:
494 peer_flag_set(peer
, PEER_FLAG_TIMER
);
495 peer
->holdtime
= intval
;
496 peer
->v_holdtime
= intval
;
498 case BGPPEERKEEPALIVECONFIGURED
:
499 peer_flag_set(peer
, PEER_FLAG_TIMER
);
500 peer
->keepalive
= intval
;
501 peer
->v_keepalive
= intval
;
503 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
504 peer
->v_routeadv
= intval
;
507 return SNMP_ERR_NOERROR
;
510 static uint8_t *bgpPeerTable(struct variable
*v
, oid name
[], size_t *length
,
511 int exact
, size_t *var_len
,
512 WriteMethod
**write_method
)
514 static struct in_addr addr
;
518 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
521 memset(&addr
, 0, sizeof(struct in_addr
));
523 peer
= bgpPeerTable_lookup(v
, name
, length
, &addr
, exact
);
528 case BGPPEERIDENTIFIER
:
529 return SNMP_IPADDRESS(peer
->remote_id
);
531 return SNMP_INTEGER(peer
->status
);
532 case BGPPEERADMINSTATUS
:
533 *write_method
= write_bgpPeerTable
;
534 #define BGP_PeerAdmin_stop 1
535 #define BGP_PeerAdmin_start 2
536 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
537 return SNMP_INTEGER(BGP_PeerAdmin_stop
);
539 return SNMP_INTEGER(BGP_PeerAdmin_start
);
540 case BGPPEERNEGOTIATEDVERSION
:
541 return SNMP_INTEGER(BGP_VERSION_4
);
542 case BGPPEERLOCALADDR
:
544 return SNMP_IPADDRESS(peer
->su_local
->sin
.sin_addr
);
546 return SNMP_IPADDRESS(bgp_empty_addr
);
547 case BGPPEERLOCALPORT
:
550 ntohs(peer
->su_local
->sin
.sin_port
));
552 return SNMP_INTEGER(0);
553 case BGPPEERREMOTEADDR
:
555 return SNMP_IPADDRESS(peer
->su_remote
->sin
.sin_addr
);
557 return SNMP_IPADDRESS(bgp_empty_addr
);
558 case BGPPEERREMOTEPORT
:
561 ntohs(peer
->su_remote
->sin
.sin_port
));
563 return SNMP_INTEGER(0);
564 case BGPPEERREMOTEAS
:
565 return SNMP_INTEGER(peer
->as
);
566 case BGPPEERINUPDATES
:
567 ui
= atomic_load_explicit(&peer
->update_in
,
568 memory_order_relaxed
);
569 return SNMP_INTEGER(ui
);
570 case BGPPEEROUTUPDATES
:
571 uo
= atomic_load_explicit(&peer
->update_out
,
572 memory_order_relaxed
);
573 return SNMP_INTEGER(uo
);
574 case BGPPEERINTOTALMESSAGES
:
575 return SNMP_INTEGER(PEER_TOTAL_RX(peer
));
576 case BGPPEEROUTTOTALMESSAGES
:
577 return SNMP_INTEGER(PEER_TOTAL_TX(peer
));
578 case BGPPEERLASTERROR
: {
579 static uint8_t lasterror
[2];
580 lasterror
[0] = peer
->notify
.code
;
581 lasterror
[1] = peer
->notify
.subcode
;
583 return (uint8_t *)&lasterror
;
585 case BGPPEERFSMESTABLISHEDTRANSITIONS
:
586 return SNMP_INTEGER(peer
->established
);
587 case BGPPEERFSMESTABLISHEDTIME
:
588 if (peer
->uptime
== 0)
589 return SNMP_INTEGER(0);
591 return SNMP_INTEGER(bgp_clock() - peer
->uptime
);
592 case BGPPEERCONNECTRETRYINTERVAL
:
593 *write_method
= write_bgpPeerTable
;
594 return SNMP_INTEGER(peer
->v_connect
);
595 case BGPPEERHOLDTIME
:
596 return SNMP_INTEGER(peer
->v_holdtime
);
597 case BGPPEERKEEPALIVE
:
598 return SNMP_INTEGER(peer
->v_keepalive
);
599 case BGPPEERHOLDTIMECONFIGURED
:
600 *write_method
= write_bgpPeerTable
;
601 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
602 return SNMP_INTEGER(peer
->holdtime
);
604 return SNMP_INTEGER(peer
->v_holdtime
);
605 case BGPPEERKEEPALIVECONFIGURED
:
606 *write_method
= write_bgpPeerTable
;
607 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
608 return SNMP_INTEGER(peer
->keepalive
);
610 return SNMP_INTEGER(peer
->v_keepalive
);
611 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
612 *write_method
= write_bgpPeerTable
;
613 return SNMP_INTEGER(peer
->v_routeadv
);
614 case BGPPEERINUPDATEELAPSEDTIME
:
615 if (peer
->update_time
== 0)
616 return SNMP_INTEGER(0);
618 return SNMP_INTEGER(bgp_clock() - peer
->update_time
);
625 static uint8_t *bgpIdentifier(struct variable
*v
, oid name
[], size_t *length
,
626 int exact
, size_t *var_len
,
627 WriteMethod
**write_method
)
631 if (smux_header_generic(v
, name
, length
, exact
, var_len
, write_method
)
635 bgp
= bgp_get_default();
639 return SNMP_IPADDRESS(bgp
->router_id
);
642 static uint8_t *bgpRcvdPathAttrTable(struct variable
*v
, oid name
[],
643 size_t *length
, int exact
, size_t *var_len
,
644 WriteMethod
**write_method
)
646 /* Received Path Attribute Table. This table contains, one entry
647 per path to a network, path attributes received from all peers
648 running BGP version 3 or less. This table is obsolete, having
649 been replaced in functionality with the bgp4PathAttrTable. */
653 static struct bgp_path_info
*bgp4PathAttrLookup(struct variable
*v
, oid name
[],
654 size_t *length
, struct bgp
*bgp
,
655 struct prefix_ipv4
*addr
,
660 struct bgp_path_info
*path
;
661 struct bgp_path_info
*min
;
662 struct bgp_dest
*dest
;
665 struct in_addr paddr
;
669 #define BGP_PATHATTR_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
672 if (*length
- v
->namelen
!= BGP_PATHATTR_ENTRY_OFFSET
)
675 /* Set OID offset for prefix. */
676 offset
= name
+ v
->namelen
;
677 oid2in_addr(offset
, IN_ADDR_SIZE
, &addr
->prefix
);
678 offset
+= IN_ADDR_SIZE
;
681 addr
->prefixlen
= *offset
;
685 su
.sin
.sin_family
= AF_INET
;
686 oid2in_addr(offset
, IN_ADDR_SIZE
, &su
.sin
.sin_addr
);
689 dest
= bgp_node_lookup(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
690 (struct prefix
*)addr
);
692 bgp_dest_unlock_node(dest
);
694 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
696 if (sockunion_same(&path
->peer
->su
, &su
))
700 offset
= name
+ v
->namelen
;
701 offsetlen
= *length
- v
->namelen
;
705 dest
= bgp_table_top(bgp
->rib
[AFI_IP
][SAFI_UNICAST
]);
707 if (len
> IN_ADDR_SIZE
)
710 oid2in_addr(offset
, len
, &addr
->prefix
);
712 offset
+= IN_ADDR_SIZE
;
713 offsetlen
-= IN_ADDR_SIZE
;
716 addr
->prefixlen
= *offset
;
718 addr
->prefixlen
= len
* 8;
720 dest
= bgp_node_get(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
721 (struct prefix
*)addr
);
729 if (len
> IN_ADDR_SIZE
)
732 oid2in_addr(offset
, len
, &paddr
);
734 paddr
.s_addr
= INADDR_ANY
;
742 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
744 if (path
->peer
->su
.sin
.sin_family
== AF_INET
745 && ntohl(paddr
.s_addr
)
746 < ntohl(path
->peer
->su
.sin
750 if (ntohl(path
->peer
->su
.sin
753 < ntohl(min
->peer
->su
.sin
763 const struct prefix
*rn_p
=
764 bgp_dest_get_prefix(dest
);
767 v
->namelen
+ BGP_PATHATTR_ENTRY_OFFSET
;
769 offset
= name
+ v
->namelen
;
770 oid_copy_in_addr(offset
, &rn_p
->u
.prefix4
);
771 offset
+= IN_ADDR_SIZE
;
772 *offset
= rn_p
->prefixlen
;
774 oid_copy_in_addr(offset
,
775 &min
->peer
->su
.sin
.sin_addr
);
776 addr
->prefix
= rn_p
->u
.prefix4
;
777 addr
->prefixlen
= rn_p
->prefixlen
;
779 bgp_dest_unlock_node(dest
);
784 paddr
.s_addr
= INADDR_ANY
;
785 } while ((dest
= bgp_route_next(dest
)) != NULL
);
790 static uint8_t *bgp4PathAttrTable(struct variable
*v
, oid name
[],
791 size_t *length
, int exact
, size_t *var_len
,
792 WriteMethod
**write_method
)
795 struct bgp_path_info
*path
;
796 struct prefix_ipv4 addr
;
798 bgp
= bgp_get_default();
802 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
)
805 memset(&addr
, 0, sizeof(struct prefix_ipv4
));
807 path
= bgp4PathAttrLookup(v
, name
, length
, bgp
, &addr
, exact
);
812 case BGP4PATHATTRPEER
: /* 1 */
813 return SNMP_IPADDRESS(path
->peer
->su
.sin
.sin_addr
);
814 case BGP4PATHATTRIPADDRPREFIXLEN
: /* 2 */
815 return SNMP_INTEGER(addr
.prefixlen
);
816 case BGP4PATHATTRIPADDRPREFIX
: /* 3 */
817 return SNMP_IPADDRESS(addr
.prefix
);
818 case BGP4PATHATTRORIGIN
: /* 4 */
819 return SNMP_INTEGER(path
->attr
->origin
);
820 case BGP4PATHATTRASPATHSEGMENT
: /* 5 */
821 return aspath_snmp_pathseg(path
->attr
->aspath
, var_len
);
822 case BGP4PATHATTRNEXTHOP
: /* 6 */
823 return SNMP_IPADDRESS(path
->attr
->nexthop
);
824 case BGP4PATHATTRMULTIEXITDISC
: /* 7 */
825 return SNMP_INTEGER(path
->attr
->med
);
826 case BGP4PATHATTRLOCALPREF
: /* 8 */
827 return SNMP_INTEGER(path
->attr
->local_pref
);
828 case BGP4PATHATTRATOMICAGGREGATE
: /* 9 */
829 return SNMP_INTEGER(1);
830 case BGP4PATHATTRAGGREGATORAS
: /* 10 */
831 return SNMP_INTEGER(path
->attr
->aggregator_as
);
832 case BGP4PATHATTRAGGREGATORADDR
: /* 11 */
833 return SNMP_IPADDRESS(path
->attr
->aggregator_addr
);
834 case BGP4PATHATTRCALCLOCALPREF
: /* 12 */
835 return SNMP_INTEGER(-1);
836 case BGP4PATHATTRBEST
: /* 13 */
837 #define BGP4_PathAttrBest_false 1
838 #define BGP4_PathAttrBest_true 2
839 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
840 return SNMP_INTEGER(BGP4_PathAttrBest_true
);
842 return SNMP_INTEGER(BGP4_PathAttrBest_false
);
843 case BGP4PATHATTRUNKNOWN
: /* 14 */
851 static struct trap_object bgpTrapList
[] = {{3, {3, 1, BGPPEERREMOTEADDR
} },
852 {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_in_addr(index
, &addr
);
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_in_addr(index
, &addr
);
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
);
901 bgp_mpls_l3vpn_module_init();
905 static int bgp_snmp_module_init(void)
907 hook_register(peer_status_changed
, bgpTrapEstablished
);
908 hook_register(peer_backward_transition
, bgpTrapBackwardTransition
);
909 hook_register(frr_late_init
, bgp_snmp_init
);
913 FRR_MODULE_SETUP(.name
= "bgpd_snmp", .version
= FRR_VERSION
,
914 .description
= "bgpd AgentX SNMP module",
915 .init
= bgp_snmp_module_init
,