]> xenbits.xensource.com Git - rumpuser-xen.git/commitdiff
Add support for static IPv4 configuration
authorMartin Lucina <martin@lucina.net>
Fri, 14 Nov 2014 12:28:50 +0000 (13:28 +0100)
committerMartin Lucina <martin@lucina.net>
Fri, 14 Nov 2014 12:35:54 +0000 (13:35 +0100)
Signed-off-by: Martin Lucina <martin@lucina.net>
app-tools/xr
rumpconfig.c

index 3d346794f147e960cec2ed3a164913c4773046be..2432499a9cb5ba9805fd85340c81552605c31496 100755 (executable)
@@ -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
index 40b47f0d3a7d6397077e471ca48ed0c130ce31bf..c4482b16bc166a0ee30cf9694676e7fb0cf5df2f 100644 (file)
 #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