Store the IP address of the corresponding ifa in the rt_gateway field
authormpi <mpi@openbsd.org>
Tue, 26 May 2015 12:19:51 +0000 (12:19 +0000)
committermpi <mpi@openbsd.org>
Tue, 26 May 2015 12:19:51 +0000 (12:19 +0000)
of RTF_CLONING and RTF_BROASCAST routes to not create MPATH conflicts
when IP address aliases are used.

This change makes it possible to have multiple RTF_CLONING routes with
the same priority.  Note that any of the existing RTF_CLONING route
might be used by the kernel to create a RTF_CLONED route which should
not be a problem with aliases since they are attached to the same ifp.

This unbreak address aliases since the kernel supports multiple connected
routes for a subnet.

Found the hardway by djm@, ok claudio@

sys/net/route.c
sys/netinet/in.c
sys/netinet6/in6.c
sys/netinet6/nd6_rtr.c

index d364fa9..dc51086 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: route.c,v 1.211 2015/05/26 12:02:11 mpi Exp $ */
+/*     $OpenBSD: route.c,v 1.212 2015/05/26 12:19:51 mpi Exp $ */
 /*     $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $      */
 
 /*
@@ -729,6 +729,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
        struct ifaddr           *ifa;
        struct sockaddr         *ndst;
        struct sockaddr_rtlabel *sa_rl, sa_rl2;
+       struct sockaddr_dl       sa_dl = { sizeof(sa_dl), AF_LINK };
        int                      dlen, error;
 #ifdef MPLS
        struct sockaddr_mpls    *sa_mpls;
@@ -827,9 +828,10 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
                        info->rti_ifa = NULL;
                        info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
                }
+
                info->rti_flags = rt->rt_flags & ~(RTF_CLONING | RTF_STATIC);
                info->rti_flags |= RTF_CLONED;
-               info->rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+               info->rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
                info->rti_flags |= RTF_HOST;
                info->rti_info[RTAX_LABEL] =
                    rtlabel_id2sa(rt->rt_labelid, &sa_rl2);
@@ -1134,7 +1136,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst)
        info.rti_ifa = ifa;
        info.rti_flags = flags | RTF_MPATH;
        info.rti_info[RTAX_DST] = dst;
-       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+       if (flags & RTF_LLINFO)
+               info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+       else
+               info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
        info.rti_info[RTAX_LABEL] =
            rtlabel_id2sa(ifa->ifa_ifp->if_rtlabelid, &sa_rl);
 
@@ -1229,7 +1234,10 @@ rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst)
        info.rti_ifa = ifa;
        info.rti_flags = flags;
        info.rti_info[RTAX_DST] = dst;
-       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+       if (flags & RTF_LLINFO)
+               info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+       else
+               info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
        info.rti_info[RTAX_LABEL] =
            rtlabel_id2sa(ifa->ifa_ifp->if_rtlabelid, &sa_rl);
 
index 91636b9..c741c80 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in.c,v 1.116 2015/05/15 12:00:57 claudio Exp $        */
+/*     $OpenBSD: in.c,v 1.117 2015/05/26 12:19:51 mpi Exp $    */
 /*     $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
 
 /*
@@ -737,8 +737,8 @@ in_insert_prefix(struct in_ifaddr *ia)
                return (error);
 
        if (ia->ia_broadaddr.sin_addr.s_addr != 0)
-               error = rt_ifa_add(ifa, RTF_UP | RTF_HOST |
-                   RTF_LLINFO | RTF_BROADCAST, ifa->ifa_broadaddr);
+               error = rt_ifa_add(ifa, RTF_UP | RTF_HOST | RTF_BROADCAST,
+                   ifa->ifa_broadaddr);
 
        if (!error)
                ia->ia_flags |= IFA_ROUTE;
@@ -754,8 +754,7 @@ in_remove_prefix(struct in_ifaddr *ia)
        rt_ifa_del(ifa, 0, ifa->ifa_addr);
 
        if (ia->ia_broadaddr.sin_addr.s_addr != 0)
-               rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO | RTF_BROADCAST,
-                   ifa->ifa_broadaddr);
+               rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST, ifa->ifa_broadaddr);
 
        ia->ia_flags &= ~IFA_ROUTE;
 }
index 9514764..d2c9737 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6.c,v 1.157 2015/05/15 12:00:57 claudio Exp $       */
+/*     $OpenBSD: in6.c,v 1.158 2015/05/26 12:19:52 mpi Exp $   */
 /*     $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $   */
 
 /*
@@ -828,10 +828,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
 
                /* join solicited multicast addr for new host id */
                struct sockaddr_in6 llsol;
-               struct sockaddr_dl sa_dl = { sizeof(sa_dl), AF_LINK };
-
-               sa_dl.sdl_type = ifp->if_type;
-               sa_dl.sdl_index = ifp->if_index;
 
                bzero(&llsol, sizeof(llsol));
                llsol.sin6_family = AF_INET6;
@@ -892,7 +888,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
 
                        bzero(&info, sizeof(info));
                        info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
-                       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+                       info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
                        info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
                        info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
                        /* XXX: we need RTF_CLONING to fake nd6_rtrequest */
@@ -961,7 +957,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
 
                        bzero(&info, sizeof(info));
                        info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
-                       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+                       info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
                        info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
                        info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
                        info.rti_flags = RTF_UP | RTF_CLONING;
index 50797c5..deb7ff8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6_rtr.c,v 1.103 2015/05/15 12:00:57 claudio Exp $   */
+/*     $OpenBSD: nd6_rtr.c,v 1.104 2015/05/26 12:19:52 mpi Exp $       */
 /*     $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $        */
 
 /*
@@ -1739,7 +1739,7 @@ nd6_prefix_onlink(struct nd_prefix *pr)
        bzero(&info, sizeof(info));
        info.rti_flags = rtflags;
        info.rti_info[RTAX_DST] = sin6tosa(&pr->ndpr_prefix);
-       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl;
+       info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
        info.rti_info[RTAX_NETMASK] = sin6tosa(&mask6);
 
        error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, ifp->if_rdomain);