mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-10-26 05:24:56 +00:00 
			
		
		
		
	 09781197b6
			
		
	
	
		09781197b6
		
	
	
	
	
		
			
			... by referencing all autogenerated headers relative to the root directory. (90% of the changes here is `version.h`.) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
		
			
				
	
	
		
			571 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			571 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* FIB SNMP.
 | |
|  * Copyright (C) 1999 Kunihiro Ishiguro
 | |
|  *
 | |
|  * This file is part of GNU Zebra.
 | |
|  *
 | |
|  * GNU Zebra is free software; you can redistribute it and/or modify it
 | |
|  * under the terms of the GNU General Public License as published by the
 | |
|  * Free Software Foundation; either version 2, or (at your option) any
 | |
|  * later version.
 | |
|  *
 | |
|  * GNU Zebra is distributed in the hope that it will be useful, but
 | |
|  * WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License along
 | |
|  * with this program; see the file COPYING; if not, write to the Free Software
 | |
|  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Currently SNMP is only running properly for MIBs in the default VRF.
 | |
|  */
 | |
| 
 | |
| #include <zebra.h>
 | |
| 
 | |
| #include <net-snmp/net-snmp-config.h>
 | |
| #include <net-snmp/net-snmp-includes.h>
 | |
| 
 | |
| #include "if.h"
 | |
| #include "log.h"
 | |
| #include "prefix.h"
 | |
| #include "command.h"
 | |
| #include "smux.h"
 | |
| #include "table.h"
 | |
| #include "vrf.h"
 | |
| #include "hook.h"
 | |
| #include "libfrr.h"
 | |
| #include "lib/version.h"
 | |
| 
 | |
| #include "zebra/rib.h"
 | |
| #include "zebra/zserv.h"
 | |
| #include "zebra/zebra_vrf.h"
 | |
| 
 | |
| #define IPFWMIB 1,3,6,1,2,1,4,24
 | |
| 
 | |
| /* ipForwardTable */
 | |
| #define IPFORWARDDEST                         1
 | |
| #define IPFORWARDMASK                         2
 | |
| #define IPFORWARDPOLICY                       3
 | |
| #define IPFORWARDNEXTHOP                      4
 | |
| #define IPFORWARDIFINDEX                      5
 | |
| #define IPFORWARDTYPE                         6
 | |
| #define IPFORWARDPROTO                        7
 | |
| #define IPFORWARDAGE                          8
 | |
| #define IPFORWARDINFO                         9
 | |
| #define IPFORWARDNEXTHOPAS                   10
 | |
| #define IPFORWARDMETRIC1                     11
 | |
| #define IPFORWARDMETRIC2                     12
 | |
| #define IPFORWARDMETRIC3                     13
 | |
| #define IPFORWARDMETRIC4                     14
 | |
| #define IPFORWARDMETRIC5                     15
 | |
| 
 | |
| /* ipCidrRouteTable */
 | |
| #define IPCIDRROUTEDEST                       1
 | |
| #define IPCIDRROUTEMASK                       2
 | |
| #define IPCIDRROUTETOS                        3
 | |
| #define IPCIDRROUTENEXTHOP                    4
 | |
| #define IPCIDRROUTEIFINDEX                    5
 | |
| #define IPCIDRROUTETYPE                       6
 | |
| #define IPCIDRROUTEPROTO                      7
 | |
| #define IPCIDRROUTEAGE                        8
 | |
| #define IPCIDRROUTEINFO                       9
 | |
| #define IPCIDRROUTENEXTHOPAS                 10
 | |
| #define IPCIDRROUTEMETRIC1                   11
 | |
| #define IPCIDRROUTEMETRIC2                   12
 | |
| #define IPCIDRROUTEMETRIC3                   13
 | |
| #define IPCIDRROUTEMETRIC4                   14
 | |
| #define IPCIDRROUTEMETRIC5                   15
 | |
| #define IPCIDRROUTESTATUS                    16
 | |
| 
 | |
| #define INTEGER32 ASN_INTEGER
 | |
| #define GAUGE32 ASN_GAUGE
 | |
| #define ENUMERATION ASN_INTEGER
 | |
| #define ROWSTATUS ASN_INTEGER
 | |
| #define IPADDRESS ASN_IPADDRESS
 | |
| #define OBJECTIDENTIFIER ASN_OBJECT_ID
 | |
| 
 | |
