Module Name: src Committed By: msaitoh Date: Fri Dec 21 08:58:08 UTC 2018
Modified Files: src/sbin/ifconfig: ether.c extern.h ifconfig.c src/sys/net: if.c if_ethersubr.c src/sys/sys: sockio.h Log Message: Add SIOCSETHERCAP. It's used to change ec_capenable. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sbin/ifconfig/ether.c cvs rdiff -u -r1.14 -r1.15 src/sbin/ifconfig/extern.h cvs rdiff -u -r1.237 -r1.238 src/sbin/ifconfig/ifconfig.c cvs rdiff -u -r1.442 -r1.443 src/sys/net/if.c cvs rdiff -u -r1.271 -r1.272 src/sys/net/if_ethersubr.c cvs rdiff -u -r1.35 -r1.36 src/sys/sys/sockio.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/ifconfig/ether.c diff -u src/sbin/ifconfig/ether.c:1.2 src/sbin/ifconfig/ether.c:1.3 --- src/sbin/ifconfig/ether.c:1.2 Thu Nov 1 13:43:23 2012 +++ src/sbin/ifconfig/ether.c Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $ */ +/* $NetBSD: ether.c,v 1.3 2018/12/21 08:58:08 msaitoh Exp $ */ /* * Copyright (c) 1983, 1993 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $"); +__RCSID("$NetBSD: ether.c,v 1.3 2018/12/21 08:58:08 msaitoh Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -40,6 +40,7 @@ __RCSID("$NetBSD: ether.c,v 1.2 2012/11/ #include <net/if.h> #include <net/if_ether.h> +#include <assert.h> #include <ctype.h> #include <err.h> #include <errno.h> @@ -55,11 +56,99 @@ __RCSID("$NetBSD: ether.c,v 1.2 2012/11/ static void ether_status(prop_dictionary_t, prop_dictionary_t); static void ether_constructor(void) __attribute__((constructor)); +static int setethercaps(prop_dictionary_t, prop_dictionary_t); static status_func_t status; +static cmdloop_branch_t branch; #define MAX_PRINT_LEN 55 +static const struct kwinst ethercapskw[] = { +#if 0 /* notyet */ + IFKW("vlan-hwfilter", ETHERCAP_VLAN_HWFILTER) +#endif + IFKW("eee", ETHERCAP_EEE) +}; + +struct pkw ethercaps = PKW_INITIALIZER(ðercaps, "ethercaps", setethercaps, + "ethercap", ethercapskw, __arraycount(ethercapskw), + &command_root.pb_parser); + +void +do_setethercaps(prop_dictionary_t env) +{ + struct eccapreq eccr; + prop_data_t d; + + d = (prop_data_t )prop_dictionary_get(env, "ethercaps"); + if (d == NULL) + return; + + assert(sizeof(eccr) == prop_data_size(d)); + + memcpy(&eccr, prop_data_data_nocopy(d), sizeof(eccr)); + if (direct_ioctl(env, SIOCSETHERCAP, &eccr) == -1) + err(EXIT_FAILURE, "SIOCSETHERCAP"); +} + +static int +getethercaps(prop_dictionary_t env, prop_dictionary_t oenv, + struct eccapreq *oeccr) +{ + bool rc; + struct eccapreq eccr; + const struct eccapreq *tmpeccr; + prop_data_t capdata; + + capdata = (prop_data_t)prop_dictionary_get(env, "ethercaps"); + + if (capdata != NULL) { + tmpeccr = prop_data_data_nocopy(capdata); + *oeccr = *tmpeccr; + return 0; + } + + (void)direct_ioctl(env, SIOCGETHERCAP, &eccr); + *oeccr = eccr; + + capdata = prop_data_create_data(&eccr, sizeof(eccr)); + + rc = prop_dictionary_set(oenv, "ethercaps", capdata); + + prop_object_release((prop_object_t)capdata); + + return rc ? 0 : -1; +} + +static int +setethercaps(prop_dictionary_t env, prop_dictionary_t oenv) +{ + int64_t ethercap; + bool rc; + prop_data_t capdata; + struct eccapreq eccr; + + rc = prop_dictionary_get_int64(env, "ethercap", ðercap); + assert(rc); + + if (getethercaps(env, oenv, &eccr) == -1) + return -1; + + if (ethercap < 0) { + ethercap = -ethercap; + eccr.eccr_capenable &= ~ethercap; + } else + eccr.eccr_capenable |= ethercap; + + if ((capdata = prop_data_create_data(&eccr, sizeof(eccr))) == NULL) + return -1; + + rc = prop_dictionary_set(oenv, "ethercaps", capdata); + prop_object_release((prop_object_t)capdata); + + return rc ? 0 : -1; +} + void ether_status(prop_dictionary_t env, prop_dictionary_t oenv) { @@ -94,6 +183,8 @@ static void ether_constructor(void) { + cmdloop_branch_init(&branch, ðercaps.pk_parser); + register_cmdloop_branch(&branch); status_func_init(&status, ether_status); register_status(&status); } Index: src/sbin/ifconfig/extern.h diff -u src/sbin/ifconfig/extern.h:1.14 src/sbin/ifconfig/extern.h:1.15 --- src/sbin/ifconfig/extern.h:1.14 Fri Aug 7 18:53:37 2009 +++ src/sbin/ifconfig/extern.h Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.14 2009/08/07 18:53:37 dyoung Exp $ */ +/* $NetBSD: extern.h,v 1.15 2018/12/21 08:58:08 msaitoh Exp $ */ /* * Copyright (c) 1983, 1993 @@ -87,6 +87,7 @@ int register_status(status_func_t *); int register_usage(usage_func_t *); int register_flag(int); bool get_flag(int); +void do_setethercaps(prop_dictionary_t); extern bool lflag, Nflag, vflag, zflag; Index: src/sbin/ifconfig/ifconfig.c diff -u src/sbin/ifconfig/ifconfig.c:1.237 src/sbin/ifconfig/ifconfig.c:1.238 --- src/sbin/ifconfig/ifconfig.c:1.237 Thu Nov 15 04:36:46 2018 +++ src/sbin/ifconfig/ifconfig.c Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.237 2018/11/15 04:36:46 ozaki-r Exp $ */ +/* $NetBSD: ifconfig.c,v 1.238 2018/12/21 08:58:08 msaitoh Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1983, 1993\ The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.237 2018/11/15 04:36:46 ozaki-r Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.238 2018/12/21 08:58:08 msaitoh Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -799,6 +799,7 @@ main(int argc, char **argv) do_setifpreference(env); do_setifcaps(env); + do_setethercaps(env); exit(EXIT_SUCCESS); } Index: src/sys/net/if.c diff -u src/sys/net/if.c:1.442 src/sys/net/if.c:1.443 --- src/sys/net/if.c:1.442 Wed Dec 12 01:46:47 2018 +++ src/sys/net/if.c Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.442 2018/12/12 01:46:47 rin Exp $ */ +/* $NetBSD: if.c,v 1.443 2018/12/21 08:58:08 msaitoh Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. @@ -90,7 +90,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.442 2018/12/12 01:46:47 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.443 2018/12/21 08:58:08 msaitoh Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -3230,6 +3230,7 @@ doifioctl(struct socket *so, u_long cmd, case SIOCSLIFPHYADDR: case SIOCADDMULTI: case SIOCDELMULTI: + case SIOCSETHERCAP: case SIOCSIFMEDIA: case SIOCSDRVSPEC: case SIOCG80211: Index: src/sys/net/if_ethersubr.c diff -u src/sys/net/if_ethersubr.c:1.271 src/sys/net/if_ethersubr.c:1.272 --- src/sys/net/if_ethersubr.c:1.271 Thu Nov 15 10:23:56 2018 +++ src/sys/net/if_ethersubr.c Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ethersubr.c,v 1.271 2018/11/15 10:23:56 maxv Exp $ */ +/* $NetBSD: if_ethersubr.c,v 1.272 2018/12/21 08:58:08 msaitoh Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.271 2018/11/15 10:23:56 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.272 2018/12/21 08:58:08 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1372,6 +1372,48 @@ ether_set_ifflags_cb(struct ethercom *ec ec->ec_ifflags_cb = cb; } +static int +ether_ioctl_reinit(struct ethercom *ec) +{ + struct ifnet *ifp = &ec->ec_if; + int error; + + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + /* + * If interface is marked down and it is running, + * then stop and disable it. + */ + (*ifp->if_stop)(ifp, 1); + break; + case IFF_UP: + /* + * If interface is marked up and it is stopped, then + * start it. + */ + return (*ifp->if_init)(ifp); + case IFF_UP | IFF_RUNNING: + error = 0; + if (ec->ec_ifflags_cb != NULL) { + error = (*ec->ec_ifflags_cb)(ec); + if (error == ENETRESET) { + /* + * Reset the interface to pick up + * changes in any other flags that + * affect the hardware state. + */ + return (*ifp->if_init)(ifp); + } + } else + error = (*ifp->if_init)(ifp); + return error; + case 0: + break; + } + + return 0; +} + /* * Common ioctls for Ethernet interfaces. Note, we must be * called at splnet(). @@ -1379,7 +1421,7 @@ ether_set_ifflags_cb(struct ethercom *ec int ether_ioctl(struct ifnet *ifp, u_long cmd, void *data) { - struct ethercom *ec = (void *) ifp; + struct ethercom *ec = (void *)ifp; struct eccapreq *eccr; struct ifreq *ifr = (struct ifreq *)data; struct if_laddrreq *iflr = data; @@ -1428,44 +1470,25 @@ ether_ioctl(struct ifnet *ifp, u_long cm case SIOCSIFFLAGS: if ((error = ifioctl_common(ifp, cmd, data)) != 0) return error; - switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { - case IFF_RUNNING: - /* - * If interface is marked down and it is running, - * then stop and disable it. - */ - (*ifp->if_stop)(ifp, 1); - break; - case IFF_UP: - /* - * If interface is marked up and it is stopped, then - * start it. - */ - return (*ifp->if_init)(ifp); - case IFF_UP | IFF_RUNNING: - error = 0; - if (ec->ec_ifflags_cb != NULL) { - error = (*ec->ec_ifflags_cb)(ec); - if (error == ENETRESET) { - /* - * Reset the interface to pick up - * changes in any other flags that - * affect the hardware state. - */ - return (*ifp->if_init)(ifp); - } - } else - error = (*ifp->if_init)(ifp); - return error; - case 0: - break; - } - return 0; + return ether_ioctl_reinit(ec); case SIOCGETHERCAP: eccr = (struct eccapreq *)data; eccr->eccr_capabilities = ec->ec_capabilities; eccr->eccr_capenable = ec->ec_capenable; return 0; + case SIOCSETHERCAP: + eccr = (struct eccapreq *)data; + if ((eccr->eccr_capenable & ~ec->ec_capabilities) != 0) + return EINVAL; + if (eccr->eccr_capenable == ec->ec_capenable) + return 0; +#if 0 /* notyet */ + ec->ec_capenable = (ec->ec_capenable & ETHERCAP_CANTCHANGE) + | (eccr->eccr_capenable & ~ETHERCAP_CANTCHANGE); +#else + ec->ec_capenable = eccr->eccr_capenable; +#endif + return ether_ioctl_reinit(ec); case SIOCADDMULTI: return ether_addmulti(ifreq_getaddr(cmd, ifr), ec); case SIOCDELMULTI: Index: src/sys/sys/sockio.h diff -u src/sys/sys/sockio.h:1.35 src/sys/sys/sockio.h:1.36 --- src/sys/sys/sockio.h:1.35 Wed Aug 1 23:35:32 2018 +++ src/sys/sys/sockio.h Fri Dec 21 08:58:08 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sockio.h,v 1.35 2018/08/01 23:35:32 rjs Exp $ */ +/* $NetBSD: sockio.h,v 1.36 2018/12/21 08:58:08 msaitoh Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1993, 1994 @@ -141,6 +141,7 @@ #define SIOCGETHERCAP _IOWR('i', 139, struct eccapreq) /* get ethercap */ #define SIOCGIFINDEX _IOWR('i', 140, struct ifreq) /* get ifnet index */ +#define SIOCSETHERCAP _IOW('i', 141, struct eccapreq) /* set ethercap */ #define SIOCGUMBINFO _IOWR('i', 190, struct ifreq) /* get MBIM info */ #define SIOCSUMBPARAM _IOW('i', 191, struct ifreq) /* set MBIM param */