On Fri, Jun 09, 2017 at 04:40:18PM +0200, Martin Pieuchot wrote:
> Now with the correct diff:

OK bluhm@

> 
> Index: net/radix.c
> ===================================================================
> RCS file: /cvs/src/sys/net/radix.c,v
> retrieving revision 1.56
> diff -u -p -r1.56 radix.c
> --- net/radix.c       24 Jan 2017 10:08:30 -0000      1.56
> +++ net/radix.c       9 Jun 2017 14:22:16 -0000
> @@ -48,24 +48,32 @@
>  
>  #include <net/radix.h>
>  
> -static unsigned int max_keylen;
> -struct radix_node_head *mask_rnhead;
> -static char *addmask_key;
> -static char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 
> -1};
> -static char *rn_zeros, *rn_ones;
> +#define SALEN(sa)    (*(u_char *)(sa))
> +
> +/*
> + * Read-only variables, allocated & filled during rn_init().
> + */
> +static char          *rn_zeros;      /* array of 0s */
> +static char          *rn_ones;       /* array of 1s */
> +static unsigned int   max_keylen;    /* size of the above arrays */
> +#define KEYLEN_LIMIT  64             /* maximum allowed keylen */
>  
> -struct pool rtmask_pool;     /* pool for radix_mask structures */
>  
> -#define rn_masktop (mask_rnhead->rnh_treetop)
> +struct radix_node_head       *mask_rnhead;   /* head of shared mask tree */
> +struct pool           rtmask_pool;   /* pool for radix_mask structures */
>  
>  static inline int rn_satisfies_leaf(char *, struct radix_node *, int);
>  static inline int rn_lexobetter(void *, void *);
>  static inline struct radix_mask *rn_new_radix_mask(struct radix_node *,
>      struct radix_mask *);
>  
> +int rn_refines(void *, void *);
> +int rn_inithead0(struct radix_node_head *, int);
> +struct radix_node *rn_addmask(void *, int, int);
>  struct radix_node *rn_insert(void *, struct radix_node_head *, int *,
>      struct radix_node [2]);
>  struct radix_node *rn_newpair(void *, int, struct radix_node[2]);
> +void rn_link_dupedkey(struct radix_node *, struct radix_node *, int);
>  
>  static inline struct radix_node *rn_search(void *, struct radix_node *);
>  struct radix_node *rn_search_m(void *, struct radix_node *, void *);
> @@ -205,11 +213,11 @@ rn_satisfies_leaf(char *trial, struct ra
>       char *cplim;
>       int length;
>  
> -     length = min(*(u_char *)cp, *(u_char *)cp2);
> +     length = min(SALEN(cp), SALEN(cp2));
>       if (cp3 == NULL)
>               cp3 = rn_ones;
>       else
> -             length = min(length, *(u_char *)cp3);
> +             length = min(length, SALEN(cp3));
>       cplim = cp + length;
>       cp += skip;
>       cp2 += skip;
> @@ -246,9 +254,9 @@ rn_match(void *v_arg, struct radix_node_
>        * are probably the most common case...
>        */
>       if (t->rn_mask)
> -             vlen = *(u_char *)t->rn_mask;
> +             vlen = SALEN(t->rn_mask);
>       else
> -             vlen = *(u_char *)v;
> +             vlen = SALEN(v);
>       cp = v + off;
>       cp2 = t->rn_key + off;
>       cplim = v + vlen;
> @@ -361,7 +369,7 @@ rn_insert(void *v_arg, struct radix_node
>       caddr_t cp, cp2, cplim;
>       int vlen, cmp_res;
>  
> -     vlen =  *(u_char *)v;
> +     vlen =  SALEN(v);
>       cp = v + off;
>       cp2 = t->rn_key + off;
>       cplim = v + vlen;
> @@ -413,9 +421,9 @@ rn_addmask(void *n_arg, int search, int 
>       caddr_t cp, cplim;
>       int b = 0, mlen, j;
>       int maskduplicated, m0, isnormal;
> -     static int last_zeroed = 0;
> +     char addmask_key[KEYLEN_LIMIT];
>  
> -     if ((mlen = *(u_char *)netmask) > max_keylen)
> +     if ((mlen = SALEN(netmask)) > max_keylen)
>               mlen = max_keylen;
>       if (skip == 0)
>               skip = 1;
> @@ -431,15 +439,11 @@ rn_addmask(void *n_arg, int search, int 
>       for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;)
>               cp--;
>       mlen = cp - addmask_key;
> -     if (mlen <= skip) {
> -             if (m0 >= last_zeroed)
> -                     last_zeroed = mlen;
> +     if (mlen <= skip)
>               return (mask_rnhead->rnh_nodes);
> -     }
> -     if (m0 < last_zeroed)
> -             memset(addmask_key + m0, 0, last_zeroed - m0);
> -     *addmask_key = last_zeroed = mlen;
> -     tm = rn_search(addmask_key, rn_masktop);
> +     memset(addmask_key + m0, 0, max_keylen - m0);
> +     SALEN(addmask_key) = mlen;
> +     tm = rn_search(addmask_key, mask_rnhead->rnh_treetop);
>       if (memcmp(addmask_key, tm->rn_key, mlen) != 0)
>               tm = NULL;
>       if (tm || search)
> @@ -452,7 +456,7 @@ rn_addmask(void *n_arg, int search, int 
>       memcpy(cp, addmask_key, mlen);
>       tm = rn_insert(cp, mask_rnhead, &maskduplicated, tm);
>       if (maskduplicated) {
> -             log(LOG_ERR, "rn_addmask: mask impossibly already in tree\n");
> +             log(LOG_ERR, "%s: mask impossibly already in tree\n", __func__);
>               free(saved_tm, M_RTABLE, 0);
>               return (tm);
>       }
> @@ -464,6 +468,9 @@ rn_addmask(void *n_arg, int search, int 
>       for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;)
>               cp++;
>       if (cp != cplim) {
> +             static const char normal_chars[] = {
> +                     0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, -1
> +             };
>               for (j = 0x80; (j & *cp) != 0; j >>= 1)
>                       b++;
>               if (*cp != normal_chars[b] || cp != (cplim - 1))
> @@ -488,9 +495,9 @@ rn_lexobetter(void *m_arg, void *n_arg)
>        * first. The netmasks were normalized before calling this function and
>        * don't have unneeded trailing zeros.
>        */
> -     if (*mp > *np)
> +     if (SALEN(mp) > SALEN(np))
>               return 1;
> -     if (*mp < *np)
> +     if (SALEN(mp) < SALEN(np))
>               return 0;
>       /*
>        * Must return the first difference between the masks
> @@ -756,6 +763,8 @@ rn_addroute(void *v_arg, void *n_arg, st
>       struct radix_node *tt, *saved_tt, *tm = NULL;
>       int keyduplicated;
>  
> +     KERNEL_ASSERT_LOCKED();
> +
>       /*
>        * In dealing with non-contiguous masks, there may be
>        * many different routes which have the same mask.
> @@ -905,7 +914,9 @@ rn_delete(void *v_arg, void *n_arg, stru
>       int off = top->rn_off;
>       int vlen;
>  
> -     vlen =  *(u_char *)v;
> +     KERNEL_ASSERT_LOCKED();
> +
> +     vlen = SALEN(v);
>  
>       /*
>        * Implement a lookup similar to rn_lookup but we need to save
> @@ -1050,6 +1061,8 @@ rn_walktree(struct radix_node_head *h, i
>       int error;
>       struct radix_node *base, *next;
>       struct radix_node *rn = h->rnh_treetop;
> +
> +     KERNEL_ASSERT_LOCKED();
>       /*
>        * This gets complicated because we may delete the node
>        * while applying the function f to it, so we need to calculate
> @@ -1138,13 +1151,15 @@ rn_inithead0(struct radix_node_head *rnh
>  
>  /*
>   * rn_init() can be called multiple time with a different key length
> - * as long as not radix tree head has been allocated.
> + * as long as no radix tree head has been allocated.
>   */
>  void
>  rn_init(unsigned int keylen)
>  {
>       char *cp, *cplim;
>  
> +     KASSERT(keylen <= KEYLEN_LIMIT);
> +
>       if (max_keylen == 0) {
>               pool_init(&rtmask_pool, sizeof(struct radix_mask), 0,
>                   IPL_SOFTNET, 0, "rtmask", NULL);
> @@ -1155,14 +1170,14 @@ rn_init(unsigned int keylen)
>  
>       KASSERT(mask_rnhead == NULL);
>  
> -     free(rn_zeros, M_RTABLE, 3 * max_keylen);
> -     rn_zeros = mallocarray(3, keylen, M_RTABLE, M_NOWAIT | M_ZERO);
> +     free(rn_zeros, M_RTABLE, 2 * max_keylen);
> +     rn_zeros = mallocarray(2, keylen, M_RTABLE, M_NOWAIT | M_ZERO);
>       if (rn_zeros == NULL)
>               panic("cannot initialize a radix tree without memory");
>       max_keylen = keylen;
>  
> -     rn_ones = cp = rn_zeros + max_keylen;
> -     addmask_key = cplim = rn_ones + max_keylen;
> +     cp = rn_ones = rn_zeros + max_keylen;
> +     cplim = rn_ones + max_keylen;
>       while (cp < cplim)
>               *cp++ = -1;
>  }
> Index: net/radix.h
> ===================================================================
> RCS file: /cvs/src/sys/net/radix.h,v
> retrieving revision 1.29
> diff -u -p -r1.29 radix.h
> --- net/radix.h       14 Nov 2016 08:56:12 -0000      1.29
> +++ net/radix.h       6 Jun 2017 13:21:56 -0000
> @@ -98,14 +98,10 @@ struct radix_node_head {
>  
>  void rn_init(unsigned int);
>  int  rn_inithead(void **, int);
> -int  rn_inithead0(struct radix_node_head *, int);
> -int  rn_refines(void *, void *);
> -void rn_link_dupedkey(struct radix_node *, struct radix_node *, int);
>  
>  int  rn_walktree(struct radix_node_head *,
>           int (*)(struct radix_node *, void *, u_int), void *);
>  
> -struct radix_node    *rn_addmask(void *, int, int);
>  struct radix_node    *rn_addroute(void *, void *, struct radix_node_head *,
>                           struct radix_node [2], u_int8_t);
>  struct radix_node    *rn_delete(void *, void *, struct radix_node_head *,

Reply via email to