This adds ktable code from bgpd to fetch, store and perform lookups
in multiple routing tables.  Currently it doesn't do anything useful
but it's a prerequisite for any future work in this direction.

OK to get this in?

diff --git usr.sbin/snmpd/kroute.c usr.sbin/snmpd/kroute.c
index e157b25..e19f924 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, NULL))
+                       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,22 +1170,20 @@ 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;
@@ -1045,22 +1192,27 @@ fetchtable(void)
        mib[1] = AF_ROUTE;
        mib[2] = 0;
        mib[3] = AF_INET;
        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 048ef79..61bc749 100644
--- usr.sbin/snmpd/snmpd.h
+++ usr.sbin/snmpd/snmpd.h
@@ -186,10 +186,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;

Reply via email to