aboutsummaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'net.c')
-rw-r--r--net.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/net.c b/net.c
index 001ebcbc84..49f4016cf8 100644
--- a/net.c
+++ b/net.c
@@ -1396,17 +1396,39 @@ static void tap_send(void *opaque)
} while (size > 0);
}
-static void tap_set_sndbuf(TAPState *s, int sndbuf, Monitor *mon)
-{
#ifdef TUNSETSNDBUF
+/* sndbuf should be set to a value lower than the tx queue
+ * capacity of any destination network interface.
+ * Ethernet NICs generally have txqueuelen=1000, so 1Mb is
+ * a good default, given a 1500 byte MTU.
+ */
+#define TAP_DEFAULT_SNDBUF 1024*1024
+
+static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
+{
+ int sndbuf = TAP_DEFAULT_SNDBUF;
+
+ if (sndbuf_str) {
+ sndbuf = atoi(sndbuf_str);
+ }
+
+ if (!sndbuf) {
+ sndbuf = INT_MAX;
+ }
+
if (ioctl(s->fd, TUNSETSNDBUF, &sndbuf) == -1) {
config_error(mon, "TUNSETSNDBUF ioctl failed: %s\n",
strerror(errno));
}
+}
#else
- config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");
-#endif
+static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
+{
+ if (sndbuf_str) {
+ config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");
+ }
}
+#endif /* TUNSETSNDBUF */
static void tap_cleanup(VLANClientState *vc)
{
@@ -2654,9 +2676,11 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
s = net_tap_init(vlan, device, name, ifname, setup_script, down_script);
}
if (s != NULL) {
+ const char *sndbuf_str = NULL;
if (get_param_value(buf, sizeof(buf), "sndbuf", p)) {
- tap_set_sndbuf(s, atoi(buf), mon);
+ sndbuf_str = buf;
}
+ tap_set_sndbuf(s, sndbuf_str, mon);
ret = 0;
} else {
ret = -1;