...borrowed from the bgpd for the most part. Currently it's
not doing anything (kroute_first/kroute_getaddr will always
select the rtable 0) since it needs new MIBs and some more
diffs from blambert@.
OK?
diff --git usr.sbin/snmpd/kroute.c usr.sbin/snmpd/kroute.c
index e157b25..d1f8890 100644
--- usr.sbin/snmpd/kroute.c
+++ usr.sbin/snmpd/kroute.c
@@ -45,10 +45,13 @@
#include "snmpd.h"
extern struct snmpd *env;
+struct ktable **krt;
+u_int krt_size;
+
struct {
struct event ks_ev;
u_long ks_iflastchange;
u_long ks_nroutes; /* 4 billions enough? */
int ks_fd;
@@ -77,24 +80,32 @@ struct kif_node {
int kroute_compare(struct kroute_node *, struct kroute_node *);
int kroute6_compare(struct kroute6_node *, struct kroute6_node *);
int kif_compare(struct kif_node *, struct kif_node *);
-struct kroute_node *kroute_find(in_addr_t, u_int8_t, u_int8_t);
+void ktable_init(void);
+int ktable_new(u_int, u_int);
+void ktable_free(u_int);
+int ktable_exists(u_int, u_int *);
+struct ktable *ktable_get(u_int);
+int ktable_update(u_int);
+
+struct kroute_node *kroute_find(struct ktable *, in_addr_t, u_int8_t,
+ u_int8_t);
struct kroute_node *kroute_matchgw(struct kroute_node *,
struct sockaddr_in *);
-int kroute_insert(struct kroute_node *);
-int kroute_remove(struct kroute_node *);
-void kroute_clear(void);
+int kroute_insert(struct ktable *, struct kroute_node *);
+int kroute_remove(struct ktable *, struct kroute_node *);
+void kroute_clear(struct ktable *);
-struct kroute6_node *kroute6_find(const struct in6_addr *, u_int8_t,
- u_int8_t);
+struct kroute6_node *kroute6_find(struct ktable *, const struct in6_addr *,
+ u_int8_t, u_int8_t);
struct kroute6_node *kroute6_matchgw(struct kroute6_node *,
struct sockaddr_in6 *);
-int kroute6_insert(struct kroute6_node *);
-int kroute6_remove(struct kroute6_node *);
-void kroute6_clear(void);
+int kroute6_insert(struct ktable *, struct kroute6_node *);
+int kroute6_remove(struct ktable *, struct kroute6_node *);
+void kroute6_clear(struct ktable *);
struct kif_arp *karp_find(struct sockaddr *, u_short);
int karp_insert(struct kif_node *, struct kif_arp *);
int karp_remove(struct kif_node *, struct kif_arp *);
@@ -121,23 +132,21 @@ void if_newaddr(u_short, struct sockaddr *,
struct sockaddr *,
struct sockaddr *);
void if_deladdr(u_short, struct sockaddr *, struct sockaddr *,
struct sockaddr *);
void if_announce(void *);
-int fetchtable(void);
+int fetchtable(struct ktable *);
int fetchifs(u_short);
-int fetcharp(void);
+int fetcharp(struct ktable *);
void dispatch_rtmsg(int, short, void *);
int rtmsg_process(char *, int);
-int dispatch_rtmsg_addr(struct rt_msghdr *,
+int dispatch_rtmsg_addr(struct ktable *, struct rt_msghdr *,
struct sockaddr *[RTAX_MAX]);
-RB_HEAD(kroute_tree, kroute_node) krt;
RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare)
-RB_HEAD(kroute6_tree, kroute6_node) krt6;
RB_PROTOTYPE(kroute6_tree, kroute6_node, entry, kroute6_compare)
RB_GENERATE(kroute6_tree, kroute6_node, entry, kroute6_compare)
RB_HEAD(kif_tree, kif_node) kit;
RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare)
@@ -149,10 +158,11 @@ RB_GENERATE(ka_tree, kif_addr, node, ka_compare)
void
kr_init(void)
{
int opt = 0, rcvbuf, default_rcvbuf;
+ unsigned int tid = RTABLE_ANY;
socklen_t optlen;
if ((kr_state.ks_ifd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
fatal("kr_init: ioctl socket");
@@ -179,31 +189,166 @@ kr_init(void)
setsockopt(kr_state.ks_fd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf, sizeof(rcvbuf)) == -1 && errno == ENOBUFS;
rcvbuf /= 2)
; /* nothing */
- RB_INIT(&krt);
- RB_INIT(&krt6);
+ if (setsockopt(kr_state.ks_fd, AF_ROUTE, ROUTE_TABLEFILTER, &tid,
+ sizeof(tid)) == -1)
+ log_warn("kr_init: setsockopt AF_ROUTE ROUTE_TABLEFILTER");
+
RB_INIT(&kit);
RB_INIT(&kat);
if (fetchifs(0) == -1)
fatalx("kr_init fetchifs");
- if (fetchtable() == -1)
- fatalx("kr_init fetchtable");
- if (fetcharp() == -1)
- fatalx("kr_init fetcharp");
+
+ ktable_init();
event_set(&kr_state.ks_ev, kr_state.ks_fd, EV_READ | EV_PERSIST,
dispatch_rtmsg, NULL);
event_add(&kr_state.ks_ev, NULL);
}
void
+ktable_init(void)
+{
+ u_int i;
+
+ for (i = 0; i < RT_TABLEID_MAX; i++)
+ if (ktable_exists(i, 0))
+ ktable_update(i);
+}
+
+int
+ktable_new(u_int rtableid, u_int rdomid)
+{
+ struct ktable **xkrt;
+ struct ktable *kt;
+ size_t newsize, oldsize;
+
+ /* resize index table if needed */
+ if (rtableid >= krt_size) {
+ oldsize = sizeof(struct ktable *) * krt_size;
+ newsize = sizeof(struct ktable *) * (rtableid + 1);
+ if ((xkrt = realloc(krt, newsize)) == NULL) {
+ log_warn("ktable_new");
+ return (-1);
+ }
+ krt = xkrt;
+ krt_size = rtableid + 1;
+ bzero((char *)krt + oldsize, newsize - oldsize);
+ }
+
+ if (krt[rtableid])
+ fatalx("ktable_new: table already exists.");
+
+ /* allocate new element */
+ kt = krt[rtableid] = calloc(1, sizeof(struct ktable));
+ if (kt == NULL) {
+ log_warn("ktable_new");
+ return (-1);
+ }
+
+ /* initialize structure ... */
+ RB_INIT(&kt->krt);
+ RB_INIT(&kt->krt6);
+ kt->rtableid = rtableid;
+ kt->rdomain = rdomid;
+
+ /* ... and load it */
+ if (fetchtable(kt) == -1)
+ return (-1);
+ /* load arp information */
+ if (fetcharp(kt) == -1)
+ return (-1);
+
+ log_debug("new ktable for rtableid %d", rtableid);
+ return (0);
+}
+
+void
+ktable_free(u_int rtableid)
+{
+ struct ktable *kt;
+
+ if ((kt = ktable_get(rtableid)) == NULL)
+ return;
+
+ log_debug("freeing ktable rtableid %u", kt->rtableid);
+ kroute_clear(kt);
+ kroute6_clear(kt);
+
+ krt[kt->rtableid] = NULL;
+ free(kt);
+}
+
+struct ktable *
+ktable_get(u_int rtableid)
+{
+ if (rtableid >= krt_size)
+ return (NULL);
+ return (krt[rtableid]);
+}
+
+int
+ktable_update(u_int rtableid)
+{
+ struct ktable *kt;
+ u_int rdomid;
+
+ if (!ktable_exists(rtableid, &rdomid))
+ fatalx("King Bula lost a table"); /* may not happen */
+
+ if (rdomid != rtableid) {
+ if (ktable_get(rdomid) == NULL &&
+ ktable_new(rdomid, rdomid) != 0)
+ return (-1);
+ }
+
+ kt = ktable_get(rtableid);
+ if (kt == NULL) {
+ if (ktable_new(rtableid, rdomid))
+ return (-1);
+ }
+ return (0);
+}
+
+int
+ktable_exists(u_int rtableid, u_int *rdomid)
+{
+ size_t len;
+ struct rt_tableinfo info;
+ int mib[6];
+
+ mib[0] = CTL_NET;
+ mib[1] = AF_ROUTE;
+ mib[2] = 0;
+ mib[3] = 0;
+ mib[4] = NET_RT_TABLE;
+ mib[5] = rtableid;
+
+ len = sizeof(info);
+ if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) {
+ if (errno == ENOENT)
+ /* table nonexistent */
+ return (0);
+ log_warn("sysctl");
+ /* must return 0 so that the table is considered non-existent */
+ return (0);
+ }
+ if (rdomid)
+ *rdomid = info.rti_domainid;
+ return (1);
+}
+
+void
kr_shutdown(void)
{
- kroute_clear();
+ u_int i;
+
+ for (i = krt_size; i > 0; i--)
+ ktable_free(i - 1);
kif_clear();
}
u_int
kr_ifnumber(void)
@@ -301,28 +446,29 @@ ka_compare(struct kif_addr *a, struct kif_addr *b)
return (memcmp(&a->addr.sa, &b->addr.sa, a->addr.sa.sa_len));
}
/* tree management */
struct kroute_node *
-kroute_find(in_addr_t prefix, u_int8_t prefixlen, u_int8_t prio)
+kroute_find(struct ktable *kt, in_addr_t prefix, u_int8_t prefixlen,
+ u_int8_t prio)
{
struct kroute_node s;
struct kroute_node *kn, *tmp;
s.r.prefix.s_addr = prefix;
s.r.prefixlen = prefixlen;
s.r.priority = prio;
- kn = RB_FIND(kroute_tree, &krt, &s);
+ kn = RB_FIND(kroute_tree, &kt->krt, &s);
if (kn && prio == RTP_ANY) {
- tmp = RB_PREV(kroute_tree, &krt, kn);
+ tmp = RB_PREV(kroute_tree, &kt->krt, kn);
while (tmp) {
if (kroute_compare(&s, tmp) == 0)
kn = tmp;
else
break;
- tmp = RB_PREV(kroute_tree, &krt, kn);
+ tmp = RB_PREV(kroute_tree, &kt->krt, kn);
}
}
return (kn);
}
@@ -345,15 +491,15 @@ kroute_matchgw(struct kroute_node *kr, struct sockaddr_in
*sa_in)
return (NULL);
}
int
-kroute_insert(struct kroute_node *kr)
+kroute_insert(struct ktable *kt, struct kroute_node *kr)
{
struct kroute_node *krm;
- if ((krm = RB_INSERT(kroute_tree, &krt, kr)) != NULL) {
+ if ((krm = RB_INSERT(kroute_tree, &kt->krt, kr)) != NULL) {
/* multipath route, add at end of list */
while (krm->next != NULL)
krm = krm->next;
krm->next = kr;
kr->next = NULL; /* to be sure */
@@ -362,29 +508,30 @@ kroute_insert(struct kroute_node *kr)
kr_state.ks_nroutes++;
return (0);
}
int
-kroute_remove(struct kroute_node *kr)
+kroute_remove(struct ktable *kt, struct kroute_node *kr)
{
struct kroute_node *krm;
- if ((krm = RB_FIND(kroute_tree, &krt, kr)) == NULL) {
+ if ((krm = RB_FIND(kroute_tree, &kt->krt, kr)) == NULL) {
log_warnx("kroute_remove failed to find %s/%u",
inet_ntoa(kr->r.prefix), kr->r.prefixlen);
return (-1);
}
if (krm == kr) {
/* head element */
- if (RB_REMOVE(kroute_tree, &krt, kr) == NULL) {
+ if (RB_REMOVE(kroute_tree, &kt->krt, kr) == NULL) {
log_warnx("kroute_remove failed for %s/%u",
inet_ntoa(kr->r.prefix), kr->r.prefixlen);
return (-1);
}
if (kr->next != NULL) {
- if (RB_INSERT(kroute_tree, &krt, kr->next) != NULL) {
+ if (RB_INSERT(kroute_tree, &kt->krt, kr->next)
+ != NULL) {
log_warnx("kroute_remove failed to add %s/%u",
inet_ntoa(kr->r.prefix), kr->r.prefixlen);
return (-1);
}
}
@@ -405,37 +552,38 @@ kroute_remove(struct kroute_node *kr)
free(kr);
return (0);
}
void
-kroute_clear(void)
+kroute_clear(struct ktable *kt)
{
struct kroute_node *kr;
- while ((kr = RB_MIN(kroute_tree, &krt)) != NULL)
- kroute_remove(kr);
+ while ((kr = RB_MIN(kroute_tree, &kt->krt)) != NULL)
+ kroute_remove(kt, kr);
}
struct kroute6_node *
-kroute6_find(const struct in6_addr *prefix, u_int8_t prefixlen, u_int8_t prio)
+kroute6_find(struct ktable *kt, const struct in6_addr *prefix,
+ u_int8_t prefixlen, u_int8_t prio)
{
struct kroute6_node s;
struct kroute6_node *kn6, *tmp;
memcpy(&s.r.prefix, prefix, sizeof(struct in6_addr));
s.r.prefixlen = prefixlen;
s.r.priority = prio;
- kn6 = RB_FIND(kroute6_tree, &krt6, &s);
+ kn6 = RB_FIND(kroute6_tree, &kt->krt6, &s);
if (kn6 && prio == RTP_ANY) {
- tmp = RB_PREV(kroute6_tree, &krt6, kn6);
+ tmp = RB_PREV(kroute6_tree, &kt->krt6, kn6);
while (tmp) {
if (kroute6_compare(&s, tmp) == 0)
kn6 = tmp;
else
break;
- tmp = RB_PREV(kroute6_tree, &krt6, kn6);
+ tmp = RB_PREV(kroute6_tree, &kt->krt6, kn6);
}
}
return (kn6);
}
@@ -458,15 +606,15 @@ kroute6_matchgw(struct kroute6_node *kr, struct
sockaddr_in6 *sa_in6)
return (NULL);
}
int
-kroute6_insert(struct kroute6_node *kr)
+kroute6_insert(struct ktable *kt, struct kroute6_node *kr)
{
struct kroute6_node *krm;
- if ((krm = RB_INSERT(kroute6_tree, &krt6, kr)) != NULL) {
+ if ((krm = RB_INSERT(kroute6_tree, &kt->krt6, kr)) != NULL) {
/* multipath route, add at end of list */
while (krm->next != NULL)
krm = krm->next;
krm->next = kr;
kr->next = NULL; /* to be sure */
@@ -475,29 +623,30 @@ kroute6_insert(struct kroute6_node *kr)
kr_state.ks_nroutes++;
return (0);
}
int
-kroute6_remove(struct kroute6_node *kr)
+kroute6_remove(struct ktable *kt, struct kroute6_node *kr)
{
struct kroute6_node *krm;
- if ((krm = RB_FIND(kroute6_tree, &krt6, kr)) == NULL) {
+ if ((krm = RB_FIND(kroute6_tree, &kt->krt6, kr)) == NULL) {
log_warnx("kroute6_remove failed for %s/%u",
log_in6addr(&kr->r.prefix), kr->r.prefixlen);
return (-1);
}
if (krm == kr) {
/* head element */
- if (RB_REMOVE(kroute6_tree, &krt6, kr) == NULL) {
+ if (RB_REMOVE(kroute6_tree, &kt->krt6, kr) == NULL) {
log_warnx("kroute6_remove failed for %s/%u",
log_in6addr(&kr->r.prefix), kr->r.prefixlen);
return (-1);
}
if (kr->next != NULL) {
- if (RB_INSERT(kroute6_tree, &krt6, kr->next) != NULL) {
+ if (RB_INSERT(kroute6_tree, &kt->krt6, kr->next) !=
+ NULL) {
log_warnx("kroute6_remove failed to add %s/%u",
log_in6addr(&kr->r.prefix),
kr->r.prefixlen);
return (-1);
}
@@ -519,16 +668,16 @@ kroute6_remove(struct kroute6_node *kr)
free(kr);
return (0);
}
void
-kroute6_clear(void)
+kroute6_clear(struct ktable *kt)
{
struct kroute6_node *kr;
- while ((kr = RB_MIN(kroute6_tree, &krt6)) != NULL)
- kroute6_remove(kr);
+ while ((kr = RB_MIN(kroute6_tree, &kt->krt6)) != NULL)
+ kroute6_remove(kt, kr);
}
static inline int
karp_compare(struct kif_arp *a, struct kif_arp *b)
{
@@ -1021,46 +1170,49 @@ if_announce(void *msg)
switch (ifan->ifan_what) {
case IFAN_ARRIVAL:
kif = kif_insert(ifan->ifan_index);
strlcpy(kif->k.if_name, ifan->ifan_name,
sizeof(kif->k.if_name));
- /* Update the ARP table */
- fetcharp();
break;
case IFAN_DEPARTURE:
kif = kif_find(ifan->ifan_index);
kif_remove(kif);
break;
}
}
int
-fetchtable(void)
+fetchtable(struct ktable *kt)
{
int mib[7];
size_t len;
char *buf;
int rv;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
- mib[3] = AF_INET;
+ mib[3] = AF_INET; /* MIKE XXX */
mib[4] = NET_RT_DUMP;
mib[5] = 0;
- mib[6] = 0; /* rtableid */
+ mib[6] = kt->rtableid;
if (sysctl(mib, 7, NULL, &len, NULL, 0) == -1) {
+ if (kt->rtableid != 0 && errno == EINVAL)
+ /* table nonexistent */
+ return (0);
log_warn("sysctl");
return (-1);
}
+ if (len == 0)
+ return (0);
if ((buf = malloc(len)) == NULL) {
log_warn("fetchtable");
return (-1);
}
if (sysctl(mib, 7, buf, &len, NULL, 0) == -1) {
- log_warn("sysctl");
+ log_warn("sysctl2");
free(buf);
return (-1);
}
rv = rtmsg_process(buf, len);
@@ -1103,11 +1255,11 @@ fetchifs(u_short if_index)
return (rv);
}
int
-fetcharp(void)
+fetcharp(struct ktable *kt)
{
size_t len;
int mib[7];
char *buf;
int rv;
@@ -1116,11 +1268,11 @@ fetcharp(void)
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
- mib[6] = 0;
+ mib[6] = kt->rtableid;
if (sysctl(mib, 7, NULL, &len, NULL, 0) == -1) {
log_warn("sysctl");
return (-1);
}
@@ -1164,10 +1316,11 @@ dispatch_rtmsg(int fd, short event, void *arg)
}
int
rtmsg_process(char *buf, int len)
{
+ struct ktable *kt;
struct rt_msghdr *rtm;
struct if_msghdr ifm;
struct ifa_msghdr *ifam;
struct sockaddr *sa, *rti_info[RTAX_MAX];
int offset;
@@ -1189,11 +1342,14 @@ rtmsg_process(char *buf, int len)
case RTM_DELETE:
case RTM_RESOLVE:
if (rtm->rtm_errno) /* failed attempts */
continue;
- if (dispatch_rtmsg_addr(rtm, rti_info) == -1)
+ if ((kt = ktable_get(rtm->rtm_tableid)) == NULL)
+ continue;
+
+ if (dispatch_rtmsg_addr(kt, rtm, rti_info) == -1)
return (-1);
break;
case RTM_IFINFO:
memcpy(&ifm, next, sizeof(ifm));
if_change(ifm.ifm_index, ifm.ifm_flags, &ifm.ifm_data,
@@ -1228,11 +1384,12 @@ rtmsg_process(char *buf, int len)
return (offset);
}
int
-dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr *rti_info[RTAX_MAX])
+dispatch_rtmsg_addr(struct ktable *kt, struct rt_msghdr *rtm,
+ struct sockaddr *rti_info[RTAX_MAX])
{
struct sockaddr *sa, *psa;
struct sockaddr_in *sa_in, *psa_in = NULL;
struct sockaddr_in6 *sa_in6, *psa_in6 = NULL;
struct sockaddr_dl *sa_dl;
@@ -1319,11 +1476,11 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX])
/* Continue to the route section below */
}
switch (psa->sa_family) {
case AF_INET:
sa_in = (struct sockaddr_in *)sa;
- if ((kr = kroute_find(psa_in->sin_addr.s_addr,
+ if ((kr = kroute_find(kt, psa_in->sin_addr.s_addr,
prefixlen, prio)) == NULL)
return (0);
if (mpath)
/* get the correct route */
@@ -1331,17 +1488,17 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX])
log_warnx("dispatch_rtmsg[delete] "
"mpath route not found");
return (0);
}
- if (kroute_remove(kr) == -1)
+ if (kroute_remove(kt, kr) == -1)
return (-1);
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *)sa;
- if ((kr6 = kroute6_find(&psa_in6->sin6_addr, prefixlen,
- prio)) == NULL)
+ if ((kr6 = kroute6_find(kt, &psa_in6->sin6_addr,
+ prefixlen, prio)) == NULL)
return (0);
if (mpath)
/* get the correct route */
if ((kr6 = kroute6_matchgw(kr6, sa_in6)) ==
@@ -1349,11 +1506,11 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX])
log_warnx("dispatch_rtmsg[delete] "
"IPv6 mpath route not found");
return (0);
}
- if (kroute6_remove(kr6) == -1)
+ if (kroute6_remove(kt, kr6) == -1)
return (-1);
break;
}
return (0);
}
@@ -1398,11 +1555,11 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX])
}
switch (psa->sa_family) {
case AF_INET:
sa_in = (struct sockaddr_in *)sa;
- if ((kr = kroute_find(psa_in->sin_addr.s_addr, prefixlen,
+ if ((kr = kroute_find(kt, psa_in->sin_addr.s_addr, prefixlen,
prio)) != NULL) {
/* get the correct route */
if (mpath && rtm->rtm_type == RTM_CHANGE &&
(kr = kroute_matchgw(kr, sa_in)) == NULL) {
log_warnx("dispatch_rtmsg[change] "
@@ -1435,16 +1592,16 @@ add4:
kr->r.flags = flags;
kr->r.if_index = ifindex;
kr->r.ticks = smi_getticks();
kr->r.priority = prio;
- kroute_insert(kr);
+ kroute_insert(kt, kr);
}
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *)sa;
- if ((kr6 = kroute6_find(&psa_in6->sin6_addr, prefixlen,
+ if ((kr6 = kroute6_find(kt, &psa_in6->sin6_addr, prefixlen,
prio)) != NULL) {
/* get the correct route */
if (mpath && rtm->rtm_type == RTM_CHANGE &&
(kr6 = kroute6_matchgw(kr6, sa_in6)) ==
NULL) {
@@ -1485,11 +1642,11 @@ add6:
kr6->r.flags = flags;
kr6->r.if_index = ifindex;
kr6->r.ticks = smi_getticks();
kr6->r.priority = prio;
- kroute6_insert(kr6);
+ kroute6_insert(kt, kr6);
}
break;
}
return (0);
@@ -1497,23 +1654,29 @@ add6:
struct kroute *
kroute_first(void)
{
struct kroute_node *kn;
+ struct ktable *kt;
- kn = RB_MIN(kroute_tree, &krt);
+ if ((kt = ktable_get(0)) == NULL)
+ return (NULL);
+ kn = RB_MIN(kroute_tree, &kt->krt);
return (&kn->r);
}
struct kroute *
kroute_getaddr(in_addr_t prefix, u_int8_t prefixlen, u_int8_t prio, int next)
{
struct kroute_node *kn;
+ struct ktable *kt;
- kn = kroute_find(prefix, prefixlen, prio);
+ if ((kt = ktable_get(0)) == NULL)
+ return (NULL);
+ kn = kroute_find(kt, prefix, prefixlen, prio);
if (kn != NULL && next)
- kn = RB_NEXT(kroute_tree, &krt, kn);
+ kn = RB_NEXT(kroute_tree, &kt->krt, kn);
if (kn != NULL)
return (&kn->r);
else
return (NULL);
}
diff --git usr.sbin/snmpd/snmpd.h usr.sbin/snmpd/snmpd.h
index bd5eae9..3d56f8e 100644
--- usr.sbin/snmpd/snmpd.h
+++ usr.sbin/snmpd/snmpd.h
@@ -170,10 +170,22 @@ extern struct ctl_connlist ctl_conns;
/*
* kroute
*/
+struct kroute_node;
+struct kroute6_node;
+RB_HEAD(kroute_tree, kroute_node);
+RB_HEAD(kroute6_tree, kroute6_node);
+
+struct ktable {
+ struct kroute_tree krt;
+ struct kroute6_tree krt6;
+ u_int rtableid;
+ u_int rdomain;
+};
+
union kaddr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_dl sdl;