From 19fc11c6c2336b1d43726bb96fd0afc3f471574d Mon Sep 17 00:00:00 2001 From: Martin Lucina Date: Fri, 14 Nov 2014 13:28:50 +0100 Subject: [PATCH] Add support for static IPv4 configuration Signed-off-by: Martin Lucina --- app-tools/xr | 58 +++++++++++++++++--- rumpconfig.c | 147 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 168 insertions(+), 37 deletions(-) diff --git a/app-tools/xr b/app-tools/xr index 3d34679..2432499 100755 --- a/app-tools/xr +++ b/app-tools/xr @@ -43,7 +43,9 @@ usage: xr COMMAND [ args ] APP is the rumprun-xen application to start args will be passed to the application command line -b BLKSPEC configures a block device as hostpath:mountpoint - -n NETSPEC configures a network interface as type:method + -n NETSPEC configures a network interface, using one of: + inet:dhcp - IPv4 with DHCP + inet:static:ADDR/MASK[:GATEWAY] - IPv4 with static IP -i attaches to domain console on startup -p creates the domain but leaves it paused -d destroys the domain on poweroff @@ -72,6 +74,52 @@ detect_fstype() { esac } +cidr2mask() +{ + # Number of args to shift, 255..255, first non-255 byte, zeroes + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} +} + +parse_netspec() { + # Call ourselves recursively to split $@ on : + if [ "$IFS" != ":" ]; then + OLDIFS=$IFS + IFS=: parse_netspec "$@" + return $? + else + set -- $1 + IFS=$OLDIFS + fi + [ $# -lt 2 ] && usage + iftype=$1 + ifmethod=$2 + [ "${iftype}" != "inet" ] && return 1 + conf_vif="${conf_vif}''," + case ${ifmethod} in + dhcp) + echo net/${nindex}/type inet >>${xenstore} + echo net/${nindex}/method dhcp >>${xenstore} + ;; + static) + ifaddr=${3%/*} + ifmask=$(cidr2mask ${3#*/}) + ifgw=$4 + echo net/${nindex}/type inet >>${xenstore} + echo net/${nindex}/method static >>${xenstore} + echo net/${nindex}/addr ${ifaddr} >>${xenstore} + echo net/${nindex}/netmask ${ifmask} >>${xenstore} + [ -n "${ifgw}" ] && + echo net/${nindex}/gw ${ifgw} >>${xenstore} + ;; + *) + return 1 + ;; + esac + return 0 +} + # xr run: Generate configuration and run application stack. xr_run() { conf=/tmp/xr.conf.$$ @@ -90,13 +138,7 @@ xr_run() { case "$opt" in # -n: NETSPEC: type:method n) - iftype=${OPTARG%:*} - ifmethod=${OPTARG#*:} - [ "$iftype" != "inet" ] && usage - [ "$ifmethod" != "dhcp" ] && usage - conf_vif="${conf_vif}''," - echo net/${nindex}/type inet >>${xenstore} - echo net/${nindex}/method dhcp >>${xenstore} + parse_netspec "${OPTARG}" || usage nindex=$(expr $nindex + 1) ;; # -b: BLKSPEC: hostpath:mountpoint diff --git a/rumpconfig.c b/rumpconfig.c index 40b47f0..c4482b1 100644 --- a/rumpconfig.c +++ b/rumpconfig.c @@ -47,10 +47,14 @@ #include "rumpconfig.h" static int -xs_read_netconfig(const char *if_index, char **type, char **method) +xs_read_netconfig(const char *if_index, char **type, char **method, char **addr, + char **mask, char **gw) { char *if_type = NULL; char *if_method = NULL; + char *if_addr = NULL; + char *if_mask = NULL; + char *if_gw = NULL; char buf[128]; char *xberr = NULL; xenbus_transaction_t txn; @@ -70,28 +74,41 @@ xs_read_netconfig(const char *if_index, char **type, char **method) xenbus_transaction_end(txn, 0, &xbretry); return 1; } - if (strcmp(if_type, "inet") != 0) { - warnx("rumprun_config: xenif%s: unknown type '%s'", - if_index, if_type); + snprintf(buf, sizeof buf, "rumprun/net/%s/method", if_index); + xberr = xenbus_read(txn, buf, &if_method); + if (xberr) { + warnx("rumprun_config: xenif%s: read %s failed: %s", + if_index, buf, xberr); xenbus_transaction_end(txn, 0, &xbretry); free(if_type); return 1; } - snprintf(buf, sizeof buf, "rumprun/net/%s/method", if_index); - xberr = xenbus_read(txn, buf, &if_method); - if (xberr) { + /* The following parameters are dependent on the type/method. */ + snprintf(buf, sizeof buf, "rumprun/net/%s/addr", if_index); + xberr = xenbus_read(txn, buf, &if_addr); + if (xberr && strcmp(xberr, "ENOENT") != 0) { + warnx("rumprun_config: xenif%s: read %s failed: %s", + if_index, buf, xberr); + xenbus_transaction_end(txn, 0, &xbretry); + free(if_type); + return 1; + } + snprintf(buf, sizeof buf, "rumprun/net/%s/netmask", if_index); + xberr = xenbus_read(txn, buf, &if_mask); + if (xberr && strcmp(xberr, "ENOENT") != 0) { warnx("rumprun_config: xenif%s: read %s failed: %s", if_index, buf, xberr); xenbus_transaction_end(txn, 0, &xbretry); free(if_type); return 1; } - if (strcmp(if_method, "dhcp") != 0) { - warnx("rumprun_config: xenif%s: unknown method '%s'", - if_index, if_method); + snprintf(buf, sizeof buf, "rumprun/net/%s/gw", if_index); + xberr = xenbus_read(txn, buf, &if_gw); + if (xberr && strcmp(xberr, "ENOENT") != 0) { + warnx("rumprun_config: xenif%s: read %s failed: %s", + if_index, buf, xberr); xenbus_transaction_end(txn, 0, &xbretry); free(if_type); - free(if_method); return 1; } xberr = xenbus_transaction_end(txn, 0, &xbretry); @@ -104,6 +121,9 @@ xs_read_netconfig(const char *if_index, char **type, char **method) } *type = if_type; *method = if_method; + *addr = if_addr; + *mask = if_mask; + *gw = if_gw; return 0; } @@ -112,55 +132,124 @@ rumprun_config_net(const char *if_index) { char *if_type = NULL; char *if_method = NULL; + char *if_addr = NULL; + char *if_mask = NULL; + char *if_gw = NULL; char buf[128]; int rv; - rv = xs_read_netconfig(if_index, &if_type, &if_method); + rv = xs_read_netconfig(if_index, &if_type, &if_method, &if_addr, + &if_mask, &if_gw); if (rv != 0) return; - printf("rumprun_config: configuring xenif%s as %s with %s\n", - if_index, if_type, if_method); + printf("rumprun_config: configuring xenif%s as %s with %s %s\n", + if_index, if_type, if_method, if_addr ? if_addr : ""); snprintf(buf, sizeof buf, "xenif%s", if_index); if ((rv = rump_pub_netconfig_ifcreate(buf)) != 0) { - warnx("rumprun_config: creating %s failed: %d\n", buf, rv); + warnx("rumprun_config: %s: ifcreate failed: %s\n", buf, + strerror(rv)); goto out; } - if ((rv = rump_pub_netconfig_dhcp_ipv4_oneshot(buf)) != 0) { - printf("rumprun_config: dhcp for %s failed: %d\n", buf, rv); - goto out; + if (strcmp(if_type, "inet") == 0 && + strcmp(if_method, "dhcp") == 0) { + if ((rv = rump_pub_netconfig_dhcp_ipv4_oneshot(buf)) != 0) { + warnx("rumprun_config: %s: dhcp_ipv4 failed: %s\n", buf, + strerror(rv)); + goto out; + } + } + else if (strcmp(if_type, "inet") == 0 && + strcmp(if_method, "static") == 0) { + if (if_addr == NULL || if_mask == NULL) { + warnx("rumprun_config: %s: missing if_addr/mask\n"); + goto out; + } + if ((rv = rump_pub_netconfig_ipv4_ifaddr(buf, if_addr, + if_mask)) != 0) { + warnx("rumprun_config: %s: ipv4_ifaddr failed: %s\n", + buf, strerror(rv)); + goto out; + } + if (if_gw && + (rv = rump_pub_netconfig_ipv4_gw(if_gw)) != 0) { + warnx("rumprun_config: %s: ipv4_gw failed: %s\n", + buf, strerror(rv)); + goto out; + } + } + else { + warnx("rumprun_config: %s: unknown type/method %s/%s\n", + buf, if_type, if_method); } out: free(if_type); free(if_method); + if (if_addr) + free(if_addr); + if (if_mask) + free(if_mask); + if (if_gw) + free(if_gw); } static void rumprun_deconfig_net(const char *if_index) { +#if 1 + /* TODO According to pwwka this is not fully implemented yet */ + printf("rumprun_deconfig: (not yet) deconfiguring xenif%s\n", if_index); +#else char *if_type = NULL; char *if_method = NULL; + char *if_addr = NULL; + char *if_mask = NULL; + char *if_gw = NULL; + char buf[128]; int rv; - rv = xs_read_netconfig(if_index, &if_type, &if_method); + rv = xs_read_netconfig(if_index, &if_type, &if_method, &if_addr, + &if_mask, &if_gw); if (rv != 0) return; - printf("rumprun_config: (not yet) deconfiguring xenif%s\n", if_index); -#if 0 /* XXX causes dhcpcd from brlib to fall over */ - snprintf(buf, sizeof buf, "xenif%s", if_index); - if ((rv = rump_pub_netconfig_ifdown(buf)) != 0) { - warnx("rumprun_config: ifdown %s failed: %d\n", buf, rv); - return; + if (strcmp(if_type, "inet") == 0 && + strcmp(if_method, "dhcp") == 0) { + /* TODO: need an interface into brlib dhcp to allow us to + * destroy the interface. */ + printf("rumprun_deconfig: not deconfiguring xenif%s (uses dhcp)\n", + if_index); + } + else if (strcmp(if_type, "inet") == 0 && + strcmp(if_method, "static") == 0) { + snprintf(buf, sizeof buf, "xenif%s", if_index); + if ((rv = rump_pub_netconfig_ifdown(buf)) != 0) { + warnx("rumprun_deconfig: %s: ifdown failed: %s\n", buf, + strerror(rv)); + goto out; + } + if ((rv = rump_pub_netconfig_ifdestroy(buf)) != 0) { + printf("rumprun_deconfig: %s: ifdestroy failed: %s\n", + buf, strerror(rv)); + goto out; + } } - if ((rv = rump_pub_netconfig_ifdestroy(buf)) != 0) { - printf("rumprun_config: ifdestroy %s failed: %d\n", buf, rv); - return; + else { + warnx("rumprun_config: %s: unknown type/method %s/%s\n", + buf, if_type, if_method); } -#endif + +out: free(if_type); free(if_method); + if (if_addr) + free(if_addr); + if (if_mask) + free(if_mask); + if (if_gw) + free(if_gw); +#endif } static int -- 2.39.5