| static oid ipfw_oid[] = {IPFWMIB};
 | |
| 
 | |
| /* Hook functions. */
 | |
| static uint8_t *ipFwNumber(struct variable *, oid[], size_t *, int, size_t *,
 | |
| 			   WriteMethod **);
 | |
| static uint8_t *ipFwTable(struct variable *, oid[], size_t *, int, size_t *,
 | |
| 			  WriteMethod **);
 | |
| static uint8_t *ipCidrNumber(struct variable *, oid[], size_t *, int, size_t *,
 | |
| 			     WriteMethod **);
 | |
| static uint8_t *ipCidrTable(struct variable *, oid[], size_t *, int, size_t *,
 | |
| 			    WriteMethod **);
 | |
| 
 | |
| static struct variable zebra_variables[] = {
 | |
| 	{0, GAUGE32, RONLY, ipFwNumber, 1, {1}},
 | |
| 	{IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}},
 | |
| 	{IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}},
 | |
| 	{IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}},
 | |
| 	{IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}},
 | |
| 	{IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}},
 | |
| 	{IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}},
 | |
| 	{IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}},
 | |
| 	{IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}},
 | |
| 	{IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}},
 | |
| 	{IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}},
 | |
| 	{IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}},
 | |
| 	{IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}},
 | |
| 	{IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}},
 | |
| 	{IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}},
 | |
| 	{IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}},
 | |
| 	{0, GAUGE32, RONLY, ipCidrNumber, 1, {3}},
 | |
| 	{IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}},
 | |
| 	{IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}},
 | |
| 	{IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}},
 | |
| 	{IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}},
 | |
| 	{IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}},
 | |
| 	{IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}},
 | |
| 	{IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}},
 | |
| 	{IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}},
 | |
| 	{IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}},
 | |
| 	{IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}},
 | |
| 	{IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}},
 | |
| 	{IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}},
 | |
| 	{IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}},
 | |
| 	{IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}},
 | |
| 	{IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}},
 | |
| 	{IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}}};
 | |
| 
 | |
| 
 | |
| static uint8_t *ipFwNumber(struct variable *v, oid objid[], size_t *objid_len,
 | |
| 			   int exact, size_t *val_len,
 | |
| 			   WriteMethod **write_method)
 | |
| {
 | |
| 	static int result;
 | |
| 	struct route_table *table;
 | |
| 	struct route_node *rn;
 | |
| 	struct route_entry *re;
 | |
| 
 | |
| 	if (smux_header_generic(v, objid, objid_len, exact, val_len,
 | |
| 				write_method)
 | |
| 	    == MATCH_FAILED)
 | |
| 		return NULL;
 | |
| 
 | |
| 	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | |
| 	if (!table)
 | |
| 		return NULL;
 | |
| 
 | |
| 	/* Return number of routing entries. */
 | |
| 	result = 0;
 | |
| 	for (rn = route_top(table); rn; rn = route_next(rn))
 | |
| 		RNODE_FOREACH_RE (rn, re) {
 | |
| 			result++;
 | |
| 		}
 | |
| 
 | |
| 	return (uint8_t *)&result;
 | |
| }
 | |
| 
 | |
| static uint8_t *ipCidrNumber(struct variable *v, oid objid[], size_t *objid_len,
 | |
| 			     int exact, size_t *val_len,
 | |
| 			     WriteMethod **write_method)
 | |
| {
 | |
| 	static int result;
 | |
| 	struct route_table *table;
 | |
| 	struct route_node *rn;
 | |
| 	struct route_entry *re;
 | |
| 
 | |
| 	if (smux_header_generic(v, objid, objid_len, exact, val_len,
 | |
| 				write_method)
 | |
| 	    == MATCH_FAILED)
 | |
| 		return NULL;
 | |
| 
 | |
| 	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | |
| 	if (!table)
 | |
| 		return 0;
 | |
| 
 | |
| 	/* Return number of routing entries. */
 | |
| 	result = 0;
 | |
| 	for (rn = route_top(table); rn; rn = route_next(rn))
 | |
| 		RNODE_FOREACH_RE (rn, re) {
 | |
| 			result++;
 | |
| 		}
 | |
| 
 | |
| 	return (uint8_t *)&result;
 | |
| }
 | |
| 
 | |
| static int in_addr_cmp(uint8_t *p1, uint8_t *p2)
 | |
