Annotation of embedaddon/quagga/bgpd/bgp_snmp.c, revision 1.1.1.3
1.1 misho 1: /* BGP4 SNMP support
2: Copyright (C) 1999, 2000 Kunihiro Ishiguro
3:
4: This file is part of GNU Zebra.
5:
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
9: later version.
10:
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.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU Zebra; see the file COPYING. If not, write to the Free
18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: 02111-1307, USA. */
20:
21: #include <zebra.h>
22:
23: #ifdef HAVE_SNMP
24: #include <net-snmp/net-snmp-config.h>
25: #include <net-snmp/net-snmp-includes.h>
26:
27: #include "if.h"
28: #include "log.h"
29: #include "prefix.h"
30: #include "command.h"
31: #include "thread.h"
32: #include "smux.h"
1.1.1.3 ! misho 33: #include "filter.h"
1.1 misho 34:
35: #include "bgpd/bgpd.h"
36: #include "bgpd/bgp_table.h"
37: #include "bgpd/bgp_aspath.h"
38: #include "bgpd/bgp_attr.h"
39: #include "bgpd/bgp_route.h"
40: #include "bgpd/bgp_fsm.h"
41: #include "bgpd/bgp_snmp.h"
1.1.1.3 ! misho 42:
1.1 misho 43: /* BGP4-MIB described in RFC1657. */
44: #define BGP4MIB 1,3,6,1,2,1,15
45:
46: /* BGP TRAP. */
47: #define BGPESTABLISHED 1
48: #define BGPBACKWARDTRANSITION 2
49:
50: /* BGP MIB bgpVersion. */
51: #define BGPVERSION 0
52:
53: /* BGP MIB bgpLocalAs. */
54: #define BGPLOCALAS 0
55:
56: /* BGP MIB bgpPeerTable. */
57: #define BGPPEERIDENTIFIER 1
58: #define BGPPEERSTATE 2
59: #define BGPPEERADMINSTATUS 3
60: #define BGPPEERNEGOTIATEDVERSION 4
61: #define BGPPEERLOCALADDR 5
62: #define BGPPEERLOCALPORT 6
63: #define BGPPEERREMOTEADDR 7
64: #define BGPPEERREMOTEPORT 8
65: #define BGPPEERREMOTEAS 9
66: #define BGPPEERINUPDATES 10
67: #define BGPPEEROUTUPDATES 11
68: #define BGPPEERINTOTALMESSAGES 12
69: #define BGPPEEROUTTOTALMESSAGES 13
70: #define BGPPEERLASTERROR 14
71: #define BGPPEERFSMESTABLISHEDTRANSITIONS 15
72: #define BGPPEERFSMESTABLISHEDTIME 16
73: #define BGPPEERCONNECTRETRYINTERVAL 17
74: #define BGPPEERHOLDTIME 18
75: #define BGPPEERKEEPALIVE 19
76: #define BGPPEERHOLDTIMECONFIGURED 20
77: #define BGPPEERKEEPALIVECONFIGURED 21
1.1.1.3 ! misho 78: #define BGPPEERMINROUTEADVERTISEMENTINTERVAL 22
! 79: #define BGPPEERINUPDATEELAPSEDTIME 23
1.1 misho 80:
81: /* BGP MIB bgpIdentifier. */
82: #define BGPIDENTIFIER 0
83:
84: /* BGP MIB bgpRcvdPathAttrTable */
85: #define BGPPATHATTRPEER 1
86: #define BGPPATHATTRDESTNETWORK 2
87: #define BGPPATHATTRORIGIN 3
88: #define BGPPATHATTRASPATH 4
89: #define BGPPATHATTRNEXTHOP 5
90: #define BGPPATHATTRINTERASMETRIC 6
91:
92: /* BGP MIB bgp4PathAttrTable. */
93: #define BGP4PATHATTRPEER 1
94: #define BGP4PATHATTRIPADDRPREFIXLEN 2
95: #define BGP4PATHATTRIPADDRPREFIX 3
96: #define BGP4PATHATTRORIGIN 4
97: #define BGP4PATHATTRASPATHSEGMENT 5
98: #define BGP4PATHATTRNEXTHOP 6
99: #define BGP4PATHATTRMULTIEXITDISC 7
100: #define BGP4PATHATTRLOCALPREF 8
101: #define BGP4PATHATTRATOMICAGGREGATE 9
102: #define BGP4PATHATTRAGGREGATORAS 10
103: #define BGP4PATHATTRAGGREGATORADDR 11
104: #define BGP4PATHATTRCALCLOCALPREF 12
105: #define BGP4PATHATTRBEST 13
106: #define BGP4PATHATTRUNKNOWN 14
107:
108: /* SNMP value hack. */
109: #define INTEGER ASN_INTEGER
110: #define INTEGER32 ASN_INTEGER
111: #define COUNTER32 ASN_COUNTER
112: #define OCTET_STRING ASN_OCTET_STR
113: #define IPADDRESS ASN_IPADDRESS
114: #define GAUGE32 ASN_UNSIGNED
1.1.1.3 ! misho 115:
1.1 misho 116: /* Declare static local variables for convenience. */
117: SNMP_LOCAL_VARIABLES
118:
119: /* BGP-MIB instances. */
120: oid bgp_oid [] = { BGP4MIB };
1.1.1.2 misho 121: oid bgp_trap_oid [] = { BGP4MIB, 0 };
1.1 misho 122:
123: /* IP address 0.0.0.0. */
1.1.1.3 ! misho 124: static struct in_addr bgp_empty_addr = { .s_addr = 0 };
1.1 misho 125:
126: /* Hook functions. */
127: static u_char *bgpVersion (struct variable *, oid [], size_t *, int,
128: size_t *, WriteMethod **);
129: static u_char *bgpLocalAs (struct variable *, oid [], size_t *,
130: int, size_t *, WriteMethod **);
131: static u_char *bgpPeerTable (struct variable *, oid [], size_t *,
132: int, size_t *, WriteMethod **);
133: static u_char *bgpRcvdPathAttrTable (struct variable *, oid [], size_t *,
134: int, size_t *, WriteMethod **);
135: static u_char *bgpIdentifier (struct variable *, oid [], size_t *,
136: int, size_t *, WriteMethod **);
137: static u_char *bgp4PathAttrTable (struct variable *, oid [], size_t *,
138: int, size_t *, WriteMethod **);
139: /* static u_char *bgpTraps (); */
140:
141: struct variable bgp_variables[] =
142: {
143: /* BGP version. */
144: {BGPVERSION, OCTET_STRING, RONLY, bgpVersion,
145: 1, {1}},
146: /* BGP local AS. */
147: {BGPLOCALAS, INTEGER, RONLY, bgpLocalAs,
148: 1, {2}},
149: /* BGP peer table. */
150: {BGPPEERIDENTIFIER, IPADDRESS, RONLY, bgpPeerTable,
151: 3, {3, 1, 1}},
152: {BGPPEERSTATE, INTEGER, RONLY, bgpPeerTable,
153: 3, {3, 1, 2}},
154: {BGPPEERADMINSTATUS, INTEGER, RWRITE, bgpPeerTable,
155: 3, {3, 1, 3}},
156: {BGPPEERNEGOTIATEDVERSION, INTEGER32, RONLY, bgpPeerTable,
157: 3, {3, 1, 4}},
158: {BGPPEERLOCALADDR, IPADDRESS, RONLY, bgpPeerTable,
159: 3, {3, 1, 5}},
160: {BGPPEERLOCALPORT, INTEGER, RONLY, bgpPeerTable,
161: 3, {3, 1, 6}},
162: {BGPPEERREMOTEADDR, IPADDRESS, RONLY, bgpPeerTable,
163: 3, {3, 1, 7}},
164: {BGPPEERREMOTEPORT, INTEGER, RONLY, bgpPeerTable,
165: 3, {3, 1, 8}},
166: {BGPPEERREMOTEAS, INTEGER, RONLY, bgpPeerTable,
167: 3, {3, 1, 9}},
168: {BGPPEERINUPDATES, COUNTER32, RONLY, bgpPeerTable,
169: 3, {3, 1, 10}},
170: {BGPPEEROUTUPDATES, COUNTER32, RONLY, bgpPeerTable,
171: 3, {3, 1, 11}},
172: {BGPPEERINTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
173: 3, {3, 1, 12}},
174: {BGPPEEROUTTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
175: 3, {3, 1, 13}},
176: {BGPPEERLASTERROR, OCTET_STRING, RONLY, bgpPeerTable,
177: 3, {3, 1, 14}},
178: {BGPPEERFSMESTABLISHEDTRANSITIONS, COUNTER32, RONLY, bgpPeerTable,
179: 3, {3, 1, 15}},
180: {BGPPEERFSMESTABLISHEDTIME, GAUGE32, RONLY, bgpPeerTable,
181: 3, {3, 1, 16}},
182: {BGPPEERCONNECTRETRYINTERVAL, INTEGER, RWRITE, bgpPeerTable,
183: 3, {3, 1, 17}},
184: {BGPPEERHOLDTIME, INTEGER, RONLY, bgpPeerTable,
185: 3, {3, 1, 18}},
186: {BGPPEERKEEPALIVE, INTEGER, RONLY, bgpPeerTable,
187: 3, {3, 1, 19}},
188: {BGPPEERHOLDTIMECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
189: 3, {3, 1, 20}},
190: {BGPPEERKEEPALIVECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
191: 3, {3, 1, 21}},
192: {BGPPEERMINROUTEADVERTISEMENTINTERVAL, INTEGER, RWRITE, bgpPeerTable,
193: 3, {3, 1, 23}},
194: {BGPPEERINUPDATEELAPSEDTIME, GAUGE32, RONLY, bgpPeerTable,
195: 3, {3, 1, 24}},
196: /* BGP identifier. */
197: {BGPIDENTIFIER, IPADDRESS, RONLY, bgpIdentifier,
198: 1, {4}},
199: /* BGP received path attribute table. */
200: {BGPPATHATTRPEER, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
201: 3, {5, 1, 1}},
202: {BGPPATHATTRDESTNETWORK, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
203: 3, {5, 1, 2}},
204: {BGPPATHATTRORIGIN, INTEGER, RONLY, bgpRcvdPathAttrTable,
205: 3, {5, 1, 3}},
206: {BGPPATHATTRASPATH, OCTET_STRING, RONLY, bgpRcvdPathAttrTable,
207: 3, {5, 1, 4}},
208: {BGPPATHATTRNEXTHOP, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
209: 3, {5, 1, 5}},
210: {BGPPATHATTRINTERASMETRIC, INTEGER32, RONLY, bgpRcvdPathAttrTable,
211: 3, {5, 1, 6}},
212: /* BGP-4 received path attribute table. */
213: {BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable,
214: 3, {6, 1, 1}},
215: {BGP4PATHATTRIPADDRPREFIXLEN, INTEGER, RONLY, bgp4PathAttrTable,
216: 3, {6, 1, 2}},
217: {BGP4PATHATTRIPADDRPREFIX, IPADDRESS, RONLY, bgp4PathAttrTable,
218: 3, {6, 1, 3}},
219: {BGP4PATHATTRORIGIN, INTEGER, RONLY, bgp4PathAttrTable,
220: 3, {6, 1, 4}},
221: {BGP4PATHATTRASPATHSEGMENT, OCTET_STRING, RONLY, bgp4PathAttrTable,
222: 3, {6, 1, 5}},
223: {BGP4PATHATTRNEXTHOP, IPADDRESS, RONLY, bgp4PathAttrTable,
224: 3, {6, 1, 6}},
225: {BGP4PATHATTRMULTIEXITDISC, INTEGER, RONLY, bgp4PathAttrTable,
226: 3, {6, 1, 7}},
227: {BGP4PATHATTRLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
228: 3, {6, 1, 8}},
229: {BGP4PATHATTRATOMICAGGREGATE, INTEGER, RONLY, bgp4PathAttrTable,
230: 3, {6, 1, 9}},
231: {BGP4PATHATTRAGGREGATORAS, INTEGER, RONLY, bgp4PathAttrTable,
232: 3, {6, 1, 10}},
233: {BGP4PATHATTRAGGREGATORADDR, IPADDRESS, RONLY, bgp4PathAttrTable,
234: 3, {6, 1, 11}},
235: {BGP4PATHATTRCALCLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
236: 3, {6, 1, 12}},
237: {BGP4PATHATTRBEST, INTEGER, RONLY, bgp4PathAttrTable,
238: 3, {6, 1, 13}},
239: {BGP4PATHATTRUNKNOWN, OCTET_STRING, RONLY, bgp4PathAttrTable,
240: 3, {6, 1, 14}},
241: };
242:
1.1.1.3 ! misho 243:
1.1 misho 244: static u_char *
245: bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
246: size_t *var_len, WriteMethod **write_method)
247: {
248: static u_char version;
249:
250: if (smux_header_generic(v, name, length, exact, var_len, write_method)
251: == MATCH_FAILED)
252: return NULL;
253:
254: /* Retrun BGP version. Zebra bgpd only support version 4. */
255: version = (0x80 >> (BGP_VERSION_4 - 1));
256:
257: /* Return octet string length 1. */
258: *var_len = 1;
259: return (u_char *)&version;
260: }
261:
262: static u_char *
263: bgpLocalAs (struct variable *v, oid name[], size_t *length,
264: int exact, size_t *var_len, WriteMethod **write_method)
265: {
266: struct bgp *bgp;
267:
268: if (smux_header_generic(v, name, length, exact, var_len, write_method)
269: == MATCH_FAILED)
270: return NULL;
271:
272: /* Get BGP structure. */
273: bgp = bgp_get_default ();
274: if (! bgp)
275: return NULL;
276:
277: return SNMP_INTEGER (bgp->as);
278: }
279:
280: static struct peer *
281: peer_lookup_addr_ipv4 (struct in_addr *src)
282: {
283: struct bgp *bgp;
284: struct peer *peer;
285: struct listnode *node;
286: struct in_addr addr;
287: int ret;
288:
289: bgp = bgp_get_default ();
290: if (! bgp)
291: return NULL;
292:
293: for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
294: {
295: ret = inet_pton (AF_INET, peer->host, &addr);
296: if (ret > 0)
297: {
298: if (IPV4_ADDR_SAME (&addr, src))
299: return peer;
300: }
301: }
302: return NULL;
303: }
304:
305: static struct peer *
306: bgp_peer_lookup_next (struct in_addr *src)
307: {
308: struct bgp *bgp;
309: struct peer *peer;
310: struct listnode *node;
311: struct in_addr *p;
312: union sockunion su;
313: int ret;
314:
315: memset (&su, 0, sizeof (union sockunion));
316:
317: bgp = bgp_get_default ();
318: if (! bgp)
319: return NULL;
320:
321: for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
322: {
323: ret = inet_pton (AF_INET, peer->host, &su.sin.sin_addr);
324: if (ret > 0)
325: {
326: p = &su.sin.sin_addr;
327:
328: if (ntohl (p->s_addr) > ntohl (src->s_addr))
329: {
330: src->s_addr = p->s_addr;
331: return peer;
332: }
333: }
334: }
335: return NULL;
336: }
337:
1.1.1.3 ! misho 338: /* 1.3.6.1.2.1.15.3.1.x = 10 */
! 339: #define PEERTAB_NAMELEN 10
! 340:
1.1 misho 341: static struct peer *
342: bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
343: struct in_addr *addr, int exact)
344: {
345: struct peer *peer = NULL;
1.1.1.3 ! misho 346: size_t namelen = v ? v->namelen : PEERTAB_NAMELEN;
1.1 misho 347: int len;
348:
349: if (exact)
350: {
351: /* Check the length. */
1.1.1.3 ! misho 352: if (*length - namelen != sizeof (struct in_addr))
1.1 misho 353: return NULL;
354:
1.1.1.3 ! misho 355: oid2in_addr (name + namelen, IN_ADDR_SIZE, addr);
1.1 misho 356:
357: peer = peer_lookup_addr_ipv4 (addr);
358: return peer;
359: }
360: else
361: {
1.1.1.3 ! misho 362: len = *length - namelen;
1.1 misho 363: if (len > 4) len = 4;
364:
1.1.1.3 ! misho 365: oid2in_addr (name + namelen, len, addr);
1.1 misho 366:
367: peer = bgp_peer_lookup_next (addr);
368:
369: if (peer == NULL)
370: return NULL;
371:
1.1.1.3 ! misho 372: oid_copy_addr (name + namelen, addr, sizeof (struct in_addr));
! 373: *length = sizeof (struct in_addr) + namelen;
1.1 misho 374:
375: return peer;
376: }
377: return NULL;
378: }
379:
380: /* BGP write methods. */
381: static int
382: write_bgpPeerTable (int action, u_char *var_val,
383: u_char var_val_type, size_t var_val_len,
1.1.1.3 ! misho 384: u_char *statP, oid *name, size_t length)
1.1 misho 385: {
386: struct in_addr addr;
387: struct peer *peer;
388: long intval;
1.1.1.3 ! misho 389:
1.1 misho 390: if (var_val_type != ASN_INTEGER)
391: {
392: return SNMP_ERR_WRONGTYPE;
393: }
394: if (var_val_len != sizeof (long))
395: {
396: return SNMP_ERR_WRONGLENGTH;
397: }
398:
1.1.1.3 ! misho 399: intval = *(long *)var_val;
1.1 misho 400:
401: memset (&addr, 0, sizeof (struct in_addr));
402:
1.1.1.3 ! misho 403: peer = bgpPeerTable_lookup (NULL, name, &length, &addr, 1);
1.1 misho 404: if (! peer)
405: return SNMP_ERR_NOSUCHNAME;
406:
1.1.1.3 ! misho 407: if (action != SNMP_MSG_INTERNAL_SET_COMMIT)
! 408: return SNMP_ERR_NOERROR;
1.1 misho 409:
1.1.1.3 ! misho 410: zlog_info ("%s: SNMP write .%ld = %ld",
! 411: peer->host, (long)name[PEERTAB_NAMELEN - 1], intval);
! 412:
! 413: switch (name[PEERTAB_NAMELEN - 1])
1.1 misho 414: {
415: case BGPPEERADMINSTATUS:
416: #define BGP_PeerAdmin_stop 1
417: #define BGP_PeerAdmin_start 2
418: /* When the peer is established, */
419: if (intval == BGP_PeerAdmin_stop)
420: BGP_EVENT_ADD (peer, BGP_Stop);
421: else if (intval == BGP_PeerAdmin_start)
422: ; /* Do nothing. */
423: else
424: return SNMP_ERR_NOSUCHNAME;
425: break;
426: case BGPPEERCONNECTRETRYINTERVAL:
427: SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
428: peer->connect = intval;
429: peer->v_connect = intval;
430: break;
431: case BGPPEERHOLDTIMECONFIGURED:
432: SET_FLAG (peer->config, PEER_CONFIG_TIMER);
433: peer->holdtime = intval;
434: peer->v_holdtime = intval;
435: break;
436: case BGPPEERKEEPALIVECONFIGURED:
437: SET_FLAG (peer->config, PEER_CONFIG_TIMER);
438: peer->keepalive = intval;
439: peer->v_keepalive = intval;
440: break;
441: case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
442: peer->v_routeadv = intval;
443: break;
444: }
445: return SNMP_ERR_NOERROR;
446: }
447:
448: static u_char *
449: bgpPeerTable (struct variable *v, oid name[], size_t *length,
450: int exact, size_t *var_len, WriteMethod **write_method)
451: {
452: static struct in_addr addr;
453: struct peer *peer;
454:
1.1.1.2 misho 455: if (smux_header_table(v, name, length, exact, var_len, write_method)
456: == MATCH_FAILED)
457: return NULL;
1.1 misho 458: memset (&addr, 0, sizeof (struct in_addr));
459:
460: peer = bgpPeerTable_lookup (v, name, length, &addr, exact);
461: if (! peer)
462: return NULL;
463:
464: switch (v->magic)
465: {
466: case BGPPEERIDENTIFIER:
467: return SNMP_IPADDRESS (peer->remote_id);
468: break;
469: case BGPPEERSTATE:
470: return SNMP_INTEGER (peer->status);
471: break;
472: case BGPPEERADMINSTATUS:
473: *write_method = write_bgpPeerTable;
474: #define BGP_PeerAdmin_stop 1
475: #define BGP_PeerAdmin_start 2
476: if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
477: return SNMP_INTEGER (BGP_PeerAdmin_stop);
478: else
479: return SNMP_INTEGER (BGP_PeerAdmin_start);
480: break;
481: case BGPPEERNEGOTIATEDVERSION:
482: return SNMP_INTEGER (BGP_VERSION_4);
483: break;
484: case BGPPEERLOCALADDR:
485: if (peer->su_local)
486: return SNMP_IPADDRESS (peer->su_local->sin.sin_addr);
487: else
488: return SNMP_IPADDRESS (bgp_empty_addr);
489: break;
490: case BGPPEERLOCALPORT:
491: if (peer->su_local)
492: return SNMP_INTEGER (ntohs (peer->su_local->sin.sin_port));
493: else
494: return SNMP_INTEGER (0);
495: break;
496: case BGPPEERREMOTEADDR:
497: if (peer->su_remote)
498: return SNMP_IPADDRESS (peer->su_remote->sin.sin_addr);
499: else
500: return SNMP_IPADDRESS (bgp_empty_addr);
501: break;
502: case BGPPEERREMOTEPORT:
503: if (peer->su_remote)
504: return SNMP_INTEGER (ntohs (peer->su_remote->sin.sin_port));
505: else
506: return SNMP_INTEGER (0);
507: break;
508: case BGPPEERREMOTEAS:
509: return SNMP_INTEGER (peer->as);
510: break;
511: case BGPPEERINUPDATES:
512: return SNMP_INTEGER (peer->update_in);
513: break;
514: case BGPPEEROUTUPDATES:
515: return SNMP_INTEGER (peer->update_out);
516: break;
517: case BGPPEERINTOTALMESSAGES:
518: return SNMP_INTEGER (peer->open_in + peer->update_in
519: + peer->keepalive_in + peer->notify_in
520: + peer->refresh_in + peer->dynamic_cap_in);
521: break;
522: case BGPPEEROUTTOTALMESSAGES:
523: return SNMP_INTEGER (peer->open_out + peer->update_out
524: + peer->keepalive_out + peer->notify_out
525: + peer->refresh_out + peer->dynamic_cap_out);
526: break;
527: case BGPPEERLASTERROR:
528: {
529: static u_char lasterror[2];
530: lasterror[0] = peer->notify.code;
531: lasterror[1] = peer->notify.subcode;
532: *var_len = 2;
533: return (u_char *)&lasterror;
534: }
535: break;
536: case BGPPEERFSMESTABLISHEDTRANSITIONS:
537: return SNMP_INTEGER (peer->established);
538: break;
539: case BGPPEERFSMESTABLISHEDTIME:
540: if (peer->uptime == 0)
541: return SNMP_INTEGER (0);
542: else
543: return SNMP_INTEGER (bgp_clock () - peer->uptime);
544: break;
545: case BGPPEERCONNECTRETRYINTERVAL:
546: *write_method = write_bgpPeerTable;
547: return SNMP_INTEGER (peer->v_connect);
548: break;
549: case BGPPEERHOLDTIME:
550: return SNMP_INTEGER (peer->v_holdtime);
551: break;
552: case BGPPEERKEEPALIVE:
553: return SNMP_INTEGER (peer->v_keepalive);
554: break;
555: case BGPPEERHOLDTIMECONFIGURED:
556: *write_method = write_bgpPeerTable;
557: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
558: return SNMP_INTEGER (peer->holdtime);
559: else
560: return SNMP_INTEGER (peer->v_holdtime);
561: break;
562: case BGPPEERKEEPALIVECONFIGURED:
563: *write_method = write_bgpPeerTable;
564: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
565: return SNMP_INTEGER (peer->keepalive);
566: else
567: return SNMP_INTEGER (peer->v_keepalive);
568: break;
569: case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
570: *write_method = write_bgpPeerTable;
571: return SNMP_INTEGER (peer->v_routeadv);
572: break;
573: case BGPPEERINUPDATEELAPSEDTIME:
574: if (peer->update_time == 0)
575: return SNMP_INTEGER (0);
576: else
577: return SNMP_INTEGER (bgp_clock () - peer->update_time);
578: break;
579: default:
580: return NULL;
581: break;
582: }
583: return NULL;
584: }
585:
586: static u_char *
587: bgpIdentifier (struct variable *v, oid name[], size_t *length,
588: int exact, size_t *var_len, WriteMethod **write_method)
589: {
590: struct bgp *bgp;
591:
592: if (smux_header_generic(v, name, length, exact, var_len, write_method)
593: == MATCH_FAILED)
594: return NULL;
595:
596: bgp = bgp_get_default ();
597: if (!bgp)
598: return NULL;
599:
600: return SNMP_IPADDRESS (bgp->router_id);
601: }
602:
603: static u_char *
604: bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
605: int exact, size_t *var_len, WriteMethod **write_method)
606: {
607: /* Received Path Attribute Table. This table contains, one entry
608: per path to a network, path attributes received from all peers
609: running BGP version 3 or less. This table is obsolete, having
610: been replaced in functionality with the bgp4PathAttrTable. */
611: return NULL;
612: }
613:
614: static struct bgp_info *
615: bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
616: struct bgp *bgp, struct prefix_ipv4 *addr, int exact)
617: {
618: oid *offset;
619: int offsetlen;
620: struct bgp_info *binfo;
621: struct bgp_info *min;
622: struct bgp_node *rn;
623: union sockunion su;
624: unsigned int len;
625: struct in_addr paddr;
626:
627: #define BGP_PATHATTR_ENTRY_OFFSET \
628: (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
629:
630: if (exact)
631: {
632: if (*length - v->namelen != BGP_PATHATTR_ENTRY_OFFSET)
633: return NULL;
634:
635: /* Set OID offset for prefix. */
636: offset = name + v->namelen;
637: oid2in_addr (offset, IN_ADDR_SIZE, &addr->prefix);
638: offset += IN_ADDR_SIZE;
639:
640: /* Prefix length. */
641: addr->prefixlen = *offset;
642: offset++;
643:
644: /* Peer address. */
645: su.sin.sin_family = AF_INET;
646: oid2in_addr (offset, IN_ADDR_SIZE, &su.sin.sin_addr);
647:
648: /* Lookup node. */
649: rn = bgp_node_lookup (bgp->rib[AFI_IP][SAFI_UNICAST],
650: (struct prefix *) addr);
651: if (rn)
652: {
653: bgp_unlock_node (rn);
654:
655: for (binfo = rn->info; binfo; binfo = binfo->next)
656: if (sockunion_same (&binfo->peer->su, &su))
657: return binfo;
658: }
659: }
660: else
661: {
662: offset = name + v->namelen;
663: offsetlen = *length - v->namelen;
664: len = offsetlen;
665:
666: if (offsetlen == 0)
667: rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]);
668: else
669: {
670: if (len > IN_ADDR_SIZE)
671: len = IN_ADDR_SIZE;
672:
673: oid2in_addr (offset, len, &addr->prefix);
674:
675: offset += IN_ADDR_SIZE;
676: offsetlen -= IN_ADDR_SIZE;
677:
678: if (offsetlen > 0)
679: addr->prefixlen = *offset;
680: else
681: addr->prefixlen = len * 8;
682:
683: rn = bgp_node_get (bgp->rib[AFI_IP][SAFI_UNICAST],
684: (struct prefix *) addr);
685:
686: offset++;
687: offsetlen--;
688: }
689:
690: if (offsetlen > 0)
691: {
692: len = offsetlen;
693: if (len > IN_ADDR_SIZE)
694: len = IN_ADDR_SIZE;
695:
696: oid2in_addr (offset, len, &paddr);
697: }
698: else
699: paddr.s_addr = 0;
700:
701: if (! rn)
702: return NULL;
703:
704: do
705: {
706: min = NULL;
707:
708: for (binfo = rn->info; binfo; binfo = binfo->next)
709: {
710: if (binfo->peer->su.sin.sin_family == AF_INET
711: && ntohl (paddr.s_addr)
712: < ntohl (binfo->peer->su.sin.sin_addr.s_addr))
713: {
714: if (min)
715: {
716: if (ntohl (binfo->peer->su.sin.sin_addr.s_addr)
717: < ntohl (min->peer->su.sin.sin_addr.s_addr))
718: min = binfo;
719: }
720: else
721: min = binfo;
722: }
723: }
724:
725: if (min)
726: {
727: *length = v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
728:
729: offset = name + v->namelen;
730: oid_copy_addr (offset, &rn->p.u.prefix4, IN_ADDR_SIZE);
731: offset += IN_ADDR_SIZE;
732: *offset = rn->p.prefixlen;
733: offset++;
734: oid_copy_addr (offset, &min->peer->su.sin.sin_addr,
735: IN_ADDR_SIZE);
736: addr->prefix = rn->p.u.prefix4;
737: addr->prefixlen = rn->p.prefixlen;
738:
739: bgp_unlock_node (rn);
740:
741: return min;
742: }
743:
744: paddr.s_addr = 0;
745: }
746: while ((rn = bgp_route_next (rn)) != NULL);
747: }
748: return NULL;
749: }
750:
751: static u_char *
752: bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
753: int exact, size_t *var_len, WriteMethod **write_method)
754: {
755: struct bgp *bgp;
756: struct bgp_info *binfo;
757: struct prefix_ipv4 addr;
758:
759: bgp = bgp_get_default ();
760: if (! bgp)
761: return NULL;
762:
1.1.1.2 misho 763: if (smux_header_table(v, name, length, exact, var_len, write_method)
764: == MATCH_FAILED)
765: return NULL;
1.1 misho 766: memset (&addr, 0, sizeof (struct prefix_ipv4));
767:
768: binfo = bgp4PathAttrLookup (v, name, length, bgp, &addr, exact);
769: if (! binfo)
770: return NULL;
771:
772: switch (v->magic)
773: {
774: case BGP4PATHATTRPEER: /* 1 */
775: return SNMP_IPADDRESS (binfo->peer->su.sin.sin_addr);
776: break;
777: case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
778: return SNMP_INTEGER (addr.prefixlen);
779: break;
780: case BGP4PATHATTRIPADDRPREFIX: /* 3 */
781: return SNMP_IPADDRESS (addr.prefix);
782: break;
783: case BGP4PATHATTRORIGIN: /* 4 */
784: return SNMP_INTEGER (binfo->attr->origin);
785: break;
786: case BGP4PATHATTRASPATHSEGMENT: /* 5 */
787: return aspath_snmp_pathseg (binfo->attr->aspath, var_len);
788: break;
789: case BGP4PATHATTRNEXTHOP: /* 6 */
790: return SNMP_IPADDRESS (binfo->attr->nexthop);
791: break;
792: case BGP4PATHATTRMULTIEXITDISC: /* 7 */
793: return SNMP_INTEGER (binfo->attr->med);
794: break;
795: case BGP4PATHATTRLOCALPREF: /* 8 */
796: return SNMP_INTEGER (binfo->attr->local_pref);
797: break;
798: case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
799: return SNMP_INTEGER (1);
800: break;
801: case BGP4PATHATTRAGGREGATORAS: /* 10 */
802: if (binfo->attr->extra)
803: return SNMP_INTEGER (binfo->attr->extra->aggregator_as);
804: else
805: return SNMP_INTEGER (0);
806: break;
807: case BGP4PATHATTRAGGREGATORADDR: /* 11 */
808: if (binfo->attr->extra)
809: return SNMP_IPADDRESS (binfo->attr->extra->aggregator_addr);
810: else
811: return SNMP_INTEGER (0);
812: break;
813: case BGP4PATHATTRCALCLOCALPREF: /* 12 */
814: return SNMP_INTEGER (-1);
815: break;
816: case BGP4PATHATTRBEST: /* 13 */
817: #define BGP4_PathAttrBest_false 1
818: #define BGP4_PathAttrBest_true 2
819: if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
820: return SNMP_INTEGER (BGP4_PathAttrBest_true);
821: else
822: return SNMP_INTEGER (BGP4_PathAttrBest_false);
823: break;
824: case BGP4PATHATTRUNKNOWN: /* 14 */
825: *var_len = 0;
826: return NULL;
827: break;
828: }
829: return NULL;
830: }
1.1.1.3 ! misho 831:
1.1 misho 832: /* BGP Traps. */
833: struct trap_object bgpTrapList[] =
834: {
1.1.1.2 misho 835: {3, {3, 1, BGPPEERLASTERROR}},
836: {3, {3, 1, BGPPEERSTATE}}
1.1 misho 837: };
838:
839: void
840: bgpTrapEstablished (struct peer *peer)
841: {
842: int ret;
843: struct in_addr addr;
844: oid index[sizeof (oid) * IN_ADDR_SIZE];
845:
846: ret = inet_aton (peer->host, &addr);
847: if (ret == 0)
848: return;
849:
850: oid_copy_addr (index, &addr, IN_ADDR_SIZE);
851:
1.1.1.2 misho 852: smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable),
853: bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
854: bgp_oid, sizeof bgp_oid / sizeof (oid),
1.1 misho 855: index, IN_ADDR_SIZE,
856: bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
1.1.1.2 misho 857: BGPESTABLISHED);
1.1 misho 858: }
859:
860: void
861: bgpTrapBackwardTransition (struct peer *peer)
862: {
863: int ret;
864: struct in_addr addr;
865: oid index[sizeof (oid) * IN_ADDR_SIZE];
866:
867: ret = inet_aton (peer->host, &addr);
868: if (ret == 0)
869: return;
870:
871: oid_copy_addr (index, &addr, IN_ADDR_SIZE);
872:
1.1.1.2 misho 873: smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable),
874: bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
875: bgp_oid, sizeof bgp_oid / sizeof (oid),
1.1 misho 876: index, IN_ADDR_SIZE,
877: bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
1.1.1.2 misho 878: BGPBACKWARDTRANSITION);
1.1 misho 879: }
880:
881: void
882: bgp_snmp_init (void)
883: {
884: smux_init (bm->master);
885: REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
886: }
887: #endif /* HAVE_SNMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>