Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add SIOCSETHERCAP. It's used to change ec_capenable.



details:   https://anonhg.NetBSD.org/src/rev/4320ade33a37
branches:  trunk
changeset: 446827:4320ade33a37
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Fri Dec 21 08:58:08 2018 +0000

description:
Add SIOCSETHERCAP. It's used to change ec_capenable.

diffstat:

 sbin/ifconfig/ether.c    |  95 ++++++++++++++++++++++++++++++++++++++++++++++-
 sbin/ifconfig/extern.h   |   3 +-
 sbin/ifconfig/ifconfig.c |   5 +-
 sys/net/if.c             |   5 +-
 sys/net/if_ethersubr.c   |  95 +++++++++++++++++++++++++++++------------------
 sys/sys/sockio.h         |   3 +-
 6 files changed, 162 insertions(+), 44 deletions(-)

diffs (truncated from 356 to 300 lines):

diff -r 0ccdf724be81 -r 4320ade33a37 sbin/ifconfig/ether.c
--- a/sbin/ifconfig/ether.c     Fri Dec 21 08:29:22 2018 +0000
+++ b/sbin/ifconfig/ether.c     Fri Dec 21 08:58:08 2018 +0000
@@ -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 @@
 #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 @@
 
 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(&ethercaps, "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", &ethercap);
+       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 @@
 ether_constructor(void)
 {
 
+       cmdloop_branch_init(&branch, &ethercaps.pk_parser);
+       register_cmdloop_branch(&branch);
        status_func_init(&status, ether_status);
        register_status(&status);
 }
diff -r 0ccdf724be81 -r 4320ade33a37 sbin/ifconfig/extern.h
--- a/sbin/ifconfig/extern.h    Fri Dec 21 08:29:22 2018 +0000
+++ b/sbin/ifconfig/extern.h    Fri Dec 21 08:58:08 2018 +0000
@@ -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_usage(usage_func_t *);
 int register_flag(int);
 bool get_flag(int);
+void do_setethercaps(prop_dictionary_t);
 
 extern bool lflag, Nflag, vflag, zflag;
 
diff -r 0ccdf724be81 -r 4320ade33a37 sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c  Fri Dec 21 08:29:22 2018 +0000
+++ b/sbin/ifconfig/ifconfig.c  Fri Dec 21 08:58:08 2018 +0000
@@ -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 @@
 
        do_setifpreference(env);
        do_setifcaps(env);
+       do_setethercaps(env);
 
        exit(EXIT_SUCCESS);
 }
diff -r 0ccdf724be81 -r 4320ade33a37 sys/net/if.c
--- a/sys/net/if.c      Fri Dec 21 08:29:22 2018 +0000
+++ b/sys/net/if.c      Fri Dec 21 08:58:08 2018 +0000
@@ -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 @@
        case SIOCSLIFPHYADDR:
        case SIOCADDMULTI:
        case SIOCDELMULTI:
+       case SIOCSETHERCAP:
        case SIOCSIFMEDIA:
        case SIOCSDRVSPEC:
        case SIOCG80211:
diff -r 0ccdf724be81 -r 4320ade33a37 sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c    Fri Dec 21 08:29:22 2018 +0000
+++ b/sys/net/if_ethersubr.c    Fri Dec 21 08:58:08 2018 +0000
@@ -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 @@
        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 @@
 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 @@
        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;



Home | Main Index | Thread Index | Old Index