| {
 | |
| 	int i;
 | |
| 
 | |
| 	for (i = 0; i < 4; i++) {
 | |
| 		if (*p1 < *p2)
 | |
| 			return -1;
 | |
| 		if (*p1 > *p2)
 | |
| 			return 1;
 | |
| 		p1++;
 | |
| 		p2++;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int in_addr_add(uint8_t *p, int num)
 | |
| {
 | |
| 	int i, ip0;
 | |
| 
 | |
| 	ip0 = *p;
 | |
| 	p += 4;
 | |
| 	for (i = 3; 0 <= i; i--) {
 | |
| 		p--;
 | |
| 		if (*p + num > 255) {
 | |
| 			*p += num;
 | |
| 			num = 1;
 | |
| 		} else {
 | |
| 			*p += num;
 | |
| 			return 1;
 | |
| 		}
 | |
| 	}
 | |
| 	if (ip0 > *p) {
 | |
| 		/* ip + num > 0xffffffff */
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| static int proto_trans(int type)
 | |
| {
 | |
| 	switch (type) {
 | |
| 	case ZEBRA_ROUTE_SYSTEM:
 | |
| 		return 1; /* other */
 | |
| 	case ZEBRA_ROUTE_KERNEL:
 | |
| 		return 1; /* other */
 | |
| 	case ZEBRA_ROUTE_CONNECT:
 | |
| 		return 2; /* local interface */
 | |
| 	case ZEBRA_ROUTE_STATIC:
 | |
| 		return 3; /* static route */
 | |
| 	case ZEBRA_ROUTE_RIP:
 | |
| 		return 8; /* rip */
 | |
| 	case ZEBRA_ROUTE_RIPNG:
 | |
| 		return 1; /* shouldn't happen */
 | |
| 	case ZEBRA_ROUTE_OSPF:
 | |
| 		return 13; /* ospf */
 | |
| 	case ZEBRA_ROUTE_OSPF6:
 | |
| 		return 1; /* shouldn't happen */
 | |
| 	case ZEBRA_ROUTE_BGP:
 | |
| 		return 14; /* bgp */
 | |
| 	default:
 | |
| 		return 1; /* other */
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void check_replace(struct route_node *np2, struct route_entry *re2,
 | |
| 			  struct route_node **np, struct route_entry **re)
 | |
| {
 | |
| 	int proto, proto2;
 | |
| 
 | |
| 	if (!*np) {
 | |
| 		*np = np2;
 | |
| 		*re = re2;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (prefix_cmp(&(*np)->p, &np2->p) < 0)
 | |
| 		return;
 | |
| 	if (prefix_cmp(&(*np)->p, &np2->p) > 0) {
 | |
| 		*np = np2;
 | |
| 		*re = re2;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	proto = proto_trans((*re)->type);
 | |
| 	proto2 = proto_trans(re2->type);
 | |
| 
 | |
| 	if (proto2 > proto)
 | |
| 		return;
 | |
| 	if (proto2 < proto) {
 | |
| 		*np = np2;
 | |
| 		*re = re2;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (in_addr_cmp((uint8_t *)&(*re)->nhe->nhg.nexthop->gate.ipv4,
 | |
| 			(uint8_t *)&re2->nhe->nhg.nexthop->gate.ipv4)
 | |
| 	    <= 0)
 | |
| 		return;
 | |
| 
 | |
| 	*np = np2;
 | |
| 	*re = re2;
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| static void get_fwtable_route_node(struct variable *v, oid objid[],
 | |
| 				   size_t *objid_len, int exact,
 | |
| 				   struct route_node **np,
 | |
| 				   struct route_entry **re)
 | |
| {
 | |
| 	struct in_addr dest;
 | |
| 	struct route_table *table;
 | |
| 	struct route_node *np2;
 | |
| 	struct route_entry *re2;
 | |
| 	int proto;
 | |
| 	int policy;
 | |
| 	struct in_addr nexthop;
 | |
| 	uint8_t *pnt;
 | |
| 	int i;
 | |
| 
 | |
| 	/* Init index variables */
 | |
| 
 | |
| 	pnt = (uint8_t *)&dest;
 | |
| 	for (i = 0; i < 4; i++)
 | |
| 		*pnt++ = 0;
 | |
| 
 | |
| 	pnt = (uint8_t *)&nexthop;
 | |
| 	for (i = 0; i < 4; i++)
 | |
| 		*pnt++ = 0;
 | |
| 
 | |
| 	proto = 0;
 | |
| 	policy = 0;
 | |
| 
 | |
| 	/* Init return variables */
 | |
| 
 | |
| 	*np = NULL;
 | |
| 	*re = NULL;
 | |
| 
 | |
| 	/* Short circuit exact matches of wrong length */
 | |
| 
 | |
| 	if (exact && (*objid_len != (unsigned)v->namelen + 10))
 | |
| 		return;
 | |
| 
 | |
| 	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 | |
| 	if (!table)
 | |
| 		return;
 | |
| 
 | |
| 	/* Get INDEX information out of OID.
 | |
| 	 * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
 | |
| 	 */
 | |
| 
 | |
| 	if (*objid_len > (unsigned)v->namelen)
 | |
| 		oid2in_addr(objid + v->namelen,
 | |
| 			    MIN(4U, *objid_len - v->namelen), &dest);
 | |
| 
 | |
| 	if (*objid_len > (unsigned)v->namelen + 4)
 | |
| 		proto = objid[v->namelen + 4];
 | |
| 
 | |
| 	if (*objid_len > (unsigned)v->namelen + 5)
 | |
| 		policy = objid[v->namelen + 5];
 | |
| 
 | |
| 	if (*objid_len > (unsigned)v->namelen + 6)
 | |
| 		oid2in_addr(objid + v->namelen + 6,
 | |
| 			    MIN(4U, *objid_len - v->namelen - 6), &nexthop);
 | |
| 
 | |
| 	/* Apply GETNEXT on not exact search */
 | |
| 
 | |
| 	if (!exact && (*objid_len >= (unsigned)v->namelen + 10)) {
 | |
| 		if (!in_addr_add((uint8_t *)&nexthop, 1))
 | |
| 			return;
 | |
| 	}
 | |
| 
 | |
| 	/* For exact: search matching entry in rib table. */
 | |
| 
 | |
| 	if (exact) {
 | |
| 		if (policy) /* Not supported (yet?) */
 | |
| 			return;
 | |
| 		for (*np = route_top(table); *np; *np = route_next(*np)) {
 | |
| 			if (!in_addr_cmp(&(*np)->p.u.prefix,
 | |
| 					 (uint8_t *)&dest)) {
 | |
| 				RNODE_FOREACH_RE (*np, *re) {
 | |
| 					if (!in_addr_cmp((uint8_t *)&(*re)->nhe
 | |
| 							 ->nhg.nexthop
 | |
| 							 ->gate.ipv4,
 | |
| 							 (uint8_t *)&nexthop))
 | |
| 						if (proto
 | |
| 						    == proto_trans((*re)->type))
 | |
| 							return;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	/* Search next best entry */
 | |
| 
 | |
| 	for (np2 = route_top(table); np2; np2 = route_next(np2)) {
 | |
| 
 | |
| 		/* Check destination first */
 | |
| 		if (in_addr_cmp(&np2->p.u.prefix, (uint8_t *)&dest) > 0)
 | |
| 			RNODE_FOREACH_RE (np2, re2) {
 | |
| 				check_replace(np2, re2, np, re);
 | |
| 			}
 | |
| 
 | |
| 		if (in_addr_cmp(&np2->p.u.prefix, (uint8_t *)&dest)
 | |
| 		    == 0) { /* have to look at each re individually */
 | |
| 			RNODE_FOREACH_RE (np2, re2) {
 | |
| 				int proto2, policy2;
 | |
| 
 | |
| 				proto2 = proto_trans(re2->type);
 | |
| 				policy2 = 0;
 | |
| 
 | |
| 				if ((policy < policy2)
 | |
| 				    || ((policy == policy2) && (proto < proto2))
 | |
| 				    || ((policy == policy2) && (proto == proto2)
 | |
| 					&& (in_addr_cmp(
 | |
| 						    (uint8_t *)&re2->nhe
 | |
| 						    ->nhg.nexthop->gate.ipv4,
 | |
| 						    (uint8_t *)&nexthop)
 | |
| 					    >= 0)))
 | |
| 					check_replace(np2, re2, np, re);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (!*re)
 | |
| 		return;
 | |
| 
 | |
| 	policy = 0;
 | |
| 	proto = proto_trans((*re)->type);
 | |
| 
 | |
| 	*objid_len = v->namelen + 10;
 | |
| 	pnt = (uint8_t *)&(*np)->p.u.prefix;
 | |
| 	for (i = 0; i < 4; i++)
 | |
| 		objid[v->namelen + i] = *pnt++;
 | |
| 
 | |
| 	objid[v->namelen + 4] = proto;
 | |
| 	objid[v->namelen + 5] = policy;
 | |
| 
 | |
| 	{
 | |
| 		struct nexthop *nexthop;
 | |
| 
 | |
| 		nexthop = (*re)->nhe->nhg.nexthop;
 | |
| 		if (nexthop) {
 | |
| 			pnt = (uint8_t *)&nexthop->gate.ipv4;
 | |
| 			for (i = 0; i < 4; i++)
 | |
| 				objid[i + v->namelen + 6] = *pnt++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| static uint8_t *ipFwTable(struct variable *v, oid objid[], size_t *objid_len,
 | |
| 			  int exact, size_t *val_len,
 | |
| 			  WriteMethod **write_method)
 | |
| {
 | |
| 	struct route_node *np;
 | |
| 	struct route_entry *re;
 | |
| 	static int result;
 | |
| 	static int resarr[2];
 | |
| 	static struct in_addr netmask;
 | |
| 	struct nexthop *nexthop;
 | |
| 
 | |
| 	if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
 | |
| 	    == MATCH_FAILED)
 | |
| 		return NULL;
 | |
| 
 | |
| 	get_fwtable_route_node(v, objid, objid_len, exact, &np, &re);
 | |
| 	if (!np)
 | |
| 		return NULL;
 | |
| 
 | |
| 	nexthop = re->nhe->nhg.nexthop;
 | |
| 	if (!nexthop)
 | |
| 		return NULL;
 | |
| 
 | |
| 	switch (v->magic) {
 | |
| 	case IPFORWARDDEST:
 | |
| 		*val_len = 4;
 | |
| 		return &np->p.u.prefix;
 | |
| 	case IPFORWARDMASK:
 | |
| 		masklen2ip(np->p.prefixlen, &netmask);
 | |
| 		*val_len = 4;
 | |
| 		return (uint8_t *)&netmask;
 | |
| 	case IPFORWARDPOLICY:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDNEXTHOP:
 | |
| 		*val_len = 4;
 | |
| 		return (uint8_t *)&nexthop->gate.ipv4;
 | |
| 	case IPFORWARDIFINDEX:
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&nexthop->ifindex;
 | |
| 	case IPFORWARDTYPE:
 | |
| 		if (nexthop->type == NEXTHOP_TYPE_IFINDEX)
 | |
| 			result = 3;
 | |
| 		else
 | |
| 			result = 4;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDPROTO:
 | |
| 		result = proto_trans(re->type);
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDAGE:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDINFO:
 | |
| 		resarr[0] = 0;
 | |
| 		resarr[1] = 0;
 | |
| 		*val_len = 2 * sizeof(int);
 | |
| 		return (uint8_t *)resarr;
 | |
| 	case IPFORWARDNEXTHOPAS:
 | |
| 		result = -1;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDMETRIC1:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDMETRIC2:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDMETRIC3:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDMETRIC4:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	case IPFORWARDMETRIC5:
 | |
| 		result = 0;
 | |
| 		*val_len = sizeof(int);
 | |
| 		return (uint8_t *)&result;
 | |
| 	default:
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| static uint8_t *ipCidrTable(struct variable *v, oid objid[], size_t *objid_len,
 | |
| 			    int exact, size_t *val_len,
 | |
| 			    WriteMethod **write_method)
 | |
| {
 | |
| 	if (smux_header_table(v, objid, objid_len, exact, val_len, write_method)
 | |
| 	    == MATCH_FAILED)
 | |
| 		return NULL;
 | |
| 
 | |
| 	switch (v->magic) {
 | |
| 	case IPCIDRROUTEDEST:
 | |
| 		break;
 | |
| 	default:
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| static int zebra_snmp_init(struct thread_master *tm)
 | |
| {
 | |
| 	smux_init(tm);
 | |
| 	REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int zebra_snmp_module_init(void)
 | |
| {
 | |
| 	hook_register(frr_late_init, zebra_snmp_init);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| FRR_MODULE_SETUP(.name = "zebra_snmp", .version = FRR_VERSION,
 | |
| 		 .description = "zebra AgentX SNMP module",
 | |
| 		 .init = zebra_snmp_module_init,
 | |
| );
 |