tech-net archive

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

passing an if-specific string via ifconfig



Hi,

While making the rump shmif clonable I ran into the situation where I
need to configure a backing file for the interface to use as the bus.
ifconfig currently has no way to pass an if-specific string to an
interface.  I added something called linkstr (cf. link[012]) to fill
this void.  I could have added a special command too just for shmif,
but maybe it's better to loosen the structure a bit and not pollute the
ifconfig man page and syntax with a fully if-specific keyword.

It works something like this on shmif:
> ./ifconfig shmif0
ifconfig: SIOCGIFFLAGS shmif0: Device not configured
> ./ifconfig shmif0 create
> ./ifconfig shmif0
shmif0: flags=8002<BROADCAST,MULTICAST> mtu 1500
        address: b2:a0:7b:98:f8:17
> ./ifconfig shmif0 linkstr /tmp/etherbus
> ./ifconfig shmif0
shmif0: flags=8002<BROADCAST,MULTICAST> mtu 1500
        address: b2:a0:7b:98:f8:17
        linkstr: /tmp/etherbus
> ./ifconfig shmif0 -linkstr
> ./ifconfig shmif0
shmif0: flags=8002<BROADCAST,MULTICAST> mtu 1500
        address: b2:a0:7b:98:f8:17

ifconfig part of patch attached.  thoughts?
Index: ifconfig.c
===================================================================
RCS file: /cvsroot/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.222
diff -p -u -r1.222 ifconfig.c
--- ifconfig.c  5 Nov 2010 13:52:41 -0000       1.222
+++ ifconfig.c  9 Nov 2010 22:49:14 -0000
@@ -126,6 +126,8 @@ static int setifmetric(prop_dictionary_t
 static int setifmtu(prop_dictionary_t, prop_dictionary_t);
 static int setifnetmask(prop_dictionary_t, prop_dictionary_t);
 static int setifprefixlen(prop_dictionary_t, prop_dictionary_t);
+static int setlinkstr(prop_dictionary_t, prop_dictionary_t);
+static int unsetlinkstr(prop_dictionary_t, prop_dictionary_t);
 static void status(const struct sockaddr *, prop_dictionary_t,
     prop_dictionary_t);
 static void usage(void);
@@ -164,6 +166,7 @@ extern struct pbranch command_root;
 extern struct pbranch opt_command;
 extern struct pbranch opt_family, opt_silent_family;
 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);
@@ -202,6 +205,9 @@ static const struct kwinst misckw[] = {
        , {.k_word = "prefixlen", .k_nextparser = &parse_prefixlen.pi_parser}
        , {.k_word = "trailers", .k_neg = true,
           .k_exec = notrailers, .k_nextparser = &command_root.pb_parser}
+       , {.k_word = "linkstr", .k_nextparser = &parse_linkstr.ps_parser }
+       , {.k_word = "-linkstr", .k_exec = unsetlinkstr,
+          .k_nextparser = &command_root.pb_parser }
 };
 
 /* key: clonecmd */
@@ -237,6 +243,9 @@ struct paddr broadcast = PADDR_INITIALIZ
     setifbroadaddr, "broadcast", NULL, "dstormask", "broadcast",
     &command_root.pb_parser);
 
+struct pstr parse_linkstr = PSTR_INITIALIZER(&parse_linkstr, "linkstr",
+    setlinkstr, "linkstr", &command_root.pb_parser);
+
 static SIMPLEQ_HEAD(, afswtch) aflist = SIMPLEQ_HEAD_INITIALIZER(aflist);
 
 static SIMPLEQ_HEAD(, usage_func) usage_funcs =
@@ -1159,6 +1168,7 @@ status(const struct sockaddr *sdl, prop_
        statistics_func_t *statistics_f;
        struct ifdatareq ifdr;
        struct ifreq ifr;
+       struct ifdrv ifdrv;
        char fbuf[BUFSIZ];
        int af, s;
        const char *ifname;
@@ -1210,6 +1220,26 @@ status(const struct sockaddr *sdl, prop_
 
        print_link_addresses(env, true);
 
+       estrlcpy(ifdrv.ifd_name, ifname, sizeof(ifdrv.ifd_name));
+
+       ifdrv.ifd_cmd = IFLNKSTR_QUERYLEN;
+       ifdrv.ifd_len = 0;
+       ifdrv.ifd_data = NULL;
+       /* interface supports linkstr? */
+       if (ioctl(s, SIOCGLINKSTR, &ifdrv) != -1) {
+               char *p;
+
+               p = malloc(ifdrv.ifd_len);
+               if (p == NULL)
+                       err(EXIT_FAILURE, "malloc linkstr buf failed");
+               ifdrv.ifd_data = p;
+               ifdrv.ifd_cmd = 0;
+               if (ioctl(s, SIOCGLINKSTR, &ifdrv) == -1)
+                       err(EXIT_FAILURE, "failed to query linkstr");
+               printf("\tlinkstr: %s\n", (char *)ifdrv.ifd_data);
+               free(p);
+       }
+
        media_status(env, oenv);
 
        if (!vflag && !zflag)
@@ -1283,6 +1313,46 @@ setifprefixlen(prop_dictionary_t env, pr
        return 0;
 }
 
+static int
+setlinkstr(prop_dictionary_t env, prop_dictionary_t oenv)
+{
+       struct ifdrv ifdrv;
+       const char *linkstr;
+       size_t linkstrlen;
+       prop_data_t data;
+
+       data = (prop_data_t)prop_dictionary_get(env, "linkstr");
+       if (data == NULL) {
+               errno = ENOENT;
+               return -1;
+       }
+       linkstrlen = prop_data_size(data)+1;
+       linkstr = prop_data_data_nocopy(data);
+
+       ifdrv.ifd_cmd = 0;
+       ifdrv.ifd_len = linkstrlen;
+       ifdrv.ifd_data = __UNCONST(linkstr);
+
+       if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1)
+               err(EXIT_FAILURE, "SIOCSLINKSTR");
+
+       return 0;
+}
+
+static int
+unsetlinkstr(prop_dictionary_t env, prop_dictionary_t oenv)
+{
+       struct ifdrv ifdrv;
+
+       memset(&ifdrv, 0, sizeof(ifdrv));
+       ifdrv.ifd_cmd = IFLNKSTR_UNSET;
+
+       if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1)
+               err(EXIT_FAILURE, "SIOCSLINKSTR");
+
+       return 0;
+}
+
 static void
 usage(void)
 {


Home | Main Index | Thread Index | Old Index