On 02/12/15(Wed) 16:18, Vincent Gross wrote:
> When fed a broadcast address, ifa_ifwitaddr() returns the unicast ifa
> whose broadcast address match the input. This is used mainly to select
> ifa, and there can be trouble when you have 2 ifas on the same range
> (e.g. 10.0.0.1/24@em0 & 10.0.0.20/24@em1) :
> 
> netinet/ip_mroute.c:814
> net/route.c:785
> netinet/ip_divert.c:143
> net/if_vxlan.c:241
> 
> There are also places where broadcast addresses should not be tolerated :
> 
> netinet/ip_input.c:1061  broadcast address is not a module identifier
> netinet/ip_input.c:1141  see above
> netinet/ip_input.c:1197  see above
> netinet6/*:              no broadcast in ipv6
> net/route.c:562:         gateway shall never be a broadcast addr
> net/route.c:713:         see above
> 
> This diff removes broadcast matching from ifa_ifwithaddr, and
> adds or rewrites checks where necessary.
> 
> Comments ? Ok ?

Looks good to me.  Some nits below.

> Index: sys/netinet/in_pcb.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in_pcb.c,v
> retrieving revision 1.188
> diff -u -p -r1.188 in_pcb.c
> --- sys/netinet/in_pcb.c      30 Oct 2015 09:39:42 -0000      1.188
> +++ sys/netinet/in_pcb.c      2 Dec 2015 15:17:26 -0000
> @@ -328,14 +328,12 @@ in_pcbbind(struct inpcb *inp, struct mbu
>  
>                               ia = ifatoia(ifa_ifwithaddr(sintosa(sin),
>                                   inp->inp_rtableid));
> -                             if (ia == NULL)
> -                                     return (EADDRNOTAVAIL);
>  
>                               /* SOCK_RAW does not use in_pcbbind() */
> -                             if (so->so_type != SOCK_DGRAM &&
> -                                 sin->sin_addr.s_addr !=
> -                                 ia->ia_addr.sin_addr.s_addr)
> -                                     return (EADDRNOTAVAIL);
> +                             if (ia == NULL &&
> +                                 (so->so_type != SOCK_DGRAM ||
> +                                 !in_broadcast(sin->sin_addr, inp->inp_rtable
id)))
^^^^^
Code should fit in 80 columns.

> +                                             return (EADDRNOTAVAIL);
>                       }
>               }
>               if (lport) {
> Index: sys/netinet/ip_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_output.c,v
> retrieving revision 1.310
> diff -u -p -r1.310 ip_output.c
> --- sys/netinet/ip_output.c   2 Dec 2015 13:29:26 -0000       1.310
> +++ sys/netinet/ip_output.c   2 Dec 2015 15:17:27 -0000
> @@ -1387,9 +1387,8 @@ ip_setmoptions(int optname, struct ip_mo
>               sin.sin_family = AF_INET;
>               sin.sin_addr = addr;
>               ia = ifatoia(ifa_ifwithaddr(sintosa(&sin), rtableid));
> -             if (ia && in_hosteq(sin.sin_addr, ia->ia_addr.sin_addr))
> -                     ifp = ia->ia_ifp;
> -             if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
> +             if (ia == NULL || (ifp = ia->ia_ifp) == NULL ||

ia_ifp MUST not be NULL since you got it from the per-ifp list, so need
to check for NULL.

> +                 (ia->ia_ifp->if_flags & IFF_MULTICAST) == 0) {
>                       error = EADDRNOTAVAIL;
>                       break;
>               }

Reply via email to