diff options
-rw-r--r-- | sys/net/if.c | 7 | ||||
-rw-r--r-- | sys/net/if_loop.c | 15 | ||||
-rw-r--r-- | sys/netinet/in.c | 58 | ||||
-rw-r--r-- | sys/netinet/in.h | 3 |
4 files changed, 78 insertions, 5 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 1557cae6cca..e450decf5ed 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -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 */ diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 5ff594ef091..9cc46c6b700 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -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 $ */ /* @@ -142,6 +142,7 @@ 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); diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 5681667a688..3651c120af8 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -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. */ diff --git a/sys/netinet/in.h b/sys/netinet/in.h index fc8a7b61044..02233bb3d08 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -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 **); |