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