diff options
Diffstat (limited to 'net/tap.c')
-rw-r--r-- | net/tap.c | 107 |
1 files changed, 94 insertions, 13 deletions
@@ -590,6 +590,7 @@ int net_init_bridge(const Netdev *netdev, const char *name, const char *helper, *br; TAPState *s; int fd, vnet_hdr; + NetdevBridgeOptions *stored; assert(netdev->type == NET_CLIENT_DRIVER_BRIDGE); bridge = &netdev->u.bridge; @@ -609,8 +610,20 @@ int net_init_bridge(const Netdev *netdev, const char *name, } s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper, - br); + /* Store startup parameters */ + s->nc.stored_config = g_new0(NetdevInfo, 1); + s->nc.stored_config->type = NET_BACKEND_BRIDGE; + stored = &s->nc.stored_config->u.bridge; + + if (br) { + stored->has_br = true; + stored->br = g_strdup(br); + } + + if (helper) { + stored->has_helper = true; + stored->helper = g_strdup(helper); + } return 0; } @@ -656,11 +669,13 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, const char *model, const char *name, const char *ifname, const char *script, const char *downscript, const char *vhostfdname, - int vnet_hdr, int fd, Error **errp) + int vnet_hdr, int fd, NetdevInfo **common_stored, + Error **errp) { Error *err = NULL; TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr); int vhostfd; + NetdevTapOptions *stored; tap_set_sndbuf(s->fd, tap, &err); if (err) { @@ -668,15 +683,59 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, return; } + /* Store startup parameters */ + if (!*common_stored) { + *common_stored = g_new0(NetdevInfo, 1); + (*common_stored)->type = NET_BACKEND_TAP; + s->nc.stored_config = *common_stored; + } + stored = &(*common_stored)->u.tap; + + if (tap->has_sndbuf && !stored->has_sndbuf) { + stored->has_sndbuf = true; + stored->sndbuf = tap->sndbuf; + } + + if (vnet_hdr && !stored->has_vnet_hdr) { + stored->has_vnet_hdr = true; + stored->vnet_hdr = true; + } + if (tap->has_fd || tap->has_fds) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); + if (!stored->has_fds) { + stored->has_fds = true; + stored->fds = g_strdup_printf("%d", fd); + } else { + char *tmp_s = stored->fds; + stored->fds = g_strdup_printf("%s:%d", stored->fds, fd); + g_free(tmp_s); + } } else if (tap->has_helper) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s", - tap->helper); + if (!stored->has_helper) { + stored->has_helper = true; + stored->helper = g_strdup(tap->helper); + } + + if (!stored->has_br) { + stored->has_br = true; + stored->br = tap->has_br ? g_strdup(tap->br) : + g_strdup(DEFAULT_BRIDGE_INTERFACE); + } } else { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "ifname=%s,script=%s,downscript=%s", ifname, script, - downscript); + if (ifname && !stored->has_ifname) { + stored->has_ifname = true; + stored->ifname = g_strdup(ifname); + } + + if (script && !stored->has_script) { + stored->has_script = true; + stored->script = g_strdup(script); + } + + if (downscript && !stored->has_downscript) { + stored->has_downscript = true; + stored->downscript = g_strdup(downscript); + } if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); @@ -689,9 +748,20 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { VhostNetOptions options; + stored->has_vhost = true; + stored->vhost = true; + + if (tap->has_vhostforce && tap->vhostforce) { + stored->has_vhostforce = true; + stored->vhostforce = true; + } + options.backend_type = VHOST_BACKEND_TYPE_KERNEL; options.net_backend = &s->nc; if (tap->has_poll_us) { + stored->has_poll_us = true; + stored->poll_us = tap->poll_us; + options.busyloop_timeout = tap->poll_us; } else { options.busyloop_timeout = 0; @@ -731,6 +801,15 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } options.opaque = (void *)(uintptr_t)vhostfd; + if (!stored->has_vhostfds) { + stored->has_vhostfds = true; + stored->vhostfds = g_strdup_printf("%d", vhostfd); + } else { + char *tmp_s = stored->vhostfds; + stored->vhostfds = g_strdup_printf("%s:%d", stored->fds, vhostfd); + g_free(tmp_s); + } + s->vhost_net = vhost_net_init(&options); if (!s->vhost_net) { if (tap->has_vhostforce && tap->vhostforce) { @@ -783,6 +862,7 @@ int net_init_tap(const Netdev *netdev, const char *name, const char *vhostfdname; char ifname[128]; int ret = 0; + NetdevInfo *common_stored = NULL; /* will store configuration */ assert(netdev->type == NET_CLIENT_DRIVER_TAP); tap = &netdev->u.tap; @@ -829,7 +909,7 @@ int net_init_tap(const Netdev *netdev, const char *name, net_init_tap_one(tap, peer, "tap", name, NULL, script, downscript, - vhostfdname, vnet_hdr, fd, &err); + vhostfdname, vnet_hdr, fd, &common_stored, &err); if (err) { error_propagate(errp, err); close(fd); @@ -892,7 +972,7 @@ int net_init_tap(const Netdev *netdev, const char *name, net_init_tap_one(tap, peer, "tap", name, ifname, script, downscript, tap->has_vhostfds ? vhost_fds[i] : NULL, - vnet_hdr, fd, &err); + vnet_hdr, fd, &common_stored, &err); if (err) { error_propagate(errp, err); ret = -1; @@ -935,7 +1015,7 @@ free_fail: net_init_tap_one(tap, peer, "bridge", name, ifname, script, downscript, vhostfdname, - vnet_hdr, fd, &err); + vnet_hdr, fd, &common_stored, &err); if (err) { error_propagate(errp, err); close(fd); @@ -981,7 +1061,8 @@ free_fail: net_init_tap_one(tap, peer, "tap", name, ifname, i >= 1 ? "no" : script, i >= 1 ? "no" : downscript, - vhostfdname, vnet_hdr, fd, &err); + vhostfdname, vnet_hdr, fd, + &common_stored, &err); if (err) { error_propagate(errp, err); close(fd); |