Similar to the IPv6 case create 127.0.0.1/8 on lo(4) interfaces which act
authorclaudio <claudio@openbsd.org>
Sat, 10 Feb 2018 05:32:21 +0000 (05:32 +0000)
committerclaudio <claudio@openbsd.org>
Sat, 10 Feb 2018 05:32:21 +0000 (05:32 +0000)
as loopback interfaces for each rdomain (including lo0). This is done when
the interface is brought up. This is now also done by default (either on
attach of lo0 or when creating the rdomain).
OK mpi@

sys/net/if.c
sys/net/if_loop.c
sys/netinet/in.c
sys/netinet/in.h

index 1557cae..e450dec 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.541 2018/02/09 09:35:03 dlg Exp $    */
+/*     $OpenBSD: if.c,v 1.542 2018/02/10 05:32:21 claudio Exp $        */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -1550,8 +1550,10 @@ if_up(struct ifnet *ifp)
 
 #ifdef INET6
        /* Userland expects the kernel to set ::1 on default lo(4). */
-       if (ifp->if_index == rtable_loindex(ifp->if_rdomain))
+       if (ifp->if_index == rtable_loindex(ifp->if_rdomain)) {
                in6_ifattach(ifp);
+               in_up_loopback(ifp);
+       }
 #endif
 
        if_linkstate(ifp);
@@ -1744,6 +1746,7 @@ if_setrdomain(struct ifnet *ifp, int rdomain)
                }
 
                loifp->if_rdomain = rdomain;
+               if_up(loifp);
        }
 
        /* make sure that the routing table is a real rdomain */
index 5ff594e..9cc46c6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_loop.c,v 1.85 2018/01/09 15:24:24 bluhm Exp $      */
+/*     $OpenBSD: if_loop.c,v 1.86 2018/02/10 05:32:21 claudio Exp $    */
 /*     $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $     */
 
 /*
 
 int    loioctl(struct ifnet *, u_long, caddr_t);
 void   loopattach(int);
+void   loop_delayed_create(void *);
 void   lortrequest(struct ifnet *, int, struct rtentry *);
 int    loinput(struct ifnet *, struct mbuf *, void *);
 int    looutput(struct ifnet *,
@@ -162,9 +163,19 @@ loopattach(int n)
        if_clone_attach(&loop_cloner);
 }
 
+void
+loop_delayed_create(void *arg)
+{
+       struct ifnet *ifp = arg;
+       NET_LOCK();
+       if_up(ifp);
+       NET_UNLOCK();
+}
+
 int
 loop_clone_create(struct if_clone *ifc, int unit)
 {
+       static struct task lot;
        struct ifnet *ifp;
 
        ifp = malloc(sizeof(*ifp), M_DEVBUF, M_WAITOK|M_ZERO);
@@ -182,6 +193,8 @@ loop_clone_create(struct if_clone *ifc, int unit)
                if_attachhead(ifp);
                if_addgroup(ifp, ifc->ifc_name);
                rtable_l2set(0, 0, ifp->if_index);
+               task_set(&lot, loop_delayed_create, ifp);
+               task_add(systq, &lot);
        } else
                if_attach(ifp);
        if_alloc_sadl(ifp);
index 5681667..3651c12 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in.c,v 1.144 2017/11/04 13:11:54 mpi Exp $    */
+/*     $OpenBSD: in.c,v 1.145 2018/02/10 05:32:21 claudio Exp $        */
 /*     $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
 
 /*
@@ -609,6 +609,62 @@ in_broadcast(struct in_addr in, u_int rtableid)
 #undef ia
 }
 
+int
+in_up_loopback(struct ifnet *ifp)
+{
+       struct in_ifaddr *ia;
+       struct rt_addrinfo info;
+       int error;
+
+       if ((ifp->if_flags & IFF_LOOPBACK) == 0)
+               return (0);
+
+       /* configure 127.0.0.1 on the loopback interface */
+       ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
+       ia->ia_addr.sin_family = AF_INET;
+       ia->ia_addr.sin_len = sizeof(ia->ia_addr);
+       ia->ia_addr.sin_addr.s_addr = INADDR_LOOPBACK;
+       ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+       ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
+       ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
+       ia->ia_netmask = IN_CLASSA_NET;
+       ia->ia_sockmask.sin_len = 8;
+       ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
+       ia->ia_ifp = ifp;
+
+       if (ifaof_ifpforaddr(ia->ia_ifa.ifa_addr, ifp) != NULL) {
+               free(ia, M_IFADDR, sizeof *ia);
+               return (0);
+       }
+
+       /*
+        * Add the address to the local list and the global tree.  If an
+        * error occured, cleanup.
+        */
+       ifa_add(ifp, &ia->ia_ifa);
+       error = rt_ifa_addlocal(&ia->ia_ifa);
+       if (error)
+               goto out;
+
+       ia->ia_net = ia->ia_addr.sin_addr.s_addr & ia->ia_netmask;
+       in_socktrim(&ia->ia_sockmask);
+
+       /* Now insert a reject route for 127.0.0.0/8 */
+       bzero((caddr_t)&info, sizeof(info));
+       info.rti_flags = RTF_GATEWAY | RTF_REJECT | RTF_STATIC;
+       info.rti_ifa = &ia->ia_ifa;
+       info.rti_info[RTAX_DST] = ia->ia_ifa.ifa_addr;
+       info.rti_info[RTAX_NETMASK] = ia->ia_ifa.ifa_netmask;
+       info.rti_info[RTAX_GATEWAY] = ia->ia_ifa.ifa_addr;
+
+       error = rtrequest(RTM_ADD, &info, 0, NULL, ifp->if_rdomain);
+
+out:
+       if (error)
+               in_purgeaddr(&ia->ia_ifa);
+       return (error);
+}
+
 /*
  * Add an address to the list of IP multicast addresses for a given interface.
  */
index fc8a7b6..02233bb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in.h,v 1.127 2017/11/20 10:35:24 mpi Exp $    */
+/*     $OpenBSD: in.h,v 1.128 2018/02/10 05:32:21 claudio Exp $        */
 /*     $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
 
 /*
@@ -811,6 +811,7 @@ int    in_cksum(struct mbuf *, int);
 int       in4_cksum(struct mbuf *, u_int8_t, int, int);
 void      in_proto_cksum_out(struct mbuf *, struct ifnet *);
 void      in_ifdetach(struct ifnet *);
+int       in_up_loopback(struct ifnet *);
 int       in_mask2len(struct in_addr *);
 void      in_len2mask(struct in_addr *, int);
 int       in_nam2sin(const struct mbuf *, struct sockaddr_in **);