1 /* BGP4V2-MIB SNMP support
3 * Copyright (C) 2022 Donatas Abraitis <donatas@opensourcerouting.org>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <net-snmp/net-snmp-config.h>
25 #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_debug.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_fsm.h"
44 #include "bgpd/bgp_snmp.h"
45 #include "bgpd/bgp_snmp_bgp4v2.h"
49 static oid bgpv2_oid
[] = {BGP4V2MIB
};
50 static struct in_addr bgp_empty_addr
= {};
52 static struct peer
*peer_lookup_all_vrf(struct ipaddr
*addr
)
56 struct listnode
*node
;
57 struct listnode
*bgpnode
;
59 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
60 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
61 switch (sockunion_family(&peer
->su
)) {
63 if (IPV4_ADDR_SAME(&peer
->su
.sin
.sin_addr
,
68 if (IPV6_ADDR_SAME(&peer
->su
.sin6
.sin6_addr
,
81 static struct peer
*peer_lookup_all_vrf_next(struct ipaddr
*addr
, oid
*offset
,
86 struct peer
*next_peer
= NULL
;
87 struct listnode
*node
;
88 struct listnode
*bgpnode
;
90 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
91 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
92 sa_family_t peer_family
= sockunion_family(&peer
->su
);
94 if (peer_family
!= family
)
97 switch (sockunion_family(&peer
->su
)) {
99 oid2in_addr(offset
, IN_ADDR_SIZE
,
101 if (IPV4_ADDR_CMP(&peer
->su
.sin
.sin_addr
,
102 &addr
->ip
._v4_addr
) < 0 ||
103 IPV4_ADDR_SAME(&peer
->su
.sin
.sin_addr
,
108 IPV4_ADDR_CMP(&next_peer
->su
.sin
.sin_addr
,
109 &peer
->su
.sin
.sin_addr
) > 0)
114 oid2in6_addr(offset
, &addr
->ip
._v6_addr
);
115 if (IPV6_ADDR_CMP(&peer
->su
.sin6
.sin6_addr
,
116 &addr
->ip
._v6_addr
) < 0 ||
117 IPV6_ADDR_SAME(&peer
->su
.sin6
.sin6_addr
,
122 IPV6_ADDR_CMP(&next_peer
->su
.sin6
.sin6_addr
,
123 &peer
->su
.sin6
.sin6_addr
) > 0)
139 static struct peer
*bgpv2PeerTable_lookup(struct variable
*v
, oid name
[],
140 size_t *length
, int exact
,
143 struct peer
*peer
= NULL
;
144 size_t namelen
= v
? v
->namelen
: BGP4V2_PEER_ENTRY_OFFSET
;
145 oid
*offset
= name
+ namelen
;
146 sa_family_t family
= name
[namelen
- 1] == 4 ? AF_INET
: AF_INET6
;
147 int afi_len
= IN_ADDR_SIZE
;
148 size_t offsetlen
= *length
- namelen
;
150 if (family
== AF_INET6
)
151 afi_len
= IN6_ADDR_SIZE
;
153 /* Somehow with net-snmp 5.7.3, every OID item in an array
154 * is uninitialized and has a max random value, let's zero it.
155 * With 5.8, 5.9, it works fine even without this hack.
158 for (int i
= 0; i
< afi_len
; i
++)
163 if (family
== AF_INET
) {
164 oid2in_addr(offset
, afi_len
, &addr
->ip
._v4_addr
);
165 peer
= peer_lookup_all_vrf(addr
);
167 } else if (family
== AF_INET6
) {
168 oid2in6_addr(offset
, &addr
->ip
._v6_addr
);
169 return peer_lookup_all_vrf(addr
);
172 peer
= peer_lookup_all_vrf_next(addr
, offset
, family
);
176 switch (sockunion_family(&peer
->su
)) {
178 oid_copy_in_addr(offset
, &peer
->su
.sin
.sin_addr
);
179 *length
= afi_len
+ namelen
;
182 oid_copy_in6_addr(offset
, &peer
->su
.sin6
.sin6_addr
);
183 *length
= afi_len
+ namelen
;
193 static uint8_t *bgpv2PeerTable(struct variable
*v
, oid name
[], size_t *length
,
194 int exact
, size_t *var_len
,
195 WriteMethod
**write_method
)
198 struct ipaddr addr
= {};
200 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
204 peer
= bgpv2PeerTable_lookup(v
, name
, length
, exact
, &addr
);
209 case BGP4V2_PEER_INSTANCE
:
210 return SNMP_INTEGER(peer
->bgp
->vrf_id
);
211 case BGP4V2_PEER_LOCAL_ADDR_TYPE
:
213 return SNMP_INTEGER(peer
->su_local
->sa
.sa_family
==
218 return SNMP_INTEGER(0);
219 case BGP4V2_PEER_LOCAL_ADDR
:
221 if (peer
->su_local
->sa
.sa_family
== AF_INET
)
222 return SNMP_IPADDRESS(
223 peer
->su_local
->sin
.sin_addr
);
225 return SNMP_IP6ADDRESS(
226 peer
->su_local
->sin6
.sin6_addr
);
228 return SNMP_IPADDRESS(bgp_empty_addr
);
229 case BGP4V2_PEER_REMOTE_ADDR_TYPE
:
231 return SNMP_INTEGER(peer
->su_remote
->sa
.sa_family
==
236 return SNMP_INTEGER(0);
237 case BGP4V2_PEER_REMOTE_ADDR
:
239 if (peer
->su_remote
->sa
.sa_family
== AF_INET
)
240 return SNMP_IPADDRESS(
241 peer
->su_remote
->sin
.sin_addr
);
243 return SNMP_IP6ADDRESS(
244 peer
->su_remote
->sin6
.sin6_addr
);
246 return SNMP_IPADDRESS(bgp_empty_addr
);
247 case BGP4V2_PEER_LOCAL_PORT
:
249 if (peer
->su_local
->sa
.sa_family
== AF_INET
)
251 ntohs(peer
->su_local
->sin
.sin_port
));
254 ntohs(peer
->su_local
->sin6
.sin6_port
));
256 return SNMP_INTEGER(0);
257 case BGP4V2_PEER_LOCAL_AS
:
258 return SNMP_INTEGER(peer
->local_as
);
259 case BGP4V2_PEER_LOCAL_IDENTIFIER
:
260 return SNMP_IPADDRESS(peer
->local_id
);
261 case BGP4V2_PEER_REMOTE_PORT
:
263 if (peer
->su_remote
->sa
.sa_family
== AF_INET
)
265 ntohs(peer
->su_remote
->sin
.sin_port
));
268 ntohs(peer
->su_remote
->sin6
.sin6_port
));
270 return SNMP_INTEGER(0);
271 case BGP4V2_PEER_REMOTE_AS
:
272 return SNMP_INTEGER(peer
->as
);
273 case BGP4V2_PEER_REMOTE_IDENTIFIER
:
274 return SNMP_IPADDRESS(peer
->remote_id
);
275 case BGP4V2_PEER_ADMIN_STATUS
:
276 #define BGP_PEER_ADMIN_STATUS_HALTED 1
277 #define BGP_PEER_ADMIN_STATUS_RUNNING 2
278 if (BGP_PEER_START_SUPPRESSED(peer
))
279 return SNMP_INTEGER(BGP_PEER_ADMIN_STATUS_HALTED
);
281 return SNMP_INTEGER(BGP_PEER_ADMIN_STATUS_RUNNING
);
282 case BGP4V2_PEER_STATE
:
283 return SNMP_INTEGER(peer
->status
);
284 case BGP4V2_PEER_DESCRIPTION
:
286 return SNMP_STRING(peer
->desc
);
295 static uint8_t *bgpv2PeerErrorsTable(struct variable
*v
, oid name
[],
296 size_t *length
, int exact
, size_t *var_len
,
297 WriteMethod
**write_method
)
300 struct ipaddr addr
= {};
302 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
306 peer
= bgpv2PeerTable_lookup(v
, name
, length
, exact
, &addr
);
311 case BGP4V2_PEER_LAST_ERROR_CODE_RECEIVED
:
312 if (peer
->last_reset
== PEER_DOWN_NOTIFY_RECEIVED
)
313 return SNMP_INTEGER(peer
->notify
.code
);
315 return SNMP_INTEGER(0);
316 case BGP4V2_PEER_LAST_ERROR_SUBCODE_RECEIVED
:
317 if (peer
->last_reset
== PEER_DOWN_NOTIFY_RECEIVED
)
318 return SNMP_INTEGER(peer
->notify
.subcode
);
320 return SNMP_INTEGER(0);
321 case BGP4V2_PEER_LAST_ERROR_RECEIVED_TIME
:
322 if (peer
->last_reset
== PEER_DOWN_NOTIFY_RECEIVED
)
323 return SNMP_INTEGER(peer
->resettime
);
325 return SNMP_INTEGER(0);
326 case BGP4V2_PEER_LAST_ERROR_RECEIVED_TEXT
:
327 if (peer
->last_reset
== PEER_DOWN_NOTIFY_RECEIVED
) {
328 struct bgp_notify notify
= peer
->notify
;
330 const char *msg_str
= NULL
;
332 if (notify
.code
== BGP_NOTIFY_CEASE
&&
334 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
||
335 notify
.subcode
== BGP_NOTIFY_CEASE_ADMIN_RESET
)) {
336 msg_str
= bgp_notify_admin_message(
337 msg_buf
, sizeof(msg_buf
),
338 (uint8_t *)notify
.data
, notify
.length
);
339 return SNMP_STRING(msg_str
);
342 return SNMP_STRING("");
343 case BGP4V2_PEER_LAST_ERROR_RECEIVED_DATA
:
344 if (peer
->last_reset
== PEER_DOWN_NOTIFY_RECEIVED
)
345 return SNMP_STRING(peer
->notify
.data
);
347 return SNMP_STRING("");
348 case BGP4V2_PEER_LAST_ERROR_CODE_SENT
:
349 if (peer
->last_reset
!= PEER_DOWN_NOTIFY_RECEIVED
)
350 return SNMP_INTEGER(peer
->notify
.code
);
352 return SNMP_INTEGER(0);
353 case BGP4V2_PEER_LAST_ERROR_SUBCODE_SENT
:
354 if (peer
->last_reset
!= PEER_DOWN_NOTIFY_RECEIVED
)
355 return SNMP_INTEGER(peer
->notify
.subcode
);
357 return SNMP_INTEGER(0);
358 case BGP4V2_PEER_LAST_ERROR_SENT_TIME
:
359 if (peer
->last_reset
!= PEER_DOWN_NOTIFY_RECEIVED
)
360 return SNMP_INTEGER(peer
->resettime
);
362 return SNMP_INTEGER(0);
363 case BGP4V2_PEER_LAST_ERROR_SENT_TEXT
:
364 if (peer
->last_reset
== PEER_DOWN_NOTIFY_SEND
||
365 peer
->last_reset
== PEER_DOWN_RTT_SHUTDOWN
||
366 peer
->last_reset
== PEER_DOWN_USER_SHUTDOWN
) {
367 struct bgp_notify notify
= peer
->notify
;
369 const char *msg_str
= NULL
;
371 if (notify
.code
== BGP_NOTIFY_CEASE
&&
373 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
||
374 notify
.subcode
== BGP_NOTIFY_CEASE_ADMIN_RESET
)) {
375 msg_str
= bgp_notify_admin_message(
376 msg_buf
, sizeof(msg_buf
),
377 (uint8_t *)notify
.data
, notify
.length
);
378 return SNMP_STRING(msg_str
);
381 return SNMP_STRING("");
382 case BGP4V2_PEER_LAST_ERROR_SENT_DATA
:
383 if ((peer
->last_reset
== PEER_DOWN_NOTIFY_SEND
||
384 peer
->last_reset
== PEER_DOWN_RTT_SHUTDOWN
||
385 peer
->last_reset
== PEER_DOWN_USER_SHUTDOWN
) &&
387 return SNMP_STRING(peer
->notify
.data
);
389 return SNMP_STRING("");
397 static uint8_t *bgpv2PeerEventTimesTable(struct variable
*v
, oid name
[],
398 size_t *length
, int exact
,
400 WriteMethod
**write_method
)
403 struct ipaddr addr
= {};
405 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
409 peer
= bgpv2PeerTable_lookup(v
, name
, length
, exact
, &addr
);
414 case BGP4V2_PEER_FSM_ESTABLISHED_TIME
:
416 return SNMP_INTEGER(0);
418 return SNMP_INTEGER(monotime(NULL
) - peer
->uptime
);
419 case BGP4V2_PEER_PEER_IN_UPDATES_ELAPSED_TIME
:
420 if (!peer
->update_time
)
421 return SNMP_INTEGER(0);
423 return SNMP_INTEGER(monotime(NULL
) - peer
->update_time
);
431 static struct bgp_path_info
*
432 bgp4v2PathAttrLookup(struct variable
*v
, oid name
[], size_t *length
,
433 struct bgp
*bgp
, struct prefix
*addr
, int exact
)
437 struct bgp_path_info
*path
, *min
;
438 struct bgp_dest
*dest
;
441 struct ipaddr paddr
= {};
442 size_t namelen
= v
? v
->namelen
: BGP4V2_NLRI_ENTRY_OFFSET
;
443 sa_family_t family
= name
[namelen
- 1] == 4 ? AF_INET
: AF_INET6
;
445 size_t afi_len
= IN_ADDR_SIZE
;
447 if (family
== AF_INET6
) {
449 afi_len
= IN6_ADDR_SIZE
;
452 #define BGP_NLRI_ENTRY_OFFSET (afi_len + 1 + afi_len)
457 if (*length
- namelen
!= BGP_NLRI_ENTRY_OFFSET
)
460 /* Set OID offset for prefix */
461 offset
= name
+ namelen
;
462 if (family
== AF_INET
)
463 oid2in_addr(offset
, afi_len
, &addr
->u
.prefix4
);
465 oid2in6_addr(offset
, &addr
->u
.prefix6
);
469 addr
->prefixlen
= *offset
;
470 addr
->family
= family
;
474 su
.sin
.sin_family
= family
;
475 if (family
== AF_INET
)
476 oid2in_addr(offset
, afi_len
, &su
.sin
.sin_addr
);
478 oid2in6_addr(offset
, &su
.sin6
.sin6_addr
);
481 dest
= bgp_node_lookup(bgp
->rib
[afi
][SAFI_UNICAST
], addr
);
483 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
485 if (sockunion_same(&path
->peer
->su
, &su
))
488 bgp_dest_unlock_node(dest
);
494 offset
= name
+ namelen
;
495 offsetlen
= *length
- namelen
;
498 if (offsetlen
== 0) {
499 dest
= bgp_table_top(bgp
->rib
[afi
][SAFI_UNICAST
]);
504 if (family
== AF_INET
)
505 oid2in_addr(offset
, len
, &addr
->u
.prefix4
);
507 oid2in6_addr(offset
, &addr
->u
.prefix6
);
510 offsetlen
-= afi_len
;
513 addr
->prefixlen
= *offset
;
515 addr
->prefixlen
= len
* 8;
517 addr
->family
= family
;
519 dest
= bgp_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], addr
);
530 if (family
== AF_INET
)
531 oid2in_addr(offset
, len
, &paddr
.ip
._v4_addr
);
533 oid2in6_addr(offset
, &paddr
.ip
._v6_addr
);
535 if (family
== AF_INET
)
536 memset(&paddr
.ip
._v4_addr
, 0, afi_len
);
538 memset(&paddr
.ip
._v6_addr
, 0, afi_len
);
547 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
549 sa_family_t path_family
=
550 sockunion_family(&path
->peer
->su
);
552 if (path_family
== AF_INET
&&
553 IPV4_ADDR_CMP(&paddr
.ip
._v4_addr
,
554 &path
->peer
->su
.sin
.sin_addr
) < 0) {
558 &path
->peer
->su
.sin
.sin_addr
,
559 &min
->peer
->su
.sin
.sin_addr
) < 0))
561 } else if (path_family
== AF_INET6
&&
564 &path
->peer
->su
.sin6
.sin6_addr
) <
569 &path
->peer
->su
.sin6
.sin6_addr
,
570 &min
->peer
->su
.sin6
.sin6_addr
) <
577 const struct prefix
*rn_p
= bgp_dest_get_prefix(dest
);
579 *length
= namelen
+ BGP_NLRI_ENTRY_OFFSET
;
581 offset
= name
+ namelen
;
583 /* Encode prefix into OID */
584 if (family
== AF_INET
)
585 oid_copy_in_addr(offset
, &rn_p
->u
.prefix4
);
587 oid_copy_in6_addr(offset
, &rn_p
->u
.prefix6
);
590 *offset
= rn_p
->prefixlen
;
593 /* Encode peer's IP into OID */
594 if (family
== AF_INET
) {
595 oid_copy_in_addr(offset
,
596 &min
->peer
->su
.sin
.sin_addr
);
597 addr
->u
.prefix4
= rn_p
->u
.prefix4
;
600 offset
, &min
->peer
->su
.sin6
.sin6_addr
);
601 addr
->u
.prefix6
= rn_p
->u
.prefix6
;
604 addr
->prefixlen
= rn_p
->prefixlen
;
605 addr
->family
= rn_p
->family
;
607 bgp_dest_unlock_node(dest
);
612 if (family
== AF_INET
)
613 memset(&paddr
.ip
._v4_addr
, 0, afi_len
);
615 memset(&paddr
.ip
._v6_addr
, 0, afi_len
);
616 } while ((dest
= bgp_route_next(dest
)));
621 static uint8_t *bgp4v2PathAttrTable(struct variable
*v
, oid name
[],
622 size_t *length
, int exact
, size_t *var_len
,
623 WriteMethod
**write_method
)
626 struct bgp_path_info
*path
;
627 struct peer_af
*paf
= NULL
;
628 struct prefix addr
= {};
629 const struct prefix
*prefix
= NULL
;
630 enum bgp_af_index index
;
632 bgp
= bgp_get_default();
636 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
640 path
= bgp4v2PathAttrLookup(v
, name
, length
, bgp
, &addr
, exact
);
644 prefix
= bgp_dest_get_prefix(path
->net
);
647 paf
= path
->peer
->peer_af_array
[index
];
653 case BGP4V2_NLRI_INDEX
:
654 return SNMP_INTEGER(0);
655 case BGP4V2_NLRI_AFI
:
657 return SNMP_INTEGER(paf
->afi
);
659 return SNMP_INTEGER(0);
660 case BGP4V2_NLRI_SAFI
:
662 return SNMP_INTEGER(paf
->safi
);
664 return SNMP_INTEGER(0);
665 case BGP4V2_NLRI_PREFIX_TYPE
:
667 return SNMP_INTEGER(paf
->afi
);
669 return SNMP_INTEGER(0);
670 case BGP4V2_NLRI_PREFIX
:
671 if (prefix
->family
== AF_INET6
)
672 return SNMP_IP6ADDRESS(prefix
->u
.prefix6
);
674 return SNMP_IPADDRESS(prefix
->u
.prefix4
);
675 case BGP4V2_NLRI_PREFIX_LEN
:
676 return SNMP_INTEGER(prefix
->prefixlen
);
677 case BGP4V2_NLRI_BEST
:
678 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
679 return SNMP_INTEGER(1);
681 return SNMP_INTEGER(0);
682 case BGP4V2_NLRI_CALC_LOCAL_PREF
:
683 if (CHECK_FLAG(path
->attr
->flag
,
684 ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))
685 return SNMP_INTEGER(path
->attr
->local_pref
);
687 return SNMP_INTEGER(0);
688 case BGP4V2_NLRI_ORIGIN
:
689 switch (path
->attr
->origin
) {
691 return SNMP_INTEGER(1);
693 return SNMP_INTEGER(2);
694 case BGP_ORIGIN_INCOMPLETE
:
695 return SNMP_INTEGER(3);
697 return SNMP_INTEGER(0);
699 case BGP4V2_NLRI_NEXT_HOP_ADDR_TYPE
:
700 switch (path
->attr
->mp_nexthop_len
) {
701 case BGP_ATTR_NHLEN_IPV4
:
702 return SNMP_INTEGER(1);
703 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
704 return SNMP_INTEGER(2);
705 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
706 if (path
->attr
->mp_nexthop_prefer_global
)
707 return SNMP_INTEGER(2);
709 return SNMP_INTEGER(4);
711 return SNMP_INTEGER(1);
713 case BGP4V2_NLRI_NEXT_HOP_ADDR
:
714 switch (path
->attr
->mp_nexthop_len
) {
715 case BGP_ATTR_NHLEN_IPV4
:
716 return SNMP_IPADDRESS(path
->attr
->mp_nexthop_global_in
);
717 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
718 return SNMP_IP6ADDRESS(path
->attr
->mp_nexthop_global
);
719 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
720 if (path
->attr
->mp_nexthop_prefer_global
)
721 return SNMP_IP6ADDRESS(
722 path
->attr
->mp_nexthop_global
);
724 return SNMP_IP6ADDRESS(
725 path
->attr
->mp_nexthop_local
);
727 return SNMP_IPADDRESS(path
->attr
->nexthop
);
730 case BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR_TYPE
:
731 case BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR
:
732 /* Not properly defined in specification what should be here. */
734 case BGP4V2_NLRI_LOCAL_PREF_PRESENT
:
735 if (CHECK_FLAG(path
->attr
->flag
,
736 ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))
737 return SNMP_INTEGER(1);
739 return SNMP_INTEGER(0);
740 case BGP4V2_NLRI_LOCAL_PREF
:
741 if (CHECK_FLAG(path
->attr
->flag
,
742 ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))
743 return SNMP_INTEGER(path
->attr
->local_pref
);
745 return SNMP_INTEGER(0);
746 case BGP4V2_NLRI_MED_PRESENT
:
747 if (CHECK_FLAG(path
->attr
->flag
,
748 ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)))
749 return SNMP_INTEGER(1);
751 return SNMP_INTEGER(0);
752 case BGP4V2_NLRI_MED
:
753 if (CHECK_FLAG(path
->attr
->flag
,
754 ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)))
755 return SNMP_INTEGER(path
->attr
->med
);
757 return SNMP_INTEGER(0);
758 case BGP4V2_NLRI_ATOMIC_AGGREGATE
:
759 if (CHECK_FLAG(path
->attr
->flag
,
760 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)))
761 return SNMP_INTEGER(1);
763 return SNMP_INTEGER(0);
764 case BGP4V2_NLRI_AGGREGATOR_PRESENT
:
765 if (CHECK_FLAG(path
->attr
->flag
,
766 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
)))
767 return SNMP_INTEGER(1);
769 return SNMP_INTEGER(0);
770 case BGP4V2_NLRI_AGGREGATOR_AS
:
771 if (CHECK_FLAG(path
->attr
->flag
,
772 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
)))
773 return SNMP_INTEGER(path
->attr
->aggregator_as
);
775 return SNMP_INTEGER(0);
776 case BGP4V2_NLRI_AGGREGATOR_ADDR
:
777 if (CHECK_FLAG(path
->attr
->flag
,
778 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
)))
779 return SNMP_IPADDRESS(path
->attr
->aggregator_addr
);
781 return SNMP_IPADDRESS(bgp_empty_addr
);
782 case BGP4V2_NLRI_AS_PATH_CALC_LENGTH
:
783 return SNMP_INTEGER(path
->attr
->aspath
->segments
->length
);
784 case BGP4V2_NLRI_AS_PATH
:
785 return aspath_snmp_pathseg(path
->attr
->aspath
, var_len
);
786 case BGP4V2_NLRI_PATH_ATTR_UNKNOWN
:
793 static struct variable bgpv2_variables
[] = {
794 /* bgp4V2PeerEntry */
795 {BGP4V2_PEER_INSTANCE
,
800 {1, 2, 1, BGP4V2_PEER_INSTANCE
, 1, 4}},
801 {BGP4V2_PEER_INSTANCE
,
806 {1, 2, 1, BGP4V2_PEER_INSTANCE
, 2, 16}},
807 {BGP4V2_PEER_LOCAL_ADDR_TYPE
,
812 {1, 2, 1, BGP4V2_PEER_LOCAL_ADDR_TYPE
, 1, 4}},
813 {BGP4V2_PEER_LOCAL_ADDR_TYPE
,
818 {1, 2, 1, BGP4V2_PEER_LOCAL_ADDR_TYPE
, 2, 16}},
819 {BGP4V2_PEER_LOCAL_ADDR
,
824 {1, 2, 1, BGP4V2_PEER_LOCAL_ADDR
, 1, 4}},
825 {BGP4V2_PEER_LOCAL_ADDR
,
830 {1, 2, 1, BGP4V2_PEER_LOCAL_ADDR
, 2, 16}},
831 {BGP4V2_PEER_REMOTE_ADDR_TYPE
,
836 {1, 2, 1, BGP4V2_PEER_REMOTE_ADDR_TYPE
, 1, 4}},
837 {BGP4V2_PEER_REMOTE_ADDR_TYPE
,
842 {1, 2, 1, BGP4V2_PEER_REMOTE_ADDR_TYPE
, 2, 16}},
843 {BGP4V2_PEER_REMOTE_ADDR
,
848 {1, 2, 1, BGP4V2_PEER_REMOTE_ADDR
, 1, 4}},
849 {BGP4V2_PEER_REMOTE_ADDR
,
854 {1, 2, 1, BGP4V2_PEER_REMOTE_ADDR
, 2, 16}},
855 {BGP4V2_PEER_LOCAL_PORT
,
860 {1, 2, 1, BGP4V2_PEER_LOCAL_PORT
, 1, 4}},
861 {BGP4V2_PEER_LOCAL_PORT
,
866 {1, 2, 1, BGP4V2_PEER_LOCAL_PORT
, 2, 16}},
867 {BGP4V2_PEER_LOCAL_AS
,
872 {1, 2, 1, BGP4V2_PEER_LOCAL_AS
, 1, 4}},
873 {BGP4V2_PEER_LOCAL_AS
,
878 {1, 2, 1, BGP4V2_PEER_LOCAL_AS
, 2, 16}},
879 {BGP4V2_PEER_LOCAL_IDENTIFIER
,
884 {1, 2, 1, BGP4V2_PEER_LOCAL_IDENTIFIER
, 1, 4}},
885 {BGP4V2_PEER_LOCAL_IDENTIFIER
,
890 {1, 2, 1, BGP4V2_PEER_LOCAL_IDENTIFIER
, 2, 16}},
891 {BGP4V2_PEER_REMOTE_PORT
,
896 {1, 2, 1, BGP4V2_PEER_REMOTE_PORT
, 1, 4}},
897 {BGP4V2_PEER_REMOTE_PORT
,
902 {1, 2, 1, BGP4V2_PEER_REMOTE_PORT
, 2, 16}},
903 {BGP4V2_PEER_REMOTE_AS
,
908 {1, 2, 1, BGP4V2_PEER_REMOTE_AS
, 1, 4}},
909 {BGP4V2_PEER_REMOTE_AS
,
914 {1, 2, 1, BGP4V2_PEER_REMOTE_AS
, 2, 16}},
915 {BGP4V2_PEER_REMOTE_IDENTIFIER
,
920 {1, 2, 1, BGP4V2_PEER_REMOTE_IDENTIFIER
, 1, 4}},
921 {BGP4V2_PEER_REMOTE_IDENTIFIER
,
926 {1, 2, 1, BGP4V2_PEER_REMOTE_IDENTIFIER
, 2, 16}},
927 {BGP4V2_PEER_ADMIN_STATUS
,
932 {1, 2, 1, BGP4V2_PEER_ADMIN_STATUS
, 1, 4}},
933 {BGP4V2_PEER_ADMIN_STATUS
,
938 {1, 2, 1, BGP4V2_PEER_ADMIN_STATUS
, 2, 16}},
944 {1, 2, 1, BGP4V2_PEER_STATE
, 1, 4}},
950 {1, 2, 1, BGP4V2_PEER_STATE
, 2, 16}},
951 {BGP4V2_PEER_DESCRIPTION
,
956 {1, 2, 1, BGP4V2_PEER_DESCRIPTION
, 1, 4}},
957 {BGP4V2_PEER_DESCRIPTION
,
962 {1, 2, 1, BGP4V2_PEER_DESCRIPTION
, 2, 16}},
963 /* bgp4V2PeerErrorsEntry */
964 {BGP4V2_PEER_LAST_ERROR_CODE_RECEIVED
,
967 bgpv2PeerErrorsTable
,
969 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_CODE_RECEIVED
, 1, 4}},
970 {BGP4V2_PEER_LAST_ERROR_CODE_RECEIVED
,
973 bgpv2PeerErrorsTable
,
975 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_CODE_RECEIVED
, 2, 16}},
976 {BGP4V2_PEER_LAST_ERROR_SUBCODE_RECEIVED
,
979 bgpv2PeerErrorsTable
,
981 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SUBCODE_RECEIVED
, 1, 4}},
982 {BGP4V2_PEER_LAST_ERROR_SUBCODE_RECEIVED
,
985 bgpv2PeerErrorsTable
,
987 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SUBCODE_RECEIVED
, 2, 16}},
988 {BGP4V2_PEER_LAST_ERROR_RECEIVED_TIME
,
991 bgpv2PeerErrorsTable
,
993 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_TIME
, 1, 4}},
994 {BGP4V2_PEER_LAST_ERROR_RECEIVED_TIME
,
997 bgpv2PeerErrorsTable
,
999 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_TIME
, 2, 16}},
1000 {BGP4V2_PEER_LAST_ERROR_RECEIVED_TEXT
,
1003 bgpv2PeerErrorsTable
,
1005 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_TEXT
, 1, 4}},
1006 {BGP4V2_PEER_LAST_ERROR_RECEIVED_TEXT
,
1009 bgpv2PeerErrorsTable
,
1011 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_TEXT
, 2, 16}},
1012 {BGP4V2_PEER_LAST_ERROR_RECEIVED_DATA
,
1015 bgpv2PeerErrorsTable
,
1017 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_DATA
, 1, 4}},
1018 {BGP4V2_PEER_LAST_ERROR_RECEIVED_DATA
,
1021 bgpv2PeerErrorsTable
,
1023 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_RECEIVED_DATA
, 2, 16}},
1024 {BGP4V2_PEER_LAST_ERROR_CODE_SENT
,
1027 bgpv2PeerErrorsTable
,
1029 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_CODE_SENT
, 1, 4}},
1030 {BGP4V2_PEER_LAST_ERROR_CODE_SENT
,
1033 bgpv2PeerErrorsTable
,
1035 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_CODE_SENT
, 2, 16}},
1036 {BGP4V2_PEER_LAST_ERROR_SUBCODE_SENT
,
1039 bgpv2PeerErrorsTable
,
1041 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SUBCODE_SENT
, 1, 4}},
1042 {BGP4V2_PEER_LAST_ERROR_SUBCODE_SENT
,
1045 bgpv2PeerErrorsTable
,
1047 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SUBCODE_SENT
, 2, 16}},
1048 {BGP4V2_PEER_LAST_ERROR_SENT_TIME
,
1051 bgpv2PeerErrorsTable
,
1053 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_TIME
, 1, 4}},
1054 {BGP4V2_PEER_LAST_ERROR_SENT_TIME
,
1057 bgpv2PeerErrorsTable
,
1059 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_TIME
, 2, 16}},
1060 {BGP4V2_PEER_LAST_ERROR_SENT_TEXT
,
1063 bgpv2PeerErrorsTable
,
1065 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_TEXT
, 1, 4}},
1066 {BGP4V2_PEER_LAST_ERROR_SENT_TEXT
,
1069 bgpv2PeerErrorsTable
,
1071 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_TEXT
, 2, 16}},
1072 {BGP4V2_PEER_LAST_ERROR_SENT_DATA
,
1075 bgpv2PeerErrorsTable
,
1077 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_DATA
, 1, 4}},
1078 {BGP4V2_PEER_LAST_ERROR_SENT_DATA
,
1081 bgpv2PeerErrorsTable
,
1083 {1, 3, 1, BGP4V2_PEER_LAST_ERROR_SENT_DATA
, 2, 16}},
1084 /* bgp4V2PeerEventTimesEntry */
1085 {BGP4V2_PEER_FSM_ESTABLISHED_TIME
,
1088 bgpv2PeerEventTimesTable
,
1090 {1, 4, 1, BGP4V2_PEER_FSM_ESTABLISHED_TIME
, 1, 4}},
1091 {BGP4V2_PEER_FSM_ESTABLISHED_TIME
,
1094 bgpv2PeerEventTimesTable
,
1096 {1, 4, 1, BGP4V2_PEER_FSM_ESTABLISHED_TIME
, 2, 16}},
1097 {BGP4V2_PEER_PEER_IN_UPDATES_ELAPSED_TIME
,
1100 bgpv2PeerEventTimesTable
,
1102 {1, 4, 1, BGP4V2_PEER_PEER_IN_UPDATES_ELAPSED_TIME
, 1, 4}},
1103 {BGP4V2_PEER_PEER_IN_UPDATES_ELAPSED_TIME
,
1106 bgpv2PeerEventTimesTable
,
1108 {1, 4, 1, BGP4V2_PEER_PEER_IN_UPDATES_ELAPSED_TIME
, 2, 16}},
1109 /* bgp4V2NlriTable */
1113 bgp4v2PathAttrTable
,
1115 {1, 9, 1, BGP4V2_NLRI_INDEX
, 1, 4}},
1119 bgp4v2PathAttrTable
,
1121 {1, 9, 1, BGP4V2_NLRI_INDEX
, 2, 16}},
1125 bgp4v2PathAttrTable
,
1127 {1, 9, 1, BGP4V2_NLRI_AFI
, 1, 4}},
1131 bgp4v2PathAttrTable
,
1133 {1, 9, 1, BGP4V2_NLRI_AFI
, 2, 16}},
1137 bgp4v2PathAttrTable
,
1139 {1, 9, 1, BGP4V2_NLRI_SAFI
, 1, 4}},
1143 bgp4v2PathAttrTable
,
1145 {1, 9, 1, BGP4V2_NLRI_SAFI
, 2, 16}},
1146 {BGP4V2_NLRI_PREFIX_TYPE
,
1149 bgp4v2PathAttrTable
,
1151 {1, 9, 1, BGP4V2_NLRI_PREFIX_TYPE
, 1, 4}},
1152 {BGP4V2_NLRI_PREFIX_TYPE
,
1155 bgp4v2PathAttrTable
,
1157 {1, 9, 1, BGP4V2_NLRI_PREFIX_TYPE
, 2, 16}},
1158 {BGP4V2_NLRI_PREFIX
,
1161 bgp4v2PathAttrTable
,
1163 {1, 9, 1, BGP4V2_NLRI_PREFIX
, 1, 4}},
1164 {BGP4V2_NLRI_PREFIX
,
1167 bgp4v2PathAttrTable
,
1169 {1, 9, 1, BGP4V2_NLRI_PREFIX
, 2, 16}},
1170 {BGP4V2_NLRI_PREFIX_LEN
,
1173 bgp4v2PathAttrTable
,
1175 {1, 9, 1, BGP4V2_NLRI_PREFIX_LEN
, 1, 4}},
1176 {BGP4V2_NLRI_PREFIX_LEN
,
1179 bgp4v2PathAttrTable
,
1181 {1, 9, 1, BGP4V2_NLRI_PREFIX_LEN
, 2, 16}},
1185 bgp4v2PathAttrTable
,
1187 {1, 9, 1, BGP4V2_NLRI_BEST
, 1, 4}},
1191 bgp4v2PathAttrTable
,
1193 {1, 9, 1, BGP4V2_NLRI_BEST
, 2, 16}},
1194 {BGP4V2_NLRI_CALC_LOCAL_PREF
,
1197 bgp4v2PathAttrTable
,
1199 {1, 9, 1, BGP4V2_NLRI_CALC_LOCAL_PREF
, 1, 4}},
1200 {BGP4V2_NLRI_CALC_LOCAL_PREF
,
1203 bgp4v2PathAttrTable
,
1205 {1, 9, 1, BGP4V2_NLRI_CALC_LOCAL_PREF
, 2, 16}},
1206 {BGP4V2_NLRI_ORIGIN
,
1209 bgp4v2PathAttrTable
,
1211 {1, 9, 1, BGP4V2_NLRI_ORIGIN
, 1, 4}},
1212 {BGP4V2_NLRI_ORIGIN
,
1215 bgp4v2PathAttrTable
,
1217 {1, 9, 1, BGP4V2_NLRI_ORIGIN
, 2, 16}},
1218 {BGP4V2_NLRI_NEXT_HOP_ADDR_TYPE
,
1221 bgp4v2PathAttrTable
,
1223 {1, 9, 1, BGP4V2_NLRI_NEXT_HOP_ADDR_TYPE
, 1, 4}},
1224 {BGP4V2_NLRI_NEXT_HOP_ADDR_TYPE
,
1227 bgp4v2PathAttrTable
,
1229 {1, 9, 1, BGP4V2_NLRI_NEXT_HOP_ADDR_TYPE
, 2, 16}},
1230 {BGP4V2_NLRI_NEXT_HOP_ADDR
,
1233 bgp4v2PathAttrTable
,
1235 {1, 9, 1, BGP4V2_NLRI_NEXT_HOP_ADDR
, 1, 4}},
1236 {BGP4V2_NLRI_NEXT_HOP_ADDR
,
1239 bgp4v2PathAttrTable
,
1241 {1, 9, 1, BGP4V2_NLRI_NEXT_HOP_ADDR
, 2, 16}},
1242 {BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR_TYPE
,
1245 bgp4v2PathAttrTable
,
1247 {1, 9, 1, BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR_TYPE
, 1, 4}},
1248 {BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR_TYPE
,
1251 bgp4v2PathAttrTable
,
1253 {1, 9, 1, BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR_TYPE
, 2, 16}},
1254 {BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR
,
1257 bgp4v2PathAttrTable
,
1259 {1, 9, 1, BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR
, 1, 4}},
1260 {BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR
,
1263 bgp4v2PathAttrTable
,
1265 {1, 9, 1, BGP4V2_NLRI_LINK_LOCAL_NEXT_HOP_ADDR
, 2, 16}},
1266 {BGP4V2_NLRI_LOCAL_PREF_PRESENT
,
1269 bgp4v2PathAttrTable
,
1271 {1, 9, 1, BGP4V2_NLRI_LOCAL_PREF_PRESENT
, 1, 4}},
1272 {BGP4V2_NLRI_LOCAL_PREF_PRESENT
,
1275 bgp4v2PathAttrTable
,
1277 {1, 9, 1, BGP4V2_NLRI_LOCAL_PREF_PRESENT
, 2, 16}},
1278 {BGP4V2_NLRI_LOCAL_PREF
,
1281 bgp4v2PathAttrTable
,
1283 {1, 9, 1, BGP4V2_NLRI_LOCAL_PREF
, 1, 4}},
1284 {BGP4V2_NLRI_LOCAL_PREF
,
1287 bgp4v2PathAttrTable
,
1289 {1, 9, 1, BGP4V2_NLRI_LOCAL_PREF
, 2, 16}},
1290 {BGP4V2_NLRI_MED_PRESENT
,
1293 bgp4v2PathAttrTable
,
1295 {1, 9, 1, BGP4V2_NLRI_MED_PRESENT
, 1, 4}},
1296 {BGP4V2_NLRI_MED_PRESENT
,
1299 bgp4v2PathAttrTable
,
1301 {1, 9, 1, BGP4V2_NLRI_MED_PRESENT
, 2, 16}},
1305 bgp4v2PathAttrTable
,
1307 {1, 9, 1, BGP4V2_NLRI_MED
, 1, 4}},
1311 bgp4v2PathAttrTable
,
1313 {1, 9, 1, BGP4V2_NLRI_MED
, 2, 16}},
1314 {BGP4V2_NLRI_ATOMIC_AGGREGATE
,
1317 bgp4v2PathAttrTable
,
1319 {1, 9, 1, BGP4V2_NLRI_ATOMIC_AGGREGATE
, 1, 4}},
1320 {BGP4V2_NLRI_ATOMIC_AGGREGATE
,
1323 bgp4v2PathAttrTable
,
1325 {1, 9, 1, BGP4V2_NLRI_ATOMIC_AGGREGATE
, 2, 16}},
1326 {BGP4V2_NLRI_AGGREGATOR_PRESENT
,
1329 bgp4v2PathAttrTable
,
1331 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_PRESENT
, 1, 4}},
1332 {BGP4V2_NLRI_AGGREGATOR_PRESENT
,
1335 bgp4v2PathAttrTable
,
1337 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_PRESENT
, 2, 16}},
1338 {BGP4V2_NLRI_AGGREGATOR_AS
,
1341 bgp4v2PathAttrTable
,
1343 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_AS
, 1, 4}},
1344 {BGP4V2_NLRI_AGGREGATOR_AS
,
1347 bgp4v2PathAttrTable
,
1349 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_AS
, 2, 16}},
1350 {BGP4V2_NLRI_AGGREGATOR_ADDR
,
1353 bgp4v2PathAttrTable
,
1355 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_ADDR
, 1, 4}},
1356 {BGP4V2_NLRI_AGGREGATOR_ADDR
,
1359 bgp4v2PathAttrTable
,
1361 {1, 9, 1, BGP4V2_NLRI_AGGREGATOR_ADDR
, 2, 16}},
1362 {BGP4V2_NLRI_AS_PATH_CALC_LENGTH
,
1365 bgp4v2PathAttrTable
,
1367 {1, 9, 1, BGP4V2_NLRI_AS_PATH_CALC_LENGTH
, 1, 4}},
1368 {BGP4V2_NLRI_AS_PATH_CALC_LENGTH
,
1371 bgp4v2PathAttrTable
,
1373 {1, 9, 1, BGP4V2_NLRI_AS_PATH_CALC_LENGTH
, 2, 16}},
1374 {BGP4V2_NLRI_AS_PATH_STRING
,
1377 bgp4v2PathAttrTable
,
1379 {1, 9, 1, BGP4V2_NLRI_AS_PATH_STRING
, 1, 4}},
1380 {BGP4V2_NLRI_AS_PATH_STRING
,
1383 bgp4v2PathAttrTable
,
1385 {1, 9, 1, BGP4V2_NLRI_AS_PATH_STRING
, 2, 16}},
1386 {BGP4V2_NLRI_AS_PATH
,
1389 bgp4v2PathAttrTable
,
1391 {1, 9, 1, BGP4V2_NLRI_AS_PATH
, 1, 4}},
1392 {BGP4V2_NLRI_AS_PATH
,
1395 bgp4v2PathAttrTable
,
1397 {1, 9, 1, BGP4V2_NLRI_AS_PATH
, 2, 16}},
1398 {BGP4V2_NLRI_PATH_ATTR_UNKNOWN
,
1401 bgp4v2PathAttrTable
,
1403 {1, 9, 1, BGP4V2_NLRI_PATH_ATTR_UNKNOWN
, 1, 4}},
1404 {BGP4V2_NLRI_PATH_ATTR_UNKNOWN
,
1407 bgp4v2PathAttrTable
,
1409 {1, 9, 1, BGP4V2_NLRI_PATH_ATTR_UNKNOWN
, 2, 16}},
1412 int bgp_snmp_bgp4v2_init(struct thread_master
*tm
)
1414 REGISTER_MIB("mibII/bgpv2", bgpv2_variables
, variable
, bgpv2_oid
);