On Sun, Oct 25, 2015 at 03:22:51PM +0100, Martin Pieuchot wrote:
> Instead of having a separate function to check for MPATH conflicts
> simply pass the gateway to rtable_insert().  Some regress tests
> outputs will need an update as we're now doing one more rtalloc(9)
> call in RTM_ADD. 
> 
> This is a step towards MPATH by default.
> 
> ok?

Looks good to me. We still return EEXIST so there should be no visible
change because of this.

 
> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.262
> diff -u -p -r1.262 route.c
> --- net/route.c       25 Oct 2015 11:58:11 -0000      1.262
> +++ net/route.c       25 Oct 2015 14:14:28 -0000
> @@ -837,15 +837,6 @@ rtrequest1(int req, struct rt_addrinfo *
>               else
>                       memcpy(ndst, info->rti_info[RTAX_DST], dlen);
>  
> -#ifndef SMALL_KERNEL
> -             /* Do not permit exactly the same dst/mask/gw pair. */
> -             if (rtable_mpath_conflict(tableid, ndst,
> -                 info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY],
> -                 prio, info->rti_flags & RTF_MPATH)) {
> -                     free(ndst, M_RTABLE, dlen);
> -                     return (EEXIST);
> -             }
> -#endif
>               rt = pool_get(&rtentry_pool, PR_NOWAIT | PR_ZERO);
>               if (rt == NULL) {
>                       free(ndst, M_RTABLE, dlen);
> @@ -953,13 +944,15 @@ rtrequest1(int req, struct rt_addrinfo *
>               }
>  
>               error = rtable_insert(tableid, ndst,
> -                 info->rti_info[RTAX_NETMASK], rt->rt_priority, rt);
> +                 info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY],
> +                 rt->rt_priority, rt);
>               if (error != 0 && (crt = rtalloc(ndst, 0, tableid)) != NULL) {
>                       /* overwrite cloned route */
>                       if ((crt->rt_flags & RTF_CLONED) != 0) {
>                               rtdeletemsg(crt, tableid);
>                               error = rtable_insert(tableid, ndst,
>                                   info->rti_info[RTAX_NETMASK],
> +                                 info->rti_info[RTAX_GATEWAY],
>                                   rt->rt_priority, rt);
>                       }
>                       rtfree(crt);
> Index: net/rtable.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtable.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 rtable.c
> --- net/rtable.c      22 Oct 2015 17:19:38 -0000      1.14
> +++ net/rtable.c      25 Oct 2015 14:13:57 -0000
> @@ -292,7 +292,8 @@ rtable_match(unsigned int rtableid, stru
>  
>  int
>  rtable_insert(unsigned int rtableid, struct sockaddr *dst,
> -    struct sockaddr *mask, uint8_t prio, struct rtentry *rt)
> +    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio,
> +    struct rtentry *rt)
>  {
>       struct radix_node_head  *rnh;
>       struct radix_node       *rn = (struct radix_node *)rt;
> @@ -301,6 +302,15 @@ rtable_insert(unsigned int rtableid, str
>       if (rnh == NULL)
>               return (EAFNOSUPPORT);
>  
> +#ifndef SMALL_KERNEL
> +     if (rnh->rnh_multipath) {
> +             /* Do not permit exactly the same dst/mask/gw pair. */
> +             if (rt_mpath_conflict(rnh, dst, mask, gateway, prio,
> +                 ISSET(rt->rt_flags, RTF_MPATH)))
> +                     return (EEXIST);
> +     }
> +#endif
> +
>       rn = rn_addroute(dst, mask, rnh, rn, prio);
>       if (rn == NULL)
>               return (ESRCH);
> @@ -382,22 +392,6 @@ rtable_mpath_match(unsigned int rtableid
>       return (rt);
>  }
>  
> -int
> -rtable_mpath_conflict(unsigned int rtableid, struct sockaddr *dst,
> -    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, int 
> mpathok)
> -{
> -     struct radix_node_head  *rnh;
> -
> -     rnh = rtable_get(rtableid, dst->sa_family);
> -     if (rnh == NULL)
> -             return (EAFNOSUPPORT);
> -
> -     if (rnh->rnh_multipath == 0)
> -             return (0);
> -
> -     return (rt_mpath_conflict(rnh, dst, mask, gateway, prio, mpathok));
> -}
> -
>  /* Gateway selection by Hash-Threshold (RFC 2992) */
>  struct rtentry *
>  rtable_mpath_select(struct rtentry *rt, uint32_t hash)
> @@ -526,7 +520,8 @@ rtable_match(unsigned int rtableid, stru
>  
>  int
>  rtable_insert(unsigned int rtableid, struct sockaddr *dst,
> -    struct sockaddr *mask, uint8_t prio, struct rtentry *rt)
> +    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio,
> +    struct rtentry *rt)
>  {
>  #ifndef SMALL_KERNEL
>       struct rtentry                  *mrt;
> @@ -545,6 +540,29 @@ rtable_insert(unsigned int rtableid, str
>       if (plen == -1)
>               return (EINVAL);
>  
> +#ifndef SMALL_KERNEL
> +     /* Do not permit exactly the same dst/mask/gw pair. */
> +     an = art_lookup(ar, addr, plen);
> +     if (an != NULL && an->an_plen == plen &&
> +         !memcmp(an->an_dst, dst, dst->sa_len)) {
> +             struct rtentry  *mrt;
> +             int              mpathok = ISSET(rt->rt_flags, RTF_MPATH);
> +
> +             LIST_FOREACH(mrt, &an->an_rtlist, rt_next) {
> +                     if (prio != RTP_ANY &&
> +                         (mrt->rt_priority & RTP_MASK) != (prio & RTP_MASK))
> +                             continue;
> +
> +                     if (!mpathok)
> +                             return (EEXIST);
> +
> +                     if (mrt->rt_gateway->sa_len == gateway->sa_len &&
> +                         !memcmp(mrt->rt_gateway, gateway, gateway->sa_len))
> +                             return (EEXIST);
> +             }
> +     }
> +#endif
> +
>       an = pool_get(&an_pool, PR_NOWAIT | PR_ZERO);
>       if (an == NULL)
>               return (ENOBUFS);
> @@ -754,48 +772,6 @@ rtable_mpath_match(unsigned int rtableid
>       rtfree(rt0);
>  
>       return (rt);
> -}
> -
> -int
> -rtable_mpath_conflict(unsigned int rtableid, struct sockaddr *dst,
> -    struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, int 
> mpathok)
> -{
> -     struct art_root                 *ar;
> -     struct art_node                 *an;
> -     struct rtentry                  *rt;
> -     uint8_t                         *addr;
> -     int                              plen;
> -
> -     ar = rtable_get(rtableid, dst->sa_family);
> -     if (ar == NULL)
> -             return (EAFNOSUPPORT);
> -
> -     addr = satoaddr(ar, dst);
> -     plen = satoplen(ar, mask);
> -     if (plen == -1)
> -             return (EINVAL);
> -
> -     an = art_lookup(ar, addr, plen);
> -     /* Make sure we've got a perfect match. */
> -     if (an == NULL || an->an_plen != plen ||
> -         memcmp(an->an_dst, dst, dst->sa_len))
> -             return (0);
> -
> -     LIST_FOREACH(rt, &an->an_rtlist, rt_next) {
> -             if (prio != RTP_ANY &&
> -                 (rt->rt_priority & RTP_MASK) != (prio & RTP_MASK))
> -                     continue;
> -
> -             if (!mpathok)
> -                     return (EEXIST);
> -
> -             if (rt->rt_gateway->sa_len == gateway->sa_len &&
> -                 memcmp(rt->rt_gateway, gateway, gateway->sa_len) == 0)
> -                     return (EEXIST);
> -     }
> -
> -
> -     return (0);
>  }
>  
>  /* Gateway selection by Hash-Threshold (RFC 2992) */
> Index: net/rtable.h
> ===================================================================
> RCS file: /cvs/src/sys/net/rtable.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 rtable.h
> --- net/rtable.h      22 Oct 2015 17:19:38 -0000      1.7
> +++ net/rtable.h      25 Oct 2015 14:13:46 -0000
> @@ -57,7 +57,8 @@ struct rtentry      *rtable_lookup(unsigned i
>                    struct sockaddr *);
>  struct rtentry       *rtable_match(unsigned int, struct sockaddr *);
>  int           rtable_insert(unsigned int, struct sockaddr *,
> -                  struct sockaddr *, uint8_t, struct rtentry *);
> +                  struct sockaddr *, struct sockaddr *, uint8_t,
> +                  struct rtentry *);
>  int           rtable_delete(unsigned int, struct sockaddr *,
>                    struct sockaddr *, uint8_t, struct rtentry *);
>  int           rtable_walk(unsigned int, sa_family_t,
> @@ -66,8 +67,6 @@ int          rtable_walk(unsigned int, sa_famil
>  int           rtable_mpath_capable(unsigned int, sa_family_t);
>  struct rtentry       *rtable_mpath_match(unsigned int, struct rtentry *,
>                    struct sockaddr *, uint8_t);
> -int           rtable_mpath_conflict(unsigned int, struct sockaddr *,
> -                  struct sockaddr *, struct sockaddr *, uint8_t, int);
>  struct rtentry       *rtable_mpath_select(struct rtentry *, uint32_t);
>  void          rtable_mpath_reprio(struct rtentry *, uint8_t);
>  #endif /* _NET_RTABLE_H_ */
> 

-- 
:wq Claudio

Reply via email to