Source-Changes-HG archive

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

[src-draft/trunk]: src/sbin/ifconfig ifconfig(8): restore modular desing and ...



details:   https://anonhg.NetBSD.org/src-all/rev/3eef71b54e7e
branches:  trunk
changeset: 1027123:3eef71b54e7e
user:      Martin Husemann <martin%NetBSD.org@localhost>
date:      Tue Oct 26 19:39:56 2021 +0200

description:
ifconfig(8): restore modular desing and fix wlan cloning.

The previous hack to get wlan cloning working quick&dirty did violate
some of the design rules of ifconfig. Now we have main ifconfig.c
independent of ieee80211.c again and all additional functions are
dynamically registered.

Implement all cloning options for wlan devices. Avoid a collision
between the "request local unique bssid" flag and the "bssid" keyword
by renaming the former to "local-bssid". Adjust man page accordingly.

diffstat:

 sbin/ifconfig/extern.h    |    7 ++
 sbin/ifconfig/ieee80211.c |  123 +++++++++++++++++++++++++++++++++++++++++++--
 sbin/ifconfig/ifconfig.8  |    7 +-
 sbin/ifconfig/ifconfig.c  |   68 ++++++++++++++----------
 sbin/ifconfig/parse.h     |   13 ++++
 5 files changed, 178 insertions(+), 40 deletions(-)

diffs (truncated from 422 to 300 lines):

diff -r fa57c2e61738 -r 3eef71b54e7e sbin/ifconfig/extern.h
--- a/sbin/ifconfig/extern.h    Sun Oct 24 13:24:14 2021 +0200
+++ b/sbin/ifconfig/extern.h    Tue Oct 26 19:39:56 2021 +0200
@@ -60,6 +60,11 @@
        usage_cb_t                      f_func;
 };
 
