Module Name: src Committed By: roy Date: Thu Sep 1 19:04:30 UTC 2016
Modified Files: src/sys/net: rtsock.c Log Message: Split out sysctl_iflist into sysctl_iflist_if and sysctl_iflist_addr. Setup a command and function pointer in one case statement instead of having a seconary case statement within a loop. This makes the code much easier to follow, and possibly to add more compat in the future. Don't panic when running an old binary without compat support. To generate a diff of this commit: cvs rdiff -u -r1.194 -r1.195 src/sys/net/rtsock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.194 src/sys/net/rtsock.c:1.195 --- src/sys/net/rtsock.c:1.194 Mon Aug 1 03:15:30 2016 +++ src/sys/net/rtsock.c Thu Sep 1 19:04:30 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.194 2016/08/01 03:15:30 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.195 2016/09/01 19:04:30 roy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.194 2016/08/01 03:15:30 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.195 2016/09/01 19:04:30 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1508,16 +1508,81 @@ sysctl_dumpentry(struct rtentry *rt, voi } static int +sysctl_iflist_if(struct ifnet *ifp, struct rt_walkarg *w, + struct rt_addrinfo *info, size_t len) +{ + struct if_xmsghdr *ifm; + int error; + + ifm = (struct if_xmsghdr *)w->w_tmem; + ifm->ifm_index = ifp->if_index; + ifm->ifm_flags = ifp->if_flags; + ifm->ifm_data = ifp->if_data; + ifm->ifm_addrs = info->rti_addrs; + if ((error = copyout(ifm, w->w_where, len)) == 0) + w->w_where = (char *)w->w_where + len; + return error; +} + +static int +sysctl_iflist_addr(struct rt_walkarg *w, struct ifaddr *ifa, + struct rt_addrinfo *info) +{ + int len, error; + + if ((error = rt_msg2(RTM_NEWADDR, info, 0, w, &len))) + return error; + if (w->w_where && w->w_tmem && w->w_needed <= 0) { + struct ifa_xmsghdr *ifam; + + ifam = (struct ifa_xmsghdr *)w->w_tmem; + ifam->ifam_index = ifa->ifa_ifp->if_index; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_addrs = info->rti_addrs; + if ((error = copyout(w->w_tmem, w->w_where, len)) == 0) + w->w_where = (char *)w->w_where + len; + } + return error; +} + +static int sysctl_iflist(int af, struct rt_walkarg *w, int type) { struct ifnet *ifp; struct ifaddr *ifa; struct rt_addrinfo info; - int len, error = 0; + int cmd, len, error = 0; + int (*iflist_if)(struct ifnet *, struct rt_walkarg *, + struct rt_addrinfo *, size_t); int s; struct psref psref; int bound = curlwp_bind(); + switch (type) { + case NET_RT_IFLIST: + cmd = RTM_IFINFO; + iflist_if = sysctl_iflist_if; + break; +#ifdef COMPAT_14 + case NET_RT_OOIFLIST: + cmd = RTM_OOIFINFO; + iflist_if = compat_14_iflist; + break; +#endif +#ifdef COMPAT_50 + case NET_RT_OIFLIST: + cmd = RTM_OIFINFO; + iflist_if = compat_50_iflist; + break; +#endif + default: +#ifdef DIAGNOSTIC + printf("sysctl_iflist\n"); +#endif + return EINVAL; + } + memset(&info, 0, sizeof(info)); s = pserialize_read_enter(); @@ -1531,60 +1596,12 @@ sysctl_iflist(int af, struct rt_walkarg pserialize_read_exit(s); info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; - switch (type) { - case NET_RT_IFLIST: - error = rt_msg2(RTM_IFINFO, &info, NULL, w, &len); - break; -#ifdef COMPAT_14 - case NET_RT_OOIFLIST: - error = rt_msg2(RTM_OOIFINFO, &info, NULL, w, &len); - break; -#endif -#ifdef COMPAT_50 - case NET_RT_OIFLIST: - error = rt_msg2(RTM_OIFINFO, &info, NULL, w, &len); - break; -#endif - default: - panic("sysctl_iflist(1)"); - } - if (error) + if ((error = rt_msg2(cmd, &info, NULL, w, &len)) != 0) goto release_exit; info.rti_info[RTAX_IFP] = NULL; if (w->w_where && w->w_tmem && w->w_needed <= 0) { - switch (type) { - case NET_RT_IFLIST: { - struct if_xmsghdr *ifm; - - ifm = (struct if_xmsghdr *)w->w_tmem; - ifm->ifm_index = ifp->if_index; - ifm->ifm_flags = ifp->if_flags; - ifm->ifm_data = ifp->if_data; - ifm->ifm_addrs = info.rti_addrs; - error = copyout(ifm, w->w_where, len); - if (error) - goto release_exit; - w->w_where = (char *)w->w_where + len; - break; - } - -#ifdef COMPAT_14 - case NET_RT_OOIFLIST: - error = compat_14_iflist(ifp, w, &info, len); - if (error) - goto release_exit; - break; -#endif -#ifdef COMPAT_50 - case NET_RT_OIFLIST: - error = compat_50_iflist(ifp, w, &info, len); - if (error) - goto release_exit; - break; -#endif - default: - panic("sysctl_iflist(2)"); - } + if ((error = iflist_if(ifp, w, &info, len)) != 0) + goto release_exit; } IFADDR_READER_FOREACH(ifa, ifp) { if (af && af != ifa->ifa_addr->sa_family) @@ -1592,21 +1609,8 @@ sysctl_iflist(int af, struct rt_walkarg info.rti_info[RTAX_IFA] = ifa->ifa_addr; info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; - if ((error = rt_msg2(RTM_NEWADDR, &info, 0, w, &len))) + if ((error = sysctl_iflist_addr(w, ifa, &info)) != 0) goto release_exit; - if (w->w_where && w->w_tmem && w->w_needed <= 0) { - struct ifa_xmsghdr *ifam; - - ifam = (struct ifa_xmsghdr *)w->w_tmem; - ifam->ifam_index = ifa->ifa_ifp->if_index; - ifam->ifam_flags = ifa->ifa_flags; - ifam->ifam_metric = ifa->ifa_metric; - ifam->ifam_addrs = info.rti_addrs; - error = copyout(w->w_tmem, w->w_where, len); - if (error) - goto release_exit; - w->w_where = (char *)w->w_where + len; - } } info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] = info.rti_info[RTAX_BRD] = NULL;