bool create_nic(char *nic, char *br, char *pidstr) { #if ISTEST char path[200]; sprintf(path, "/tmp/lxcnettest/%s", nic); int fd = open(path, O_RDWR|O_CREAT, S_IWUSR | S_IRUSR); if (fd < 0) return false; close(fd); return true; #else // not yet implemented char *veth1buf, *veth2buf; veth1buf = alloca(IFNAMSIZ); veth2buf = alloca(IFNAMSIZ); int ret; int pid = atoi(pidstr); ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic); if (ret < 0 || ret >= IFNAMSIZ) { fprintf(stderr, "nic name too long\n"); exit(1); } /* create the nics */ if (instanciate_veth(veth1buf, &veth2buf) < 0) { fprintf(stderr, "Error creating veth tunnel\n"); return false; } /* attach veth1 to bridge */ if (lxc_bridge_attach(br, veth1buf) < 0) { fprintf(stderr, "Error attaching %s to %s\n", veth1buf, br); goto out_del; } /* pass veth2 to target netns */ ret = lxc_netdev_move(veth2buf, pid); if (ret < 0) { fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid); goto out_del; } return true; out_del: lxc_netdev_delete_by_name(veth1buf); exit(1); #endif }
static bool create_nic(char *nic, char *br, int pid, char **cnic) { char *veth1buf, *veth2buf; veth1buf = alloca(IFNAMSIZ); veth2buf = alloca(IFNAMSIZ); int ret, mtu; ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic); if (ret < 0 || ret >= IFNAMSIZ) { fprintf(stderr, "host nic name too long\n"); return false; } /* create the nics */ if (instanciate_veth(veth1buf, &veth2buf) < 0) { fprintf(stderr, "Error creating veth tunnel\n"); return false; } /* copy the bridge's mtu to both ends */ mtu = get_mtu(br); if (mtu != -1) { if (lxc_netdev_set_mtu(veth1buf, mtu) < 0 || lxc_netdev_set_mtu(veth2buf, mtu) < 0) { fprintf(stderr, "Failed setting mtu\n"); goto out_del; } } /* attach veth1 to bridge */ if (lxc_bridge_attach(br, veth1buf) < 0) { fprintf(stderr, "Error attaching %s to %s\n", veth1buf, br); goto out_del; } /* pass veth2 to target netns */ ret = lxc_netdev_move_by_name(veth2buf, pid, NULL); if (ret < 0) { fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid); goto out_del; } *cnic = strdup(veth2buf); return true; out_del: lxc_netdev_delete_by_name(veth1buf); return false; }