1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 1999, 2000 Kunihiro Ishiguro
8 #include <net-snmp/net-snmp-config.h>
9 #include <net-snmp/net-snmp-includes.h>
21 #include "bgpd/bgpd.h"
22 #include "bgpd/bgp_table.h"
23 #include "bgpd/bgp_aspath.h"
24 #include "bgpd/bgp_attr.h"
25 #include "bgpd/bgp_route.h"
26 #include "bgpd/bgp_fsm.h"
27 #include "bgpd/bgp_snmp.h"
28 #include "bgpd/bgp_snmp_bgp4.h"
29 #include "bgpd/bgp_mplsvpn_snmp.h"
31 /* Declare static local variables for convenience. */
34 /* BGP-MIB instances. */
35 static oid bgp_oid
[] = {BGP4MIB
};
36 static oid bgp_trap_oid
[] = {BGP4MIB
, 0};
38 /* IP address 0.0.0.0. */
39 static struct in_addr bgp_empty_addr
= {.s_addr
= 0};
41 static uint8_t *bgpVersion(struct variable
*v
, oid name
[], size_t *length
,
42 int exact
, size_t *var_len
,
43 WriteMethod
**write_method
)
45 static uint8_t version
;
47 if (smux_header_generic(v
, name
, length
, exact
, var_len
,
48 write_method
) == MATCH_FAILED
)
51 /* Return BGP version. Zebra bgpd only support version 4. */
52 version
= (0x80 >> (BGP_VERSION_4
- 1));
54 /* Return octet string length 1. */
59 static uint8_t *bgpLocalAs(struct variable
*v
, oid name
[], size_t *length
,
60 int exact
, size_t *var_len
,
61 WriteMethod
**write_method
)
65 if (smux_header_generic(v
, name
, length
, exact
, var_len
,
66 write_method
) == MATCH_FAILED
)
69 /* Get BGP structure. */
70 bgp
= bgp_get_default();
74 return SNMP_INTEGER(bgp
->as
);
77 static struct peer
*peer_lookup_addr_ipv4(struct in_addr
*src
)
81 struct listnode
*node
;
82 struct listnode
*bgpnode
;
84 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
85 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
86 if (sockunion_family(&peer
->su
) != AF_INET
)
89 if (sockunion2ip(&peer
->su
) == src
->s_addr
)
97 static struct peer
*bgp_peer_lookup_next(struct in_addr
*src
)
101 struct peer
*next_peer
= NULL
;
102 struct listnode
*node
;
103 struct listnode
*bgpnode
;
105 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, bgpnode
, bgp
)) {
106 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
107 if (sockunion_family(&peer
->su
) != AF_INET
)
109 if (ntohl(sockunion2ip(&peer
->su
)) <=
114 ntohl(sockunion2ip(&next_peer
->su
)) >
115 ntohl(sockunion2ip(&peer
->su
))) {
122 src
->s_addr
= sockunion2ip(&next_peer
->su
);
129 /* 1.3.6.1.2.1.15.3.1.x = 10 */
130 #define PEERTAB_NAMELEN 10
132 static struct peer
*bgpPeerTable_lookup(struct variable
*v
, oid name
[],
133 size_t *length
, struct in_addr
*addr
,
136 struct peer
*peer
= NULL
;
137 size_t namelen
= v
? v
->namelen
: PEERTAB_NAMELEN
;
141 /* Check the length. */
142 if (*length
- namelen
!= sizeof(struct in_addr
))
145 oid2in_addr(name
+ namelen
, IN_ADDR_SIZE
, addr
);
147 peer
= peer_lookup_addr_ipv4(addr
);
150 len
= *length
- namelen
;
154 oid2in_addr(name
+ namelen
, len
, addr
);
156 peer
= bgp_peer_lookup_next(addr
);
161 oid_copy_in_addr(name
+ namelen
, addr
);
162 *length
= sizeof(struct in_addr
) + namelen
;
169 /* BGP write methods. */
170 static int write_bgpPeerTable(int action
, uint8_t *var_val
,
171 uint8_t var_val_type
, size_t var_val_len
,
172 uint8_t *statP
, oid
*name
, size_t length
)
178 if (var_val_type
!= ASN_INTEGER
) {
179 return SNMP_ERR_WRONGTYPE
;
181 if (var_val_len
!= sizeof(long)) {
182 return SNMP_ERR_WRONGLENGTH
;
185 intval
= *(long *)var_val
;
187 memset(&addr
, 0, sizeof(addr
));
189 peer
= bgpPeerTable_lookup(NULL
, name
, &length
, &addr
, 1);
191 return SNMP_ERR_NOSUCHNAME
;
193 if (action
!= SNMP_MSG_INTERNAL_SET_COMMIT
)
194 return SNMP_ERR_NOERROR
;
196 zlog_info("%s: SNMP write .%ld = %ld", peer
->host
,
197 (long)name
[PEERTAB_NAMELEN
- 1], intval
);
199 switch (name
[PEERTAB_NAMELEN
- 1]) {
200 case BGPPEERADMINSTATUS
:
201 #define BGP_PeerAdmin_stop 1
202 #define BGP_PeerAdmin_start 2
203 /* When the peer is established, */
204 if (intval
== BGP_PeerAdmin_stop
)
205 BGP_EVENT_ADD(peer
, BGP_Stop
);
206 else if (intval
== BGP_PeerAdmin_start
)
209 return SNMP_ERR_NOSUCHNAME
;
211 case BGPPEERCONNECTRETRYINTERVAL
:
212 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
213 peer
->connect
= intval
;
214 peer
->v_connect
= intval
;
216 case BGPPEERHOLDTIMECONFIGURED
:
217 peer_flag_set(peer
, PEER_FLAG_TIMER
);
218 peer
->holdtime
= intval
;
219 peer
->v_holdtime
= intval
;
221 case BGPPEERKEEPALIVECONFIGURED
:
222 peer_flag_set(peer
, PEER_FLAG_TIMER
);
223 peer
->keepalive
= intval
;
224 peer
->v_keepalive
= intval
;
226 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
227 peer
->v_routeadv
= intval
;
230 return SNMP_ERR_NOERROR
;
233 static uint8_t *bgpPeerTable(struct variable
*v
, oid name
[], size_t *length
,
234 int exact
, size_t *var_len
,
235 WriteMethod
**write_method
)
237 static struct in_addr addr
;
241 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
244 memset(&addr
, 0, sizeof(addr
));
246 peer
= bgpPeerTable_lookup(v
, name
, length
, &addr
, exact
);
251 case BGPPEERIDENTIFIER
:
252 return SNMP_IPADDRESS(peer
->remote_id
);
254 return SNMP_INTEGER(peer
->status
);
255 case BGPPEERADMINSTATUS
:
256 *write_method
= write_bgpPeerTable
;
257 #define BGP_PeerAdmin_stop 1
258 #define BGP_PeerAdmin_start 2
259 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
260 return SNMP_INTEGER(BGP_PeerAdmin_stop
);
262 return SNMP_INTEGER(BGP_PeerAdmin_start
);
263 case BGPPEERNEGOTIATEDVERSION
:
264 return SNMP_INTEGER(BGP_VERSION_4
);
265 case BGPPEERLOCALADDR
:
267 return SNMP_IPADDRESS(peer
->su_local
->sin
.sin_addr
);
269 return SNMP_IPADDRESS(bgp_empty_addr
);
270 case BGPPEERLOCALPORT
:
273 ntohs(peer
->su_local
->sin
.sin_port
));
275 return SNMP_INTEGER(0);
276 case BGPPEERREMOTEADDR
:
278 return SNMP_IPADDRESS(peer
->su_remote
->sin
.sin_addr
);
280 return SNMP_IPADDRESS(bgp_empty_addr
);
281 case BGPPEERREMOTEPORT
:
284 ntohs(peer
->su_remote
->sin
.sin_port
));
286 return SNMP_INTEGER(0);
287 case BGPPEERREMOTEAS
:
288 return SNMP_INTEGER(peer
->as
);
289 case BGPPEERINUPDATES
:
290 ui
= atomic_load_explicit(&peer
->update_in
,
291 memory_order_relaxed
);
292 return SNMP_INTEGER(ui
);
293 case BGPPEEROUTUPDATES
:
294 uo
= atomic_load_explicit(&peer
->update_out
,
295 memory_order_relaxed
);
296 return SNMP_INTEGER(uo
);
297 case BGPPEERINTOTALMESSAGES
:
298 return SNMP_INTEGER(PEER_TOTAL_RX(peer
));
299 case BGPPEEROUTTOTALMESSAGES
:
300 return SNMP_INTEGER(PEER_TOTAL_TX(peer
));
301 case BGPPEERLASTERROR
: {
302 static uint8_t lasterror
[2];
303 lasterror
[0] = peer
->notify
.code
;
304 lasterror
[1] = peer
->notify
.subcode
;
306 return (uint8_t *)&lasterror
;
308 case BGPPEERFSMESTABLISHEDTRANSITIONS
:
309 return SNMP_INTEGER(peer
->established
);
310 case BGPPEERFSMESTABLISHEDTIME
:
311 if (peer
->uptime
== 0)
312 return SNMP_INTEGER(0);
314 return SNMP_INTEGER(monotime(NULL
) - peer
->uptime
);
315 case BGPPEERCONNECTRETRYINTERVAL
:
316 *write_method
= write_bgpPeerTable
;
317 return SNMP_INTEGER(peer
->v_connect
);
318 case BGPPEERHOLDTIME
:
319 return SNMP_INTEGER(peer
->v_holdtime
);
320 case BGPPEERKEEPALIVE
:
321 return SNMP_INTEGER(peer
->v_keepalive
);
322 case BGPPEERHOLDTIMECONFIGURED
:
323 *write_method
= write_bgpPeerTable
;
324 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
325 return SNMP_INTEGER(peer
->holdtime
);
327 return SNMP_INTEGER(peer
->v_holdtime
);
328 case BGPPEERKEEPALIVECONFIGURED
:
329 *write_method
= write_bgpPeerTable
;
330 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
331 return SNMP_INTEGER(peer
->keepalive
);
333 return SNMP_INTEGER(peer
->v_keepalive
);
334 case BGPPEERMINROUTEADVERTISEMENTINTERVAL
:
335 *write_method
= write_bgpPeerTable
;
336 return SNMP_INTEGER(peer
->v_routeadv
);
337 case BGPPEERINUPDATEELAPSEDTIME
:
338 if (peer
->update_time
== 0)
339 return SNMP_INTEGER(0);
341 return SNMP_INTEGER(monotime(NULL
) - peer
->update_time
);
348 static uint8_t *bgpIdentifier(struct variable
*v
, oid name
[], size_t *length
,
349 int exact
, size_t *var_len
,
350 WriteMethod
**write_method
)
354 if (smux_header_generic(v
, name
, length
, exact
, var_len
,
355 write_method
) == MATCH_FAILED
)
358 bgp
= bgp_get_default();
362 return SNMP_IPADDRESS(bgp
->router_id
);
365 static uint8_t *bgpRcvdPathAttrTable(struct variable
*v
, oid name
[],
366 size_t *length
, int exact
, size_t *var_len
,
367 WriteMethod
**write_method
)
369 /* Received Path Attribute Table. This table contains, one entry
370 per path to a network, path attributes received from all peers
371 running BGP version 3 or less. This table is obsolete, having
372 been replaced in functionality with the bgp4PathAttrTable. */
376 static struct bgp_path_info
*bgp4PathAttrLookup(struct variable
*v
, oid name
[],
377 size_t *length
, struct bgp
*bgp
,
378 struct prefix_ipv4
*addr
,
383 struct bgp_path_info
*path
;
384 struct bgp_path_info
*min
;
385 struct bgp_dest
*dest
;
388 struct in_addr paddr
;
392 #define BGP_PATHATTR_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
395 if (*length
- v
->namelen
!= BGP_PATHATTR_ENTRY_OFFSET
)
398 /* Set OID offset for prefix. */
399 offset
= name
+ v
->namelen
;
400 oid2in_addr(offset
, IN_ADDR_SIZE
, &addr
->prefix
);
401 offset
+= IN_ADDR_SIZE
;
404 addr
->prefixlen
= *offset
;
408 su
.sin
.sin_family
= AF_INET
;
409 oid2in_addr(offset
, IN_ADDR_SIZE
, &su
.sin
.sin_addr
);
412 dest
= bgp_node_lookup(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
413 (struct prefix
*)addr
);
415 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
417 if (sockunion_same(&path
->peer
->su
, &su
))
420 bgp_dest_unlock_node(dest
);
423 offset
= name
+ v
->namelen
;
424 offsetlen
= *length
- v
->namelen
;
428 dest
= bgp_table_top(bgp
->rib
[AFI_IP
][SAFI_UNICAST
]);
430 if (len
> IN_ADDR_SIZE
)
433 oid2in_addr(offset
, len
, &addr
->prefix
);
435 offset
+= IN_ADDR_SIZE
;
436 offsetlen
-= IN_ADDR_SIZE
;
439 addr
->prefixlen
= *offset
;
441 addr
->prefixlen
= len
* 8;
443 dest
= bgp_node_get(bgp
->rib
[AFI_IP
][SAFI_UNICAST
],
444 (struct prefix
*)addr
);
452 if (len
> IN_ADDR_SIZE
)
455 oid2in_addr(offset
, len
, &paddr
);
457 paddr
.s_addr
= INADDR_ANY
;
465 for (path
= bgp_dest_get_bgp_path_info(dest
); path
;
467 if (path
->peer
->su
.sin
.sin_family
== AF_INET
&&
468 ntohl(paddr
.s_addr
) <
469 ntohl(path
->peer
->su
.sin
.sin_addr
472 if (ntohl(path
->peer
->su
.sin
475 ntohl(min
->peer
->su
.sin
485 const struct prefix
*rn_p
=
486 bgp_dest_get_prefix(dest
);
489 v
->namelen
+ BGP_PATHATTR_ENTRY_OFFSET
;
491 offset
= name
+ v
->namelen
;
492 oid_copy_in_addr(offset
, &rn_p
->u
.prefix4
);
493 offset
+= IN_ADDR_SIZE
;
494 *offset
= rn_p
->prefixlen
;
496 oid_copy_in_addr(offset
,
497 &min
->peer
->su
.sin
.sin_addr
);
498 addr
->prefix
= rn_p
->u
.prefix4
;
499 addr
->prefixlen
= rn_p
->prefixlen
;
501 bgp_dest_unlock_node(dest
);
506 paddr
.s_addr
= INADDR_ANY
;
507 } while ((dest
= bgp_route_next(dest
)) != NULL
);
512 static uint8_t *bgp4PathAttrTable(struct variable
*v
, oid name
[],
513 size_t *length
, int exact
, size_t *var_len
,
514 WriteMethod
**write_method
)
517 struct bgp_path_info
*path
;
518 struct prefix_ipv4 addr
;
520 bgp
= bgp_get_default();
524 if (smux_header_table(v
, name
, length
, exact
, var_len
, write_method
) ==
527 memset(&addr
, 0, sizeof(addr
));
529 path
= bgp4PathAttrLookup(v
, name
, length
, bgp
, &addr
, exact
);
534 case BGP4PATHATTRPEER
: /* 1 */
535 return SNMP_IPADDRESS(path
->peer
->su
.sin
.sin_addr
);
536 case BGP4PATHATTRIPADDRPREFIXLEN
: /* 2 */
537 return SNMP_INTEGER(addr
.prefixlen
);
538 case BGP4PATHATTRIPADDRPREFIX
: /* 3 */
539 return SNMP_IPADDRESS(addr
.prefix
);
540 case BGP4PATHATTRORIGIN
: /* 4 */
541 return SNMP_INTEGER(path
->attr
->origin
);
542 case BGP4PATHATTRASPATHSEGMENT
: /* 5 */
543 return aspath_snmp_pathseg(path
->attr
->aspath
, var_len
);
544 case BGP4PATHATTRNEXTHOP
: /* 6 */
545 return SNMP_IPADDRESS(path
->attr
->nexthop
);
546 case BGP4PATHATTRMULTIEXITDISC
: /* 7 */
547 return SNMP_INTEGER(path
->attr
->med
);
548 case BGP4PATHATTRLOCALPREF
: /* 8 */
549 return SNMP_INTEGER(path
->attr
->local_pref
);
550 case BGP4PATHATTRATOMICAGGREGATE
: /* 9 */
551 return SNMP_INTEGER(1);
552 case BGP4PATHATTRAGGREGATORAS
: /* 10 */
553 return SNMP_INTEGER(path
->attr
->aggregator_as
);
554 case BGP4PATHATTRAGGREGATORADDR
: /* 11 */
555 return SNMP_IPADDRESS(path
->attr
->aggregator_addr
);
556 case BGP4PATHATTRCALCLOCALPREF
: /* 12 */
557 return SNMP_INTEGER(-1);
558 case BGP4PATHATTRBEST
: /* 13 */
559 #define BGP4_PathAttrBest_false 1
560 #define BGP4_PathAttrBest_true 2
561 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
562 return SNMP_INTEGER(BGP4_PathAttrBest_true
);
564 return SNMP_INTEGER(BGP4_PathAttrBest_false
);
565 case BGP4PATHATTRUNKNOWN
: /* 14 */
573 static struct trap_object bgpTrapList
[] = {{3, {3, 1, BGPPEERREMOTEADDR
}},
574 {3, {3, 1, BGPPEERLASTERROR
}},
575 {3, {3, 1, BGPPEERSTATE
}}};
577 static struct variable bgp_variables
[] = {
579 {BGPVERSION
, OCTET_STRING
, RONLY
, bgpVersion
, 1, {1}},
581 {BGPLOCALAS
, INTEGER
, RONLY
, bgpLocalAs
, 1, {2}},
582 /* BGP peer table. */
583 {BGPPEERIDENTIFIER
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 1}},
584 {BGPPEERSTATE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 2}},
585 {BGPPEERADMINSTATUS
, INTEGER
, RWRITE
, bgpPeerTable
, 3, {3, 1, 3}},
586 {BGPPEERNEGOTIATEDVERSION
,
592 {BGPPEERLOCALADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 5}},
593 {BGPPEERLOCALPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 6}},
594 {BGPPEERREMOTEADDR
, IPADDRESS
, RONLY
, bgpPeerTable
, 3, {3, 1, 7}},
595 {BGPPEERREMOTEPORT
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 8}},
596 {BGPPEERREMOTEAS
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 9}},
597 {BGPPEERINUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 10}},
598 {BGPPEEROUTUPDATES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 11}},
599 {BGPPEERINTOTALMESSAGES
, COUNTER32
, RONLY
, bgpPeerTable
, 3, {3, 1, 12}},
600 {BGPPEEROUTTOTALMESSAGES
,
606 {BGPPEERLASTERROR
, OCTET_STRING
, RONLY
, bgpPeerTable
, 3, {3, 1, 14}},
607 {BGPPEERFSMESTABLISHEDTRANSITIONS
,
613 {BGPPEERFSMESTABLISHEDTIME
,
619 {BGPPEERCONNECTRETRYINTERVAL
,
625 {BGPPEERHOLDTIME
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 18}},
626 {BGPPEERKEEPALIVE
, INTEGER
, RONLY
, bgpPeerTable
, 3, {3, 1, 19}},
627 {BGPPEERHOLDTIMECONFIGURED
,
633 {BGPPEERKEEPALIVECONFIGURED
,
639 {BGPPEERMINROUTEADVERTISEMENTINTERVAL
,
645 {BGPPEERINUPDATEELAPSEDTIME
,
651 /* BGP identifier. */
652 {BGPIDENTIFIER
, IPADDRESS
, RONLY
, bgpIdentifier
, 1, {4}},
653 /* BGP received path attribute table. */
654 {BGPPATHATTRPEER
, IPADDRESS
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 1}},
655 {BGPPATHATTRDESTNETWORK
,
658 bgpRcvdPathAttrTable
,
661 {BGPPATHATTRORIGIN
, INTEGER
, RONLY
, bgpRcvdPathAttrTable
, 3, {5, 1, 3}},
665 bgpRcvdPathAttrTable
,
671 bgpRcvdPathAttrTable
,
674 {BGPPATHATTRINTERASMETRIC
,
677 bgpRcvdPathAttrTable
,
680 /* BGP-4 received path attribute table. */
681 {BGP4PATHATTRPEER
, IPADDRESS
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 1}},
682 {BGP4PATHATTRIPADDRPREFIXLEN
,
688 {BGP4PATHATTRIPADDRPREFIX
,
694 {BGP4PATHATTRORIGIN
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 4}},
695 {BGP4PATHATTRASPATHSEGMENT
,
701 {BGP4PATHATTRNEXTHOP
,
707 {BGP4PATHATTRMULTIEXITDISC
,
713 {BGP4PATHATTRLOCALPREF
,
719 {BGP4PATHATTRATOMICAGGREGATE
,
725 {BGP4PATHATTRAGGREGATORAS
,
731 {BGP4PATHATTRAGGREGATORADDR
,
737 {BGP4PATHATTRCALCLOCALPREF
,
743 {BGP4PATHATTRBEST
, INTEGER
, RONLY
, bgp4PathAttrTable
, 3, {6, 1, 13}},
744 {BGP4PATHATTRUNKNOWN
,
752 int bgpTrapEstablished(struct peer
*peer
)
756 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
758 /* Check if this peer just went to Established */
759 if ((peer
->ostatus
!= OpenConfirm
) || !(peer_established(peer
)))
762 ret
= inet_aton(peer
->host
, &addr
);
766 oid_copy_in_addr(index
, &addr
);
768 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
769 array_size(bgp_trap_oid
), bgp_oid
,
770 sizeof(bgp_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
,
771 bgpTrapList
, array_size(bgpTrapList
), BGPESTABLISHED
);
775 int bgpTrapBackwardTransition(struct peer
*peer
)
779 oid index
[sizeof(oid
) * IN_ADDR_SIZE
];
781 ret
= inet_aton(peer
->host
, &addr
);
785 oid_copy_in_addr(index
, &addr
);
787 smux_trap(bgp_variables
, array_size(bgp_variables
), bgp_trap_oid
,
788 array_size(bgp_trap_oid
), bgp_oid
,
789 sizeof(bgp_oid
) / sizeof(oid
), index
, IN_ADDR_SIZE
,
790 bgpTrapList
, array_size(bgpTrapList
), BGPBACKWARDTRANSITION
);
794 int bgp_snmp_bgp4_init(struct event_loop
*tm
)
796 REGISTER_MIB("mibII/bgp", bgp_variables
, variable
, bgp_oid
);