]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_snmp.c
89b8238c29386401e8f2b302c92f24f771c58729
2 * Copyright (C) 1999 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
22 * Currently SNMP is only running properly for MIBs in the default VRF.
27 #include <net-snmp/net-snmp-config.h>
28 #include <net-snmp/net-snmp-includes.h>
41 #include "zebra/rib.h"
42 #include "zebra/zserv.h"
43 #include "zebra/zebra_vrf.h"
45 #define IPFWMIB 1,3,6,1,2,1,4,24
48 #define IPFORWARDDEST 1
49 #define IPFORWARDMASK 2
50 #define IPFORWARDPOLICY 3
51 #define IPFORWARDNEXTHOP 4
52 #define IPFORWARDIFINDEX 5
53 #define IPFORWARDTYPE 6
54 #define IPFORWARDPROTO 7
55 #define IPFORWARDAGE 8
56 #define IPFORWARDINFO 9
57 #define IPFORWARDNEXTHOPAS 10
58 #define IPFORWARDMETRIC1 11
59 #define IPFORWARDMETRIC2 12
60 #define IPFORWARDMETRIC3 13
61 #define IPFORWARDMETRIC4 14
62 #define IPFORWARDMETRIC5 15
64 /* ipCidrRouteTable */
65 #define IPCIDRROUTEDEST 1
66 #define IPCIDRROUTEMASK 2
67 #define IPCIDRROUTETOS 3
68 #define IPCIDRROUTENEXTHOP 4
69 #define IPCIDRROUTEIFINDEX 5
70 #define IPCIDRROUTETYPE 6
71 #define IPCIDRROUTEPROTO 7
72 #define IPCIDRROUTEAGE 8
73 #define IPCIDRROUTEINFO 9
74 #define IPCIDRROUTENEXTHOPAS 10
75 #define IPCIDRROUTEMETRIC1 11
76 #define IPCIDRROUTEMETRIC2 12
77 #define IPCIDRROUTEMETRIC3 13
78 #define IPCIDRROUTEMETRIC4 14
79 #define IPCIDRROUTEMETRIC5 15
80 #define IPCIDRROUTESTATUS 16
82 #define INTEGER32 ASN_INTEGER
83 #define GAUGE32 ASN_GAUGE
84 #define ENUMERATION ASN_INTEGER
85 #define ROWSTATUS ASN_INTEGER
86 #define IPADDRESS ASN_IPADDRESS
87 #define OBJECTIDENTIFIER ASN_OBJECT_ID
89 static oid ipfw_oid
[] = {IPFWMIB
};
92 static uint8_t *ipFwNumber(struct variable
*, oid
[], size_t *, int, size_t *,
94 static uint8_t *ipFwTable(struct variable
*, oid
[], size_t *, int, size_t *,
96 static uint8_t *ipCidrNumber(struct variable
*, oid
[], size_t *, int, size_t *,
98 static uint8_t *ipCidrTable(struct variable
*, oid
[], size_t *, int, size_t *,
101 static struct variable zebra_variables
[] = {
102 {0, GAUGE32
, RONLY
, ipFwNumber
, 1, {1}},
103 {IPFORWARDDEST
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 1}},
104 {IPFORWARDMASK
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 2}},
105 {IPFORWARDPOLICY
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 3}},
106 {IPFORWARDNEXTHOP
, IPADDRESS
, RONLY
, ipFwTable
, 3, {2, 1, 4}},
107 {IPFORWARDIFINDEX
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 5}},
108 {IPFORWARDTYPE
, ENUMERATION
, RONLY
, ipFwTable
, 3, {2, 1, 6}},
109 {IPFORWARDPROTO
, ENUMERATION
, RONLY
, ipFwTable
, 3, {2, 1, 7}},
110 {IPFORWARDAGE
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 8}},
111 {IPFORWARDINFO
, OBJECTIDENTIFIER
, RONLY
, ipFwTable
, 3, {2, 1, 9}},
112 {IPFORWARDNEXTHOPAS
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 10}},
113 {IPFORWARDMETRIC1
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 11}},
114 {IPFORWARDMETRIC2
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 12}},
115 {IPFORWARDMETRIC3
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 13}},
116 {IPFORWARDMETRIC4
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 14}},
117 {IPFORWARDMETRIC5
, INTEGER32
, RONLY
, ipFwTable
, 3, {2, 1, 15}},
118 {0, GAUGE32
, RONLY
, ipCidrNumber
, 1, {3}},
119 {IPCIDRROUTEDEST
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 1}},
120 {IPCIDRROUTEMASK
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 2}},
121 {IPCIDRROUTETOS
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 3}},
122 {IPCIDRROUTENEXTHOP
, IPADDRESS
, RONLY
, ipCidrTable
, 3, {4, 1, 4}},
123 {IPCIDRROUTEIFINDEX
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 5}},
124 {IPCIDRROUTETYPE
, ENUMERATION
, RONLY
, ipCidrTable
, 3, {4, 1, 6}},
125 {IPCIDRROUTEPROTO
, ENUMERATION
, RONLY
, ipCidrTable
, 3, {4, 1, 7}},
126 {IPCIDRROUTEAGE
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 8}},
127 {IPCIDRROUTEINFO
, OBJECTIDENTIFIER
, RONLY
, ipCidrTable
, 3, {4, 1, 9}},
128 {IPCIDRROUTENEXTHOPAS
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 10}},
129 {IPCIDRROUTEMETRIC1
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 11}},
130 {IPCIDRROUTEMETRIC2
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 12}},
131 {IPCIDRROUTEMETRIC3
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 13}},
132 {IPCIDRROUTEMETRIC4
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 14}},
133 {IPCIDRROUTEMETRIC5
, INTEGER32
, RONLY
, ipCidrTable
, 3, {4, 1, 15}},
134 {IPCIDRROUTESTATUS
, ROWSTATUS
, RONLY
, ipCidrTable
, 3, {4, 1, 16}}};
137 static uint8_t *ipFwNumber(struct variable
*v
, oid objid
[], size_t *objid_len
,
138 int exact
, size_t *val_len
,
139 WriteMethod
**write_method
)
142 struct route_table
*table
;
143 struct route_node
*rn
;
144 struct route_entry
*re
;
146 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
,
151 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
155 /* Return number of routing entries. */
157 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
158 RNODE_FOREACH_RE (rn
, re
) {
162 return (uint8_t *)&result
;
165 static uint8_t *ipCidrNumber(struct variable
*v
, oid objid
[], size_t *objid_len
,
166 int exact
, size_t *val_len
,
167 WriteMethod
**write_method
)
170 struct route_table
*table
;
171 struct route_node
*rn
;
172 struct route_entry
*re
;
174 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
,
179 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
183 /* Return number of routing entries. */
185 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
186 RNODE_FOREACH_RE (rn
, re
) {
190 return (uint8_t *)&result
;
193 static int in_addr_cmp(uint8_t *p1
, uint8_t *p2
)
197 for (i
= 0; i
< 4; i
++) {
208 static int in_addr_add(uint8_t *p
, int num
)
214 for (i
= 3; 0 <= i
; i
--) {
216 if (*p
+ num
> 255) {
225 /* ip + num > 0xffffffff */
232 static int proto_trans(int type
)
235 case ZEBRA_ROUTE_SYSTEM
:
236 return 1; /* other */
237 case ZEBRA_ROUTE_KERNEL
:
238 return 1; /* other */
239 case ZEBRA_ROUTE_CONNECT
:
240 return 2; /* local interface */
241 case ZEBRA_ROUTE_STATIC
:
242 return 3; /* static route */
243 case ZEBRA_ROUTE_RIP
:
245 case ZEBRA_ROUTE_RIPNG
:
246 return 1; /* shouldn't happen */
247 case ZEBRA_ROUTE_OSPF
:
248 return 13; /* ospf */
249 case ZEBRA_ROUTE_OSPF6
:
250 return 1; /* shouldn't happen */
251 case ZEBRA_ROUTE_BGP
:
254 return 1; /* other */
258 static void check_replace(struct route_node
*np2
, struct route_entry
*re2
,
259 struct route_node
**np
, struct route_entry
**re
)
269 if (prefix_cmp(&(*np
)->p
, &np2
->p
) < 0)
271 if (prefix_cmp(&(*np
)->p
, &np2
->p
) > 0) {
277 proto
= proto_trans((*re
)->type
);
278 proto2
= proto_trans(re2
->type
);
282 if (proto2
< proto
) {
288 if (in_addr_cmp((uint8_t *)&(*re
)->nhe
->nhg
.nexthop
->gate
.ipv4
,
289 (uint8_t *)&re2
->nhe
->nhg
.nexthop
->gate
.ipv4
)
298 static void get_fwtable_route_node(struct variable
*v
, oid objid
[],
299 size_t *objid_len
, int exact
,
300 struct route_node
**np
,
301 struct route_entry
**re
)
304 struct route_table
*table
;
305 struct route_node
*np2
;
306 struct route_entry
*re2
;
309 struct in_addr nexthop
;
313 /* Init index variables */
315 pnt
= (uint8_t *)&dest
;
316 for (i
= 0; i
< 4; i
++)
319 pnt
= (uint8_t *)&nexthop
;
320 for (i
= 0; i
< 4; i
++)
326 /* Init return variables */
331 /* Short circuit exact matches of wrong length */
333 if (exact
&& (*objid_len
!= (unsigned)v
->namelen
+ 10))
336 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
340 /* Get INDEX information out of OID.
341 * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
344 if (*objid_len
> (unsigned)v
->namelen
)
345 oid2in_addr(objid
+ v
->namelen
,
346 MIN(4U, *objid_len
- v
->namelen
), &dest
);
348 if (*objid_len
> (unsigned)v
->namelen
+ 4)
349 proto
= objid
[v
->namelen
+ 4];
351 if (*objid_len
> (unsigned)v
->namelen
+ 5)
352 policy
= objid
[v
->namelen
+ 5];
354 if (*objid_len
> (unsigned)v
->namelen
+ 6)
355 oid2in_addr(objid
+ v
->namelen
+ 6,
356 MIN(4U, *objid_len
- v
->namelen
- 6), &nexthop
);
358 /* Apply GETNEXT on not exact search */
360 if (!exact
&& (*objid_len
>= (unsigned)v
->namelen
+ 10)) {
361 if (!in_addr_add((uint8_t *)&nexthop
, 1))
365 /* For exact: search matching entry in rib table. */
368 if (policy
) /* Not supported (yet?) */
370 for (*np
= route_top(table
); *np
; *np
= route_next(*np
)) {
371 if (!in_addr_cmp(&(*np
)->p
.u
.prefix
,
373 RNODE_FOREACH_RE (*np
, *re
) {
374 if (!in_addr_cmp((uint8_t *)&(*re
)->nhe
377 (uint8_t *)&nexthop
))
379 == proto_trans((*re
)->type
))
387 /* Search next best entry */
389 for (np2
= route_top(table
); np2
; np2
= route_next(np2
)) {
391 /* Check destination first */
392 if (in_addr_cmp(&np2
->p
.u
.prefix
, (uint8_t *)&dest
) > 0)
393 RNODE_FOREACH_RE (np2
, re2
) {
394 check_replace(np2
, re2
, np
, re
);
397 if (in_addr_cmp(&np2
->p
.u
.prefix
, (uint8_t *)&dest
)
398 == 0) { /* have to look at each re individually */
399 RNODE_FOREACH_RE (np2
, re2
) {
402 proto2
= proto_trans(re2
->type
);
405 if ((policy
< policy2
)
406 || ((policy
== policy2
) && (proto
< proto2
))
407 || ((policy
== policy2
) && (proto
== proto2
)
410 ->nhg
.nexthop
->gate
.ipv4
,
413 check_replace(np2
, re2
, np
, re
);
422 proto
= proto_trans((*re
)->type
);
424 *objid_len
= v
->namelen
+ 10;
425 pnt
= (uint8_t *)&(*np
)->p
.u
.prefix
;
426 for (i
= 0; i
< 4; i
++)
427 objid
[v
->namelen
+ i
] = *pnt
++;
429 objid
[v
->namelen
+ 4] = proto
;
430 objid
[v
->namelen
+ 5] = policy
;
433 struct nexthop
*nexthop
;
435 nexthop
= (*re
)->nhe
->nhg
.nexthop
;
437 pnt
= (uint8_t *)&nexthop
->gate
.ipv4
;
438 for (i
= 0; i
< 4; i
++)
439 objid
[i
+ v
->namelen
+ 6] = *pnt
++;
446 static uint8_t *ipFwTable(struct variable
*v
, oid objid
[], size_t *objid_len
,
447 int exact
, size_t *val_len
,
448 WriteMethod
**write_method
)
450 struct route_node
*np
;
451 struct route_entry
*re
;
453 static int resarr
[2];
454 static struct in_addr netmask
;
455 struct nexthop
*nexthop
;
457 if (smux_header_table(v
, objid
, objid_len
, exact
, val_len
, write_method
)
461 get_fwtable_route_node(v
, objid
, objid_len
, exact
, &np
, &re
);
465 nexthop
= re
->nhe
->nhg
.nexthop
;
472 return &np
->p
.u
.prefix
;
474 masklen2ip(np
->p
.prefixlen
, &netmask
);
476 return (uint8_t *)&netmask
;
477 case IPFORWARDPOLICY
:
479 *val_len
= sizeof(int);
480 return (uint8_t *)&result
;
481 case IPFORWARDNEXTHOP
:
483 return (uint8_t *)&nexthop
->gate
.ipv4
;
484 case IPFORWARDIFINDEX
:
485 *val_len
= sizeof(int);
486 return (uint8_t *)&nexthop
->ifindex
;
488 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
)
492 *val_len
= sizeof(int);
493 return (uint8_t *)&result
;
495 result
= proto_trans(re
->type
);
496 *val_len
= sizeof(int);
497 return (uint8_t *)&result
;
500 *val_len
= sizeof(int);
501 return (uint8_t *)&result
;
505 *val_len
= 2 * sizeof(int);
506 return (uint8_t *)resarr
;
507 case IPFORWARDNEXTHOPAS
:
509 *val_len
= sizeof(int);
510 return (uint8_t *)&result
;
511 case IPFORWARDMETRIC1
:
513 *val_len
= sizeof(int);
514 return (uint8_t *)&result
;
515 case IPFORWARDMETRIC2
:
517 *val_len
= sizeof(int);
518 return (uint8_t *)&result
;
519 case IPFORWARDMETRIC3
:
521 *val_len
= sizeof(int);
522 return (uint8_t *)&result
;
523 case IPFORWARDMETRIC4
:
525 *val_len
= sizeof(int);
526 return (uint8_t *)&result
;
527 case IPFORWARDMETRIC5
:
529 *val_len
= sizeof(int);
530 return (uint8_t *)&result
;
537 static uint8_t *ipCidrTable(struct variable
*v
, oid objid
[], size_t *objid_len
,
538 int exact
, size_t *val_len
,
539 WriteMethod
**write_method
)
541 if (smux_header_table(v
, objid
, objid_len
, exact
, val_len
, write_method
)
546 case IPCIDRROUTEDEST
:
554 static int zebra_snmp_init(struct thread_master
*tm
)
557 REGISTER_MIB("mibII/ipforward", zebra_variables
, variable
, ipfw_oid
);
561 static int zebra_snmp_module_init(void)
563 hook_register(frr_late_init
, zebra_snmp_init
);
567 FRR_MODULE_SETUP(.name
= "zebra_snmp", .version
= FRR_VERSION
,
568 .description
= "zebra AgentX SNMP module",
569 .init
= zebra_snmp_module_init
, )