]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_snmp.c
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
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
23 * Currently SNMP is only running properly for MIBs in the default VRF.
29 #include <net-snmp/net-snmp-config.h>
30 #include <net-snmp/net-snmp-includes.h>
40 #include "zebra/rib.h"
41 #include "zebra/zserv.h"
42 #include "zebra/zebra_vrf.h"
44 #define IPFWMIB 1,3,6,1,2,1,4,24
47 #define IPFORWARDDEST 1
48 #define IPFORWARDMASK 2
49 #define IPFORWARDPOLICY 3
50 #define IPFORWARDNEXTHOP 4
51 #define IPFORWARDIFINDEX 5
52 #define IPFORWARDTYPE 6
53 #define IPFORWARDPROTO 7
54 #define IPFORWARDAGE 8
55 #define IPFORWARDINFO 9
56 #define IPFORWARDNEXTHOPAS 10
57 #define IPFORWARDMETRIC1 11
58 #define IPFORWARDMETRIC2 12
59 #define IPFORWARDMETRIC3 13
60 #define IPFORWARDMETRIC4 14
61 #define IPFORWARDMETRIC5 15
63 /* ipCidrRouteTable */
64 #define IPCIDRROUTEDEST 1
65 #define IPCIDRROUTEMASK 2
66 #define IPCIDRROUTETOS 3
67 #define IPCIDRROUTENEXTHOP 4
68 #define IPCIDRROUTEIFINDEX 5
69 #define IPCIDRROUTETYPE 6
70 #define IPCIDRROUTEPROTO 7
71 #define IPCIDRROUTEAGE 8
72 #define IPCIDRROUTEINFO 9
73 #define IPCIDRROUTENEXTHOPAS 10
74 #define IPCIDRROUTEMETRIC1 11
75 #define IPCIDRROUTEMETRIC2 12
76 #define IPCIDRROUTEMETRIC3 13
77 #define IPCIDRROUTEMETRIC4 14
78 #define IPCIDRROUTEMETRIC5 15
79 #define IPCIDRROUTESTATUS 16
81 #define INTEGER32 ASN_INTEGER
82 #define GAUGE32 ASN_GAUGE
83 #define ENUMERATION ASN_INTEGER
84 #define ROWSTATUS ASN_INTEGER
85 #define IPADDRESS ASN_IPADDRESS
86 #define OBJECTIDENTIFIER ASN_OBJECT_ID
88 static oid ipfw_oid
[] = { IPFWMIB
};
91 static u_char
* ipFwNumber (struct variable
*, oid
[], size_t *,
92 int, size_t *, WriteMethod
**);
93 static u_char
* ipFwTable (struct variable
*, oid
[], size_t *,
94 int, size_t *, WriteMethod
**);
95 static u_char
* ipCidrNumber (struct variable
*, oid
[], size_t *,
96 int, size_t *, WriteMethod
**);
97 static u_char
* ipCidrTable (struct variable
*, oid
[], size_t *,
98 int, size_t *, WriteMethod
**);
100 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}}
139 ipFwNumber (struct variable
*v
, oid objid
[], size_t *objid_len
,
140 int exact
, size_t *val_len
, WriteMethod
**write_method
)
143 struct route_table
*table
;
144 struct route_node
*rn
;
147 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
, write_method
) == MATCH_FAILED
)
150 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
154 /* Return number of routing entries. */
156 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
157 RNODE_FOREACH_RIB (rn
, rib
)
160 return (u_char
*)&result
;
164 ipCidrNumber (struct variable
*v
, oid objid
[], size_t *objid_len
,
165 int exact
, size_t *val_len
, WriteMethod
**write_method
)
168 struct route_table
*table
;
169 struct route_node
*rn
;
172 if (smux_header_generic(v
, objid
, objid_len
, exact
, val_len
, write_method
) == MATCH_FAILED
)
175 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
179 /* Return number of routing entries. */
181 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
182 RNODE_FOREACH_RIB (rn
, rib
)
185 return (u_char
*)&result
;
189 in_addr_cmp(u_char
*p1
, u_char
*p2
)
205 in_addr_add(u_char
*p
, int num
)
211 for (i
= 3; 0 <= i
; i
--) {
213 if (*p
+ num
> 255) {
222 /* ip + num > 0xffffffff */
230 proto_trans(int type
)
234 case ZEBRA_ROUTE_SYSTEM
:
235 return 1; /* other */
236 case ZEBRA_ROUTE_KERNEL
:
237 return 1; /* other */
238 case ZEBRA_ROUTE_CONNECT
:
239 return 2; /* local interface */
240 case ZEBRA_ROUTE_STATIC
:
241 return 3; /* static route */
242 case ZEBRA_ROUTE_RIP
:
244 case ZEBRA_ROUTE_RIPNG
:
245 return 1; /* shouldn't happen */
246 case ZEBRA_ROUTE_OSPF
:
247 return 13; /* ospf */
248 case ZEBRA_ROUTE_OSPF6
:
249 return 1; /* shouldn't happen */
250 case ZEBRA_ROUTE_BGP
:
253 return 1; /* other */
258 check_replace(struct route_node
*np2
, struct rib
*rib2
,
259 struct route_node
**np
, struct rib
**rib
)
270 if (in_addr_cmp(&(*np
)->p
.u
.prefix
, &np2
->p
.u
.prefix
) < 0)
272 if (in_addr_cmp(&(*np
)->p
.u
.prefix
, &np2
->p
.u
.prefix
) > 0)
279 proto
= proto_trans((*rib
)->type
);
280 proto2
= proto_trans(rib2
->type
);
291 if (in_addr_cmp((u_char
*)&(*rib
)->nexthop
->gate
.ipv4
,
292 (u_char
*)&rib2
->nexthop
->gate
.ipv4
) <= 0)
301 get_fwtable_route_node(struct variable
*v
, oid objid
[], size_t *objid_len
,
302 int exact
, struct route_node
**np
, struct rib
**rib
)
305 struct route_table
*table
;
306 struct route_node
*np2
;
310 struct in_addr nexthop
;
314 /* Init index variables */
316 pnt
= (u_char
*) &dest
;
317 for (i
= 0; i
< 4; i
++)
320 pnt
= (u_char
*) &nexthop
;
321 for (i
= 0; i
< 4; i
++)
327 /* Init return variables */
332 /* Short circuit exact matches of wrong length */
334 if (exact
&& (*objid_len
!= (unsigned) v
->namelen
+ 10))
337 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
341 /* Get INDEX information out of OID.
342 * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
345 if (*objid_len
> (unsigned) v
->namelen
)
346 oid2in_addr (objid
+ v
->namelen
, 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, MIN(4U, *objid_len
- v
->namelen
- 6),
358 /* Apply GETNEXT on not exact search */
360 if (!exact
&& (*objid_len
>= (unsigned) v
->namelen
+ 10))
362 if (! in_addr_add((u_char
*) &nexthop
, 1))
366 /* For exact: search matching entry in rib table. */
370 if (policy
) /* Not supported (yet?) */
372 for (*np
= route_top (table
); *np
; *np
= route_next (*np
))
374 if (!in_addr_cmp(&(*np
)->p
.u
.prefix
, (u_char
*)&dest
))
376 RNODE_FOREACH_RIB (*np
, *rib
)
378 if (!in_addr_cmp((u_char
*)&(*rib
)->nexthop
->gate
.ipv4
,
380 if (proto
== proto_trans((*rib
)->type
))
388 /* Search next best entry */
390 for (np2
= route_top (table
); np2
; np2
= route_next (np2
))
393 /* Check destination first */
394 if (in_addr_cmp(&np2
->p
.u
.prefix
, (u_char
*)&dest
) > 0)
395 RNODE_FOREACH_RIB (np2
, rib2
)
396 check_replace(np2
, rib2
, np
, rib
);
398 if (in_addr_cmp(&np2
->p
.u
.prefix
, (u_char
*)&dest
) == 0)
399 { /* have to look at each rib individually */
400 RNODE_FOREACH_RIB (np2
, rib2
)
404 proto2
= proto_trans(rib2
->type
);
407 if ((policy
< policy2
)
408 || ((policy
== policy2
) && (proto
< proto2
))
409 || ((policy
== policy2
) && (proto
== proto2
)
410 && (in_addr_cmp((u_char
*)&rib2
->nexthop
->gate
.ipv4
,
411 (u_char
*) &nexthop
) >= 0)
413 check_replace(np2
, rib2
, np
, rib
);
422 proto
= proto_trans((*rib
)->type
);
424 *objid_len
= v
->namelen
+ 10;
425 pnt
= (u_char
*) &(*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
= (*rib
)->nexthop
;
438 pnt
= (u_char
*) &nexthop
->gate
.ipv4
;
439 for (i
= 0; i
< 4; i
++)
440 objid
[i
+ v
->namelen
+ 6] = *pnt
++;
448 ipFwTable (struct variable
*v
, oid objid
[], size_t *objid_len
,
449 int exact
, size_t *val_len
, WriteMethod
**write_method
)
451 struct route_node
*np
;
454 static int resarr
[2];
455 static struct in_addr netmask
;
456 struct nexthop
*nexthop
;
458 if (smux_header_table(v
, objid
, objid_len
, exact
, val_len
, write_method
)
462 get_fwtable_route_node(v
, objid
, objid_len
, exact
, &np
, &rib
);
466 nexthop
= rib
->nexthop
;
474 return &np
->p
.u
.prefix
;
477 masklen2ip(np
->p
.prefixlen
, &netmask
);
479 return (u_char
*)&netmask
;
481 case IPFORWARDPOLICY
:
483 *val_len
= sizeof(int);
484 return (u_char
*)&result
;
486 case IPFORWARDNEXTHOP
:
488 return (u_char
*)&nexthop
->gate
.ipv4
;
490 case IPFORWARDIFINDEX
:
491 *val_len
= sizeof(int);
492 return (u_char
*)&nexthop
->ifindex
;
495 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
)
499 *val_len
= sizeof(int);
500 return (u_char
*)&result
;
503 result
= proto_trans(rib
->type
);
504 *val_len
= sizeof(int);
505 return (u_char
*)&result
;
509 *val_len
= sizeof(int);
510 return (u_char
*)&result
;
515 *val_len
= 2 * sizeof(int);
516 return (u_char
*)resarr
;
518 case IPFORWARDNEXTHOPAS
:
520 *val_len
= sizeof(int);
521 return (u_char
*)&result
;
523 case IPFORWARDMETRIC1
:
525 *val_len
= sizeof(int);
526 return (u_char
*)&result
;
528 case IPFORWARDMETRIC2
:
530 *val_len
= sizeof(int);
531 return (u_char
*)&result
;
533 case IPFORWARDMETRIC3
:
535 *val_len
= sizeof(int);
536 return (u_char
*)&result
;
538 case IPFORWARDMETRIC4
:
540 *val_len
= sizeof(int);
541 return (u_char
*)&result
;
543 case IPFORWARDMETRIC5
:
545 *val_len
= sizeof(int);
546 return (u_char
*)&result
;
556 ipCidrTable (struct variable
*v
, oid objid
[], size_t *objid_len
,
557 int exact
, size_t *val_len
, WriteMethod
**write_method
)
559 if (smux_header_table(v
, objid
, objid_len
, exact
, val_len
, write_method
)
565 case IPCIDRROUTEDEST
:
577 smux_init (zebrad
.master
);
578 REGISTER_MIB("mibII/ipforward", zebra_variables
, variable
, ipfw_oid
);
580 #endif /* HAVE_SNMP */