On 12/03/15 10:21, Vincent Gross wrote:
> On 12/02/15 20:06, Martin Pieuchot wrote:
>> 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.
> 
> Nits applied.
> 
> Anyone else ?

bluhm@ spotted one case where in_broadcast was needed.

ok ?

Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.418
diff -u -p -r1.418 if.c
--- sys/net/if.c        3 Dec 2015 12:22:51 -0000       1.418
+++ sys/net/if.c        3 Dec 2015 13:48:58 -0000
@@ -1220,13 +1220,6 @@ ifa_ifwithaddr(struct sockaddr *addr, u_
 
                        if (equal(addr, ifa->ifa_addr))
                                return (ifa);
-
-                       /* IPv6 doesn't have broadcast */
-                       if ((ifp->if_flags & IFF_BROADCAST) &&
-                           ifa->ifa_broadaddr &&
-                           ifa->ifa_broadaddr->sa_len != 0 &&
-                           equal(ifa->ifa_broadaddr, addr))
-                               return (ifa);
                }
        }
        return (NULL);
Index: sys/net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.283
diff -u -p -r1.283 route.c
--- sys/net/route.c     2 Dec 2015 16:49:58 -0000       1.283
+++ sys/net/route.c     3 Dec 2015 13:49:00 -0000
@@ -539,7 +539,9 @@ rtredirect(struct sockaddr *dst, struct 
         bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
        if (rt != NULL && (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
                error = EINVAL;
-       else if (ifa_ifwithaddr(gateway, rdomain) != NULL)
+       else if (ifa_ifwithaddr(gateway, rdomain) != NULL ||
+           (gateway->sa_family = AF_INET &&
+           in_broadcast(satosin(gateway)->sin_addr, rdomain)))
                error = EHOSTUNREACH;
        if (error)
                goto done;
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.191
diff -u -p -r1.191 in_pcb.c
--- sys/netinet/in_pcb.c        3 Dec 2015 09:49:15 -0000       1.191
+++ sys/netinet/in_pcb.c        3 Dec 2015 13:49:00 -0000
@@ -332,14 +332,13 @@ 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_rtableid)))
+                                               return (EADDRNOTAVAIL);
                        }
                }
                if (lport) {
@@ -353,7 +352,8 @@ in_pcbbind(struct inpcb *inp, struct mbu
                                t = in_pcblookup(table, &zeroin_addr, 0,
                                    &sin->sin_addr, lport, INPLOOKUP_WILDCARD,
                                    inp->inp_rtableid);
-                               if (t && (so->so_euid != 
t->inp_socket->so_euid))
+                               if (t &&
+                                   (so->so_euid != t->inp_socket->so_euid))
                                        return (EADDRINUSE);
                        }
                        t = in_pcblookup(table, &zeroin_addr, 0,
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.311
diff -u -p -r1.311 ip_output.c
--- sys/netinet/ip_output.c     2 Dec 2015 20:50:20 -0000       1.311
+++ sys/netinet/ip_output.c     3 Dec 2015 13:49:01 -0000
@@ -1368,13 +1368,12 @@ 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 ||
+                   (ia->ia_ifp->if_flags & IFF_MULTICAST) == 0) {
                        error = EADDRNOTAVAIL;
                        break;
                }
-               imo->imo_ifidx = ifp->if_index;
+               imo->imo_ifidx = ia->ia_ifp->if_index;
                break;
 
        case IP_MULTICAST_TTL:
@@ -1542,12 +1541,11 @@ ip_setmoptions(int optname, struct ip_mo
                        sin.sin_family = AF_INET;
                        sin.sin_addr = mreq->imr_interface;
                        ia = ifatoia(ifa_ifwithaddr(sintosa(&sin), rtableid));
-                       if (ia && in_hosteq(sin.sin_addr, ia->ia_addr.sin_addr))
-                               ifp = ia->ia_ifp;
-                       else {
+                       if (ia == NULL) {
                                error = EADDRNOTAVAIL;
                                break;
                        }
+                       ifp = ia->ia_ifp;
                }
                /*
                 * Find the membership in the membership array.
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.84
diff -u -p -r1.84 raw_ip.c
--- sys/netinet/raw_ip.c        28 Jul 2015 12:22:07 -0000      1.84
+++ sys/netinet/raw_ip.c        3 Dec 2015 13:49:01 -0000
@@ -473,6 +473,7 @@ rip_usrreq(struct socket *so, int req, s
                if (!((so->so_options & SO_BINDANY) ||
                    addr->sin_addr.s_addr == INADDR_ANY ||
                    addr->sin_addr.s_addr == INADDR_BROADCAST ||
+                   in_broadcast(addr->sin_addr, inp->inp_rtableid) ||
                    ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid))) {
                        error = EADDRNOTAVAIL;
                        break;

Reply via email to