From 0d357b6bac214552fce7765dd696c919521d0e15 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 23 Oct 2015 10:22:29 +0000 Subject: [PATCH] Introduce a new sysctl NET_RT_IFNAMES that returns only ifnames to ifindex mappings. This will be used by if_nameindex(3), if_nametoindex(3) and if_indextoname(3) soon to fix the issues in pledge because of inet6 link local addressing. OK mpi@ benno@ deraadt@ The libc version will follow soon so better start updating your kernels --- sys/kern/kern_pledge.c | 6 +++++- sys/net/if.h | 8 +++++++- sys/net/rtsock.c | 37 +++++++++++++++++++++++++++++++++++-- sys/sys/socket.h | 6 ++++-- sys/sys/sysctl.h | 3 +-- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index a5ed8cc26cc..561409505be 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.66 2015/10/23 01:10:01 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.67 2015/10/23 10:22:29 claudio Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -938,6 +938,10 @@ pledge_sysctl_check(struct proc *p, int miblen, int *mib, void *new) if (miblen == 2 && /* gethostname() */ mib[0] == CTL_KERN && mib[1] == KERN_HOSTNAME) return (0); + if (miblen == 6 && /* if_nameindex() */ + mib[0] == CTL_NET && mib[1] == PF_ROUTE && + mib[2] == 0 && mib[3] == 0 && mib[4] == NET_RT_IFNAMES) + return (0); if (miblen == 2 && /* uname() */ mib[0] == CTL_KERN && mib[1] == KERN_OSTYPE) return (0); diff --git a/sys/net/if.h b/sys/net/if.h index 82dd41cc06e..760892939c1 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.170 2015/10/23 01:19:04 dlg Exp $ */ +/* $OpenBSD: if.h,v 1.171 2015/10/23 10:22:29 claudio Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -304,6 +304,12 @@ struct if_announcemsghdr { #define IFAN_ARRIVAL 0 /* interface arrival */ #define IFAN_DEPARTURE 1 /* interface departure */ +/* message format used to pass interface name to index mappings */ +struct if_nameindex_msg { + unsigned int if_index; + char if_name[IFNAMSIZ]; +}; + /* * interface groups */ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 4f7d6261fac..12d963e4dec 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.173 2015/10/22 17:19:38 mpi Exp $ */ +/* $OpenBSD: rtsock.c,v 1.174 2015/10/23 10:22:29 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -102,6 +102,9 @@ int rt_msg2(int, int, struct rt_addrinfo *, caddr_t, struct walkarg *); void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); +int sysctl_iflist(int, struct walkarg *); +int sysctl_ifnames(struct walkarg *); + struct routecb { struct rawcb rcb; struct timeout timeout; @@ -1320,6 +1323,34 @@ sysctl_iflist(int af, struct walkarg *w) return (0); } +int +sysctl_ifnames(struct walkarg *w) +{ + struct if_nameindex_msg ifn; + struct ifnet *ifp; + int error = 0; + + /* XXX ignore tableid for now */ + TAILQ_FOREACH(ifp, &ifnet, if_list) { + if (w->w_arg && w->w_arg != ifp->if_index) + continue; + w->w_needed += sizeof(ifn); + if (w->w_where && w->w_needed <= 0) { + + memset(&ifn, 0, sizeof(ifn)); + ifn.if_index = ifp->if_index; + strlcpy(ifn.if_name, ifp->if_xname, + sizeof(ifn.if_name)); + error = copyout(&ifn, w->w_where, sizeof(ifn)); + if (error) + return (error); + w->w_where += sizeof(ifn); + } + } + + return (0); +} + int sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, size_t newlen) @@ -1351,7 +1382,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, s = splsoftnet(); switch (w.w_op) { - case NET_RT_DUMP: case NET_RT_FLAGS: for (i = 1; i <= AF_MAX; i++) { @@ -1387,6 +1417,9 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, &tableinfo, sizeof(tableinfo)); splx(s); return (error); + case NET_RT_IFNAMES: + error = sysctl_ifnames(&w); + break; } splx(s); free(w.w_tmem, M_RTABLE, 0); diff --git a/sys/sys/socket.h b/sys/sys/socket.h index a0b01ba7c8a..de9502c52db 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socket.h,v 1.89 2015/10/20 18:04:03 deraadt Exp $ */ +/* $OpenBSD: socket.h,v 1.90 2015/10/23 10:22:30 claudio Exp $ */ /* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */ /* @@ -350,7 +350,8 @@ struct sockpeercred { #define NET_RT_IFLIST 3 /* survey interface list */ #define NET_RT_STATS 4 /* routing table statistics */ #define NET_RT_TABLE 5 -#define NET_RT_MAXID 6 +#define NET_RT_IFNAMES 6 +#define NET_RT_MAXID 7 #define CTL_NET_RT_NAMES { \ { 0, 0 }, \ @@ -359,6 +360,7 @@ struct sockpeercred { { "iflist", CTLTYPE_STRUCT }, \ { "stats", CTLTYPE_STRUCT }, \ { "table", CTLTYPE_STRUCT }, \ + { "ifnames", CTLTYPE_STRUCT }, \ } /* diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 33e0222cbff..8a6d6047fcb 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.156 2015/07/18 15:51:17 mpi Exp $ */ +/* $OpenBSD: sysctl.h,v 1.157 2015/10/23 10:22:30 claudio Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -945,7 +945,6 @@ int sysctl_doproc(int *, u_int, char *, size_t *); struct rtentry; struct walkarg; int sysctl_dumpentry(struct rtentry *, void *, unsigned int); -int sysctl_iflist(int, struct walkarg *); int sysctl_rtable(int *, u_int, void *, size_t *, void *, size_t); int sysctl_clockrate(char *, size_t *, void *); int sysctl_vnode(char *, size_t *, struct proc *); -- 2.20.1