From d62081b6dd05a67ee176092f85ee96e83eb74a19 Mon Sep 17 00:00:00 2001 From: claudio Date: Sat, 10 Feb 2018 05:32:21 +0000 Subject: [PATCH] Similar to the IPv6 case create 127.0.0.1/8 on lo(4) interfaces which act 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 | 7 ++++-- sys/net/if_loop.c | 15 +++++++++++- sys/netinet/in.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 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 **); -- 2.20.1