Re: snmpd: add backend from bgpd to support multiple routing tables

2014-05-13 Thread Mike Belopuhov
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

2014-04-28 Thread Mike Belopuhov
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