This patch adds network2-attach command to xl.
Usage: xl network2-attach <Domain> [front_mac=<mac>] [back_mac=<mac>]
[backend=<BackDomain>] [trusted=<0|1>] [back_trusted=<0|1>]
[bridge=<bridge>] [filter_mac=<0|1>] [front_filter_mac=<0|1>]
[pdev=<PDEV>] [max_bypasses=n]
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1582,6 +1582,109 @@ libxl_nicinfo *libxl_list_nics(struct li
return res;
}
+/******************************************************************************/
+int libxl_device_net2_add(struct libxl_ctx *ctx, uint32_t domid,
libxl_device_net2 *net2)
+{
+ flexarray_t *front, *back;
+ unsigned int boffset = 0, foffset = 0;
+ libxl_device device;
+ char *dompath, *dom, **l;
+ unsigned int nb;
+
+ front = flexarray_make(16, 1);
+ if (!front)
+ return ERROR_NOMEM;
+ back = flexarray_make(16, 1);
+ if (!back)
+ return ERROR_NOMEM;
+
+ if (!(dompath = libxl_xs_get_dompath(ctx, domid))) {
+ return ERROR_FAIL;
+ }
+ dom = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/name", dompath));
+
+ if (net2->devid == -1) {
+ if (!(l = libxl_xs_directory(ctx, XBT_NULL,
+ libxl_sprintf(ctx, "%s/device/vif2",
dompath), &nb))) {
+ net2->devid = 0;
+ } else {
+ net2->devid = strtoul(l[nb - 1], NULL, 10) + 1;
+ libxl_free(ctx, l);
+ }
+ }
+
+ device.backend_devid = net2->devid;
+ device.backend_domid = net2->backend_domid;
+ device.backend_kind = DEVICE_VIF2;
+ device.devid = net2->devid;
+ device.domid = net2->domid;
+ device.kind = DEVICE_VIF2;
+
+ flexarray_set(back, boffset++, "domain");
+ flexarray_set(back, boffset++, dom);
+ flexarray_set(back, boffset++, "frontend-id");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->domid));
+
+ flexarray_set(back, boffset++, "local-trusted");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d",
net2->back_trusted));
+ flexarray_set(back, boffset++, "mac");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx,
"%02x:%02x:%02x:%02x:%02x:%02x",
+ net2->back_mac[0],
net2->back_mac[1],
+ net2->back_mac[2],
net2->back_mac[3],
+ net2->back_mac[4],
net2->back_mac[5]));
+
+ flexarray_set(back, boffset++, "remote-trusted");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+ flexarray_set(back, boffset++, "remote-mac");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx,
"%02x:%02x:%02x:%02x:%02x:%02x",
+ net2->front_mac[0],
net2->front_mac[1],
+ net2->front_mac[2],
net2->front_mac[3],
+ net2->front_mac[4],
net2->front_mac[5]));
+
+ flexarray_set(back, boffset++, "max-bypasses");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d",
net2->max_bypasses));
+ flexarray_set(back, boffset++, "filter-mac");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d",
!!(net2->filter_mac)));
+ flexarray_set(back, boffset++, "handle");
+ flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->devid));
+ flexarray_set(back, boffset++, "online");
+ flexarray_set(back, boffset++, "1");
+ flexarray_set(back, boffset++, "state");
+ flexarray_set(back, boffset++, "1");
+
+ flexarray_set(front, foffset++, "backend-id");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d",
net2->backend_domid));
+
+ flexarray_set(front, foffset++, "local-trusted");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+ flexarray_set(front, foffset++, "mac");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx,
"%02x:%02x:%02x:%02x:%02x:%02x",
+ net2->front_mac[0],
net2->front_mac[1],
+ net2->front_mac[2],
net2->front_mac[3],
+ net2->front_mac[4],
net2->front_mac[5]));
+
+ flexarray_set(front, foffset++, "remote-trusted");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d",
net2->back_trusted));
+ flexarray_set(front, foffset++, "remote-mac");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx,
"%02x:%02x:%02x:%02x:%02x:%02x",
+ net2->back_mac[0],
net2->back_mac[1],
+ net2->back_mac[2],
net2->back_mac[3],
+ net2->back_mac[4],
net2->back_mac[5]));
+
+ flexarray_set(front, foffset++, "filter-mac");
+ flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d",
!!(net2->filter_mac)));
+ flexarray_set(front, foffset++, "state");
+ flexarray_set(front, foffset++, "1");
+
+ libxl_device_generic_add(ctx, &device,
+ libxl_xs_kvs_of_flexarray(ctx, back, boffset),
+ libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+
+ /* FIXME: wait for plug */
+ flexarray_free(back);
+ flexarray_free(front);
+ return 0;
+}
/******************************************************************************/
int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid,
libxl_device_console *console)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -240,6 +240,21 @@ typedef struct {
libxl_nic_type nictype;
} libxl_device_nic;
+typedef struct {
+ int devid;
+ uint8_t front_mac[6];
+ uint8_t back_mac[6];
+ uint32_t backend_domid;
+ uint32_t domid;
+ uint32_t trusted:1;
+ uint32_t back_trusted:1;
+ uint32_t filter_mac:1;
+ uint32_t front_filter_mac:1;
+ uint32_t pdev;
+ uint32_t max_bypasses;
+ char *bridge;
+} libxl_device_net2;
+
typedef struct {
union {
unsigned int value;
@@ -536,5 +551,8 @@ int libxl_tmem_set(struct libxl_ctx *ctx
uint32_t set);
int libxl_tmem_shared_auth(struct libxl_ctx *ctx, uint32_t domid, char* uuid,
int auth);
+
+int libxl_device_net2_add(struct libxl_ctx *ctx, uint32_t domid,
libxl_device_net2 *net2);
+
#endif /* LIBXL_H */
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -28,6 +28,7 @@
static const char *string_of_kinds[] = {
[DEVICE_VIF] = "vif",
+ [DEVICE_VIF2] = "vif2",
[DEVICE_VBD] = "vbd",
[DEVICE_TAP] = "tap",
[DEVICE_PCI] = "pci",
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -68,6 +68,7 @@ void xl_log(struct libxl_ctx *ctx, xento
typedef enum {
DEVICE_VIF = 1,
+ DEVICE_VIF2,
DEVICE_VBD,
DEVICE_TAP,
DEVICE_PCI,
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -467,3 +467,18 @@ int libxl_devid_to_device_disk(struct li
return 0;
}
+
+int libxl_strtomac(const char *mac_s, uint8_t *mac)
+{
+ const char *end = mac_s + 17;
+ char val, *endptr;
+
+ for (; mac_s < end; mac_s += 3, ++mac) {
+ val = strtoul(mac_s, &endptr, 16);
+ if (endptr != (mac_s + 2)) {
+ return ERROR_INVAL;
+ }
+ *mac = val;
+ }
+ return 0;
+}
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -63,6 +63,7 @@ int libxl_devid_to_device_nic(struct lib
int libxl_devid_to_device_disk(struct libxl_ctx *ctx, uint32_t domid,
const char *devid, libxl_device_disk *disk);
+int libxl_strtomac(const char *mac_s, uint8_t *mac);
#endif
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -72,6 +72,7 @@ int main_tmem_destroy(int argc, char **a
int main_tmem_thaw(int argc, char **argv);
int main_tmem_set(int argc, char **argv);
int main_tmem_shared_auth(int argc, char **argv);
+int main_network2attach(int argc, char **argv);
void help(char *command);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -241,6 +241,29 @@ static void init_nic_info(libxl_device_n
nic_info->nictype = NICTYPE_IOEMU;
}
+static void init_net2_info(libxl_device_net2 *net2_info, int devnum)
+{
+ memset(net2_info, '\0', sizeof(*net2_info));
+
+ net2_info->devid = devnum;
+ net2_info->front_mac[0] = 0x00;
+ net2_info->front_mac[1] = 0x16;
+ net2_info->front_mac[2] = 0x3e;;
+ net2_info->front_mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
+ net2_info->front_mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+ net2_info->front_mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+ net2_info->back_mac[0] = 0x00;
+ net2_info->back_mac[1] = 0x16;
+ net2_info->back_mac[2] = 0x3e;
+ net2_info->back_mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
+ net2_info->back_mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+ net2_info->back_mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+ net2_info->back_trusted = 1;
+ net2_info->filter_mac = 1;
+ net2_info->max_bypasses = 5;
+ net2_info->bridge = "xenbr0";
+}
+
static void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
{
memset(vfb, 0x00, sizeof(libxl_device_vfb));
@@ -406,6 +429,8 @@ static void parse_config_data(const char
int *num_disks,
libxl_device_nic **vifs,
int *num_vifs,
+ libxl_device_net2 **vif2s,
+ int *num_vif2s,
libxl_device_pci **pcidevs,
int *num_pcidevs,
libxl_device_vfb **vfbs,
@@ -417,7 +442,7 @@ static void parse_config_data(const char
const char *buf;
long l;
XLU_Config *config;
- XLU_ConfigList *vbds, *nics, *pcis, *cvfbs;
+ XLU_ConfigList *vbds, *nics, *pcis, *cvfbs, *net2s;
int pci_power_mgmt = 0;
int pci_msitranslate = 1;
int i, e;
@@ -648,6 +673,46 @@ skip:
}
}
+ if (!xlu_cfg_get_list(config, "vif2", &net2s, 0)) {
+ *num_vif2s = 0;
+ *vif2s = NULL;
+ while ((buf = xlu_cfg_get_listitem(net2s, *num_vif2s))) {
+ char *buf2 = strdup(buf);
+ char *p;
+
+ *vif2s = realloc(*vif2s, sizeof (libxl_device_net2) * (*num_vif2s
+ 1));
+ init_net2_info(*vif2s + *num_vif2s, *num_vif2s);
+
+ for (p = strtok(buf2, ","); p; p = strtok(buf2, ",")) {
+ while (isblank(*p))
+ p++;
+ if (!strncmp("front_mac=", p, 10)) {
+ libxl_strtomac(p + 10, (*vif2s)[*num_vif2s].front_mac);
+ } else if (!strncmp("back_mac=", p, 9)) {
+ libxl_strtomac(p + 9, (*vif2s)[*num_vif2s].back_mac);
+ } else if (!strncmp("backend=", p, 8)) {
+ domain_qualifier_to_domid(p + 8,
&((*vif2s)[*num_vif2s].backend_domid), 0);
+ } else if (!strncmp("trusted=", p, 8)) {
+ (*vif2s)[*num_vif2s].trusted = (*(p + 8) == '1');
+ } else if (!strncmp("back_trusted=", p, 13)) {
+ (*vif2s)[*num_vif2s].back_trusted = (*(p + 13) == '1');
+ } else if (!strncmp("bridge=", p, 7)) {
+ (*vif2s)[*num_vif2s].bridge = strdup(p + 13);
+ } else if (!strncmp("filter_mac=", p, 11)) {
+ (*vif2s)[*num_vif2s].filter_mac = (*(p + 11) == '1');
+ } else if (!strncmp("front_filter_mac=", p, 17)) {
+ (*vif2s)[*num_vif2s].front_filter_mac = (*(p + 17) == '1');
+ } else if (!strncmp("pdev=", p, 5)) {
+ (*vif2s)[*num_vif2s].pdev = strtoul(p + 5, NULL, 10);
+ } else if (!strncmp("max_bypasses=", p, 13)) {
+ (*vif2s)[*num_vif2s].max_bypasses = strtoul(p + 13, NULL,
10);
+ }
+ }
+ free(buf2);
+ ++(*num_vif2s);
+ }
+ }
+
if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0)) {
*num_vfbs = 0;
*num_vkbs = 0;
@@ -841,6 +906,7 @@ static int create_domain(struct domain_c
libxl_device_model_info dm_info;
libxl_device_disk *disks = NULL;
libxl_device_nic *vifs = NULL;
+ libxl_device_net2 *vif2s = NULL;
libxl_device_pci *pcidevs = NULL;
libxl_device_vfb *vfbs = NULL;
libxl_device_vkb *vkbs = NULL;
@@ -855,7 +921,7 @@ static int create_domain(struct domain_c
int migrate_fd = dom_info->migrate_fd;
char **migration_domname_r = dom_info->migration_domname_r;
- int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs =
0;
+ int num_disks = 0, num_vifs = 0, num_vif2s = 0, num_pcidevs = 0, num_vfbs
= 0, num_vkbs = 0;
int i, fd;
int need_daemon = 1;
int ret, rc;
@@ -967,7 +1033,7 @@ static int create_domain(struct domain_c
printf("Parsing config file %s\n", config_file);
- parse_config_data(config_file, config_data, config_len, &info1, &info2,
&disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs,
&vkbs, &num_vkbs, &dm_info);
+ parse_config_data(config_file, config_data, config_len, &info1, &info2,
&disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs,
&num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info);
if (migrate_fd >= 0) {
if (info1.name) {
@@ -1038,6 +1104,17 @@ start:
goto error_out;
}
}
+ if (!info1.hvm) {
+ for (i = 0; i < num_vif2s; i++) {
+ vif2s[i].domid = domid;
+ ret = libxl_device_net2_add(&ctx, domid, &(vif2s[i]));
+ if (ret) {
+ fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
+ ret = ERROR_FAIL;
+ goto error_out;
+ }
+ }
+ }
if (info1.hvm) {
dm_info.domid = domid;
MUST( libxl_create_device_model(&ctx, &dm_info, disks, num_disks,
@@ -3696,6 +3773,102 @@ int main_blockdetach(int argc, char **ar
exit(0);
}
+int main_network2attach(int argc, char **argv)
+{
+ int opt;
+ char *tok, *endptr;
+ char *back_dom = NULL;
+ uint32_t domid, back_domid;
+ unsigned int val, i;
+ libxl_device_net2 net2;
+
+ if ((argc < 3) || (argc > 12)) {
+ help("network2-attach");
+ exit(0);
+ }
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ help("network2-attach");
+ exit(0);
+ default:
+ fprintf(stderr, "option `%c' not supported.\n", opt);
+ break;
+ }
+ }
+
+ if (domain_qualifier_to_domid(argv[2], &domid, 0) < 0) {
+ fprintf(stderr, "%s is an invalid domain identifier\n", argv[1]);
+ exit(1);
+ }
+ init_net2_info(&net2, -1);
+ for (argv += 3, argc -= 3; argc > 0; --argc, ++argv) {
+ if (!strncmp("front_mac=", *argv, 10)) {
+ tok = strtok((*argv) + 10, ":");
+ for (i = 0; tok && i < 6; tok = strtok(NULL, ":"), ++i) {
+ val = strtoul(tok, &endptr, 16);
+ if ((tok == endptr) || (val > 255)) {
+ fprintf(stderr, "Invalid parameter `front_mac'.\n");
+ exit(1);
+ }
+ net2.front_mac[i] = val;
+ }
+ } else if (!strncmp("back_mac=", *argv, 9)) {
+ tok = strtok((*argv) + 10, ":");
+ for (i = 0; tok && i < 6; tok = strtok(NULL, ":"), ++i) {
+ val = strtoul(tok, &endptr, 16);
+ if ((tok == endptr) || (val > 255)) {
+ fprintf(stderr, "Invalid parameter back_mac=%s.\n", *argv
+ 9);
+ exit(1);
+ }
+ net2.back_mac[i] = val;
+ }
+ } else if (!strncmp("backend=", *argv, 8)) {
+ back_dom = *argv;
+ } else if (!strncmp("trusted=", *argv, 8)) {
+ net2.trusted = (*((*argv) + 8) == '1');
+ } else if (!strncmp("back_trusted=", *argv, 13)) {
+ net2.back_trusted = (*((*argv) + 13) == '1');
+ } else if (!strncmp("bridge=", *argv, 7)) {
+ net2.bridge = *argv + 13;
+ } else if (!strncmp("filter_mac=", *argv, 11)) {
+ net2.filter_mac = (*((*argv) + 11) == '1');
+ } else if (!strncmp("front_filter_mac=", *argv, 17)) {
+ net2.front_filter_mac = (*((*argv) + 17) == '1');
+ } else if (!strncmp("pdev=", *argv, 5)) {
+ val = strtoul(*argv + 5, &endptr, 10);
+ if (endptr == (*argv + 5)) {
+ fprintf(stderr, "Invalid parameter pdev=%s.\n", *argv + 5);
+ exit(1);
+ }
+ net2.pdev = val;
+ } else if (!strncmp("max_bypasses=", *argv, 13)) {
+ val = strtoul(*argv + 13, &endptr, 10);
+ if (endptr == (*argv + 13)) {
+ fprintf(stderr, "Invalid parameter max_bypasses=%s.\n", *argv
+ 13);
+ exit(1);
+ }
+ net2.max_bypasses = val;
+ } else {
+ fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+ exit(1);
+ }
+ }
+
+ if (back_dom) {
+ if (domain_qualifier_to_domid(back_dom, &back_domid, 0) < 0) {
+ fprintf(stderr, "%s is an invalid domain identifier\n", back_dom);
+ exit(1);
+ }
+ }
+ net2.domid = domid;
+ net2.backend_domid = back_domid;
+ if (libxl_device_net2_add(&ctx, domid, &net2)) {
+ fprintf(stderr, "libxl_device_net2_add failed.\n");
+ }
+ exit(0);
+}
+
static char *uptime_to_string(unsigned long time, int short_mode)
{
int sec, min, hour, day;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -287,6 +287,14 @@ struct cmd_spec cmd_table[] = {
"
(abcdef01-2345-6789-1234-567890abcdef)\n"
" -A AUTH 0=auth,1=deauth",
},
+ { "network2-attach",
+ &main_network2attach,
+ "Create a new version 2 virtual network device",
+ "<Domain> [front_mac=<mac>] [back_mac=<mac>] [backend=<BackDomain>]"
+ " [trusted=<0|1>] [back_trusted=<0|1>] [bridge=<bridge>]"
+ " [filter_mac=<0|1>] [front_filter_mac=<0|1>] [pdev=<PDEV>]"
+ " [max_bypasses=n]",
+ },
};
int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|