+struct usage_create_func {
+       SIMPLEQ_ENTRY(usage_func)       f_next;
+       usage_cb_t                      f_func;
+};
+
 struct status_func {
        SIMPLEQ_ENTRY(status_func)      f_next;
        status_cb_t                     f_func;
@@ -79,12 +84,14 @@
 void cmdloop_branch_init(cmdloop_branch_t *, struct parser *);
 int register_family(struct afswtch *);
 int register_cmdloop_branch(cmdloop_branch_t *);
+int register_clone_parser(cmdloop_branch_t *);
 void statistics_func_init(statistics_func_t *, statistics_cb_t);
 void status_func_init(status_func_t *, status_cb_t);
 void usage_func_init(usage_func_t *, usage_cb_t);
 int register_statistics(statistics_func_t *);
 int register_status(status_func_t *);
 int register_usage(usage_func_t *);
+int register_usage_create(usage_func_t *);
 int register_flag(int);
 bool get_flag(int);
 void do_setethercaps(prop_dictionary_t);
diff -r fa57c2e61738 -r 3eef71b54e7e sbin/ifconfig/ieee80211.c
--- a/sbin/ifconfig/ieee80211.c Sun Oct 24 13:24:14 2021 +0200
+++ b/sbin/ifconfig/ieee80211.c Tue Oct 26 19:39:56 2021 +0200
@@ -95,6 +95,8 @@
 static int setifpowersavesleep(prop_dictionary_t, prop_dictionary_t);
 static int setifrts(prop_dictionary_t, prop_dictionary_t);
 static int scan_exec(prop_dictionary_t, prop_dictionary_t);
+static int get_mac_addr(prop_dictionary_t, const char *,
+    uint8_t ssid[IEEE80211_ADDR_LEN]);
 
 static void printies(const u_int8_t *, int, int);
 static void printwmeparam(const char *, const u_int8_t *, size_t , int);
@@ -116,8 +118,7 @@
 extern struct pinteger parse_chan, parse_frag, parse_rts;
 extern struct pstr parse_bssid, parse_ssid, parse_nwkey, wlan_device;
 extern struct pinteger parse_powersavesleep;
-extern struct pbranch wlan_or_opt_silent_family;
-extern struct pkw wlan_mode;
+extern struct pbranch clone_create_branches;
 
 static const struct kwinst ieee80211boolkw[] = {
          {.k_word = "hidessid", .k_key = "hidessid", .k_neg = true,
@@ -156,7 +157,9 @@
          {.k_word = "wds", .k_key = "mode",
           .k_type = KW_T_INT, .k_int = IEEE80211_M_WDS },
          {.k_word = "tdma", .k_key = "mode",
-          .k_type = KW_T_INT, .k_int = -1 },   /* XXX ??? */
+          .k_type = KW_T_INT, .k_int = -1 },
+          /* -1 is special cased in wlan_clone_command, this is equivalent
+           * to IEEE80211_M_AHDEMO and flags IEEE80211_CLONE_TDMA */
          {.k_word = "mesh", .k_key = "mode",
           .k_type = KW_T_INT, .k_int = IEEE80211_M_MBSS },
          {.k_word = "monitor", .k_key = "mode",
@@ -225,9 +228,48 @@
     "bssid", false, &command_root.pb_parser);
 
 struct pstr wlan_device = PSTR_INITIALIZER2(&wlan_device, "wlandev", NULL,
-     "wlandev", false, &wlan_or_opt_silent_family.pb_parser, wlan_clone_fixup,
+     "wlandev", false, &clone_create_branches.pb_parser, wlan_clone_fixup,
+     true);
+
+struct pstr wlan_bssid = PSTR_INITIALIZER2(&wlan_bssid, "wlanbssid", NULL,
+     "wlanbssid", false, &clone_create_branches.pb_parser, wlan_clone_fixup,
+     true);
+
+struct pstr wlan_addr = PSTR_INITIALIZER2(&wlan_addr, "wlanaddr", NULL,
+     "wlanaddr",  false, &clone_create_branches.pb_parser, wlan_clone_fixup,
      true);
 
+static const struct kwinst wlan_createkw[] = {
+         {.k_word = "wlandev", .k_key = "wlandev",
+          .k_nextparser = &wlan_device.ps_parser}
+       , {.k_word = "wlanmode", .k_key = "wlanmode",
+          .k_nextparser = &wlan_mode.pk_parser}
+       , {.k_word = "wlanbssid", .k_key = "wlanbssid",
+          .k_nextparser = &wlan_bssid.ps_parser}
+       , {.k_word = "wlanaddr", .k_key = "wlanaddr",
+          .k_nextparser = &wlan_addr.ps_parser}
+       , {.k_word = "wdslegacy", .k_key = "wdslegacy",
+          .k_type = KW_T_BOOL, .k_bool = true,
+          .k_nextparser = &clone_create_branches.pb_parser}
+       , {.k_word = "-wdslegacy", .k_key = "wdslegacy",
+          .k_type = KW_T_BOOL, .k_bool = false,
+          .k_nextparser = &clone_create_branches.pb_parser}
+       , {.k_word = "local-bssid", .k_key = "bssid",
+          .k_type = KW_T_BOOL, .k_bool = true,
+          .k_nextparser = &clone_create_branches.pb_parser}
+       , {.k_word = "beacons", .k_key = "beacons",
+          .k_type = KW_T_BOOL, .k_bool = true,
+          .k_nextparser = &clone_create_branches.pb_parser}
+       , {.k_word = "-beacons", .k_key = "beacons",
+          .k_type = KW_T_BOOL, .k_bool = false,
+          .k_nextparser = &clone_create_branches.pb_parser}
+};
+
+struct pkw wlan_create =
+    PKW_INITIALIZER1(&wlan_create, "wlan-create", NULL, "wlan-create",
+       wlan_createkw, __arraycount(wlan_createkw),
+       &clone_create_branches.pb_parser, wlan_clone_fixup);
+
 /*
  * We accumlute various changes originally directed at clone_command()
  * into a single extended call redirected to wlan_clone_command
@@ -266,6 +308,7 @@
        struct ieee80211_clone_params req;
        const char *parent;
        int mode;
+       bool wdslegacy = false, bssid = false, beacons = false;
 
        if (!prop_dictionary_get_cstring_nocopy(env, "wlandev", &parent)) {
                warn("wlandev required");
@@ -280,8 +323,36 @@
        carg.ifc_arg_size = sizeof req;
        carg.ifc_args = &req;
        strlcpy(req.icp_parent, parent, sizeof req.icp_parent);
-       if (prop_dictionary_get_int(env, "mode", &mode))
-               req.icp_opmode = mode;
+       if (prop_dictionary_get_int(env, "mode", &mode)) {
+               if (mode == -1) {
+                       req.icp_opmode = IEEE80211_M_AHDEMO;
+                       req.icp_flags |= IEEE80211_CLONE_TDMA;
+               } else {
+                       req.icp_opmode = mode;
+               }
+       }
+       get_mac_addr(env, "wlanbssid", req.icp_bssid);
+       if (get_mac_addr(env, "wlanaddr", req.icp_macaddr) == 0)
+               req.icp_flags |= IEEE80211_CLONE_MACADDR;
+
+       if (prop_dictionary_get_bool(env, "wdslegacy", &wdslegacy)) {
+               if (wdslegacy)
+                       req.icp_flags |= IEEE80211_CLONE_WDSLEGACY;
+               else
+                       req.icp_flags &= ~IEEE80211_CLONE_WDSLEGACY;
+       }
+       if (prop_dictionary_get_bool(env, "bssid", &bssid)) {
+               if (bssid)
+                       req.icp_flags |= IEEE80211_CLONE_BSSID;
+               else
+                       req.icp_flags &= ~IEEE80211_CLONE_BSSID;
+       }
+       if (prop_dictionary_get_bool(env, "beacons", &beacons)) {
+               if (beacons)
+                       req.icp_flags &= ~IEEE80211_CLONE_NOBEACONS;
+               else
+                       req.icp_flags |= IEEE80211_CLONE_NOBEACONS;
+       }
 
        if (direct_ioctl(env, SIOCIFCREATEARGS, &carg) == -1) {
                warn("%s", __func__);
@@ -384,6 +455,25 @@
 }
 
 static int
+get_mac_addr(prop_dictionary_t env, const char *key,
+    uint8_t ssid[IEEE80211_ADDR_LEN])
+{
+       struct ether_addr *ea;
+       const char *buf;
+
+       if (!prop_dictionary_get_cstring_nocopy(env, key, &buf))
+               return -1;
+
+       ea = ether_aton(buf);
+       if (ea == NULL) {
+               errx(EXIT_FAILURE, "malformed IEEE 802.11 MAC address %s", buf);
+               return -1;
+       }
+       memcpy(ssid, ea->ether_addr_octet, IEEE80211_ADDR_LEN);
+       return 0;
+}
+
+static int
 setifbssid(prop_dictionary_t env, prop_dictionary_t oenv)
 {
        char buf[24];
@@ -1555,7 +1645,7 @@
 }
 
 static status_func_t status;
-static usage_func_t usage;
+static usage_func_t usage, usage_create;
 static statistics_func_t statistics;
 static cmdloop_branch_t branch[2];
 
@@ -1570,8 +1660,22 @@
 }
 
 static void
+ieee80211_usage_create(prop_dictionary_t env)
+{
+       const char *progname = getprogname();
+
+       fprintf(stderr,
+               "     | %s interface create wlandev device\n"
+               "              [ wlanmode mode ] [ wlanbssid bssid ] [ wlanaddr address ]\n"
+               "              [ wdslegacy|-wdslegacy ] [ bssid|-bssid ] [ beacons|-beacons]\n",
+               progname);
+}
+
+static void
 ieee80211_constructor(void)
 {
+       static cmdloop_branch_t wlan_create_br = {};
+
        cmdloop_branch_init(&branch[0], &ieee80211bool.pk_parser);
        cmdloop_branch_init(&branch[1], &kw80211.pk_parser);
        register_cmdloop_branch(&branch[0]);
@@ -1579,8 +1683,11 @@
        status_func_init(&status, ieee80211_status);
        statistics_func_init(&statistics, ieee80211_statistics);
        usage_func_init(&usage, ieee80211_usage);
+       usage_func_init(&usage_create, ieee80211_usage_create);
        register_status(&status);
        register_statistics(&statistics);
        register_usage(&usage);
+       register_usage_create(&usage_create);
+       cmdloop_branch_init(&wlan_create_br, &wlan_create.pk_parser);
+       register_clone_parser(&wlan_create_br);
 }
-
diff -r fa57c2e61738 -r 3eef71b54e7e sbin/ifconfig/ifconfig.8
--- a/sbin/ifconfig/ifconfig.8  Sun Oct 24 13:24:14 2021 +0200
+++ b/sbin/ifconfig/ifconfig.8  Tue Oct 26 19:39:56 2021 +0200
@@ -561,13 +561,12 @@
 .Cm wds
 devices have a fixed peer relationship and do not, for example, roam
 if their peer stops communicating.
-For completeness a Dynamic WDS (DWDS) interface may marked as
+For completeness a Dynamic WDS (DWDS) interface may be marked as
 .Fl wdslegacy .
-.It Cm bssid
+.It Cm local-bssid
 Request a unique local mac address for the cloned device.
 This is only possible if the device supports multiple mac addresses.
-To force use of the parent's mac address use
-.Fl bssid .
+If this flag is not present, the parent's mac address is used.
 .It Cm beacons
 Mark the cloned interface as depending on hardware support to
 track received beacons.
diff -r fa57c2e61738 -r 3eef71b54e7e sbin/ifconfig/ifconfig.c
--- a/sbin/ifconfig/ifconfig.c  Sun Oct 24 13:24:14 2021 +0200
+++ b/sbin/ifconfig/ifconfig.c  Tue Oct 26 19:39:56 2021 +0200
@@ -171,10 +171,9 @@
 
 extern struct pbranch command_root;
 extern struct pbranch opt_command;
-extern struct pbranch opt_family, wlan_or_opt_silent_family;
-extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc,
-                wlan_create;
-extern struct pstr parse_linkstr, wlan_device, wlan_mode;
+extern struct pbranch opt_family, clone_create_branches;
+extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc;
+extern struct pstr parse_linkstr;
 
 struct pinteger parse_metric = PINTEGER_INITIALIZER(&parse_metric, "metric", 10,
     setifmetric, "metric", &command_root.pb_parser);
@@ -227,17 +226,10 @@
           .k_nextparser = &command_root.pb_parser}
 };
 
-static const struct kwinst wlan_createkw[] = {
-         {.k_word = "wlandev", .k_key = "wlandev",
-          .k_nextparser = &wlan_device.ps_parser}
-       , {.k_word = "wlanmode", .k_key = "wlanmode",
-          .k_nextparser = &wlan_mode.ps_parser}
-};
-
 /* key: clonecmd */
 static const struct kwinst clonekw[] = {
        {.k_word = "create", .k_type = KW_T_INT, .k_int = SIOCIFCREATE,
-        .k_nextparser = &wlan_or_opt_silent_family.pb_parser},
+        .k_nextparser = &clone_create_branches.pb_parser},
        {.k_word = "destroy", .k_type = KW_T_INT, .k_int = SIOCIFDESTROY}
 };
 
@@ -252,11 +244,6 @@
 struct pterm no_cmds = PTERM_INITIALIZER(&no_cmds, "no commands", no_cmds_exec,
     "none");
 
-struct pkw wlan_create =
-    PKW_INITIALIZER(&wlan_create, "wlan-create", NULL, "wlan-create",
-       wlan_createkw, __arraycount(wlan_createkw),
-       &wlan_or_opt_silent_family.pb_parser);
-
 struct pkw family_only =
     PKW_INITIALIZER(&family_only, "family-only", NULL, "af", familykw,
        __arraycount(familykw), &no_cmds.pt_parser);
@@ -282,20 +269,20 @@



Home | Main Index | Thread Index | Old Index