Re: snmpd: add backend from bgpd to support multiple routing tables
On Mon, Apr 28, 2014 at 14:20 +0200, Mike Belopuhov wrote: 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? Any objections? 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 @@ voidif_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 inttid = 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
snmpd: add backend from bgpd to support multiple routing tables
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_intkrt_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 { intkroute_compare(struct kroute_node *, struct kroute_node *); intkroute6_compare(struct kroute6_node *, struct kroute6_node *); intkif_compare(struct kif_node *, struct kif_node *); -struct kroute_node *kroute_find(in_addr_t, u_int8_t, u_int8_t); +voidktable_init(void); +int ktable_new(u_int, u_int); +voidktable_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 *); -voidkroute_clear(void); +int kroute_insert(struct ktable *, struct kroute_node *); +int kroute_remove(struct ktable *, struct kroute_node *); +voidkroute_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 *); -voidkroute6_clear(void); +int kroute6_insert(struct ktable *, struct kroute6_node *); +int kroute6_remove(struct ktable *, struct kroute6_node *); +voidkroute6_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 *); -intfetchtable(void); +intfetchtable(struct ktable *); intfetchifs(u_short); -intfetcharp(void); +intfetcharp(struct ktable *); void dispatch_rtmsg(int, short, void *); intrtmsg_process(char *, int); -intdispatch_rtmsg_addr(struct rt_msghdr *, +intdispatch_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 inttid = 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