Date: Thu, 13 Dec 2018 10:18:31 +0000 (UTC) From: Vincenzo Maffione <vmaffione@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r342035 - stable/11/tools/tools/netmap Message-ID: <201812131018.wBDAIVhg093454@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vmaffione Date: Thu Dec 13 10:18:31 2018 New Revision: 342035 URL: https://svnweb.freebsd.org/changeset/base/342035 Log: MFC r341726 tools: netmap: pkt-gen: check packet length against interface MTU Validate the value of the -l argument (packet length) against the MTU of the netmap port. In case the netmap port does not refer to a physical interface (e.g. VALE port or pipe), then the netmap buffer size is used as MTU. This change also sets a better default value for the -M option, so that pkt-gen uses the largest possible fragments in case of multi-slot packets. Differential Revision: https://reviews.freebsd.org/D18436 Modified: stable/11/tools/tools/netmap/pkt-gen.c Directory Properties: stable/11/ (props changed) Modified: stable/11/tools/tools/netmap/pkt-gen.c ============================================================================== --- stable/11/tools/tools/netmap/pkt-gen.c Thu Dec 13 10:17:32 2018 (r342034) +++ stable/11/tools/tools/netmap/pkt-gen.c Thu Dec 13 10:18:31 2018 (r342035) @@ -195,7 +195,7 @@ struct virt_header { uint8_t fields[VIRT_HDR_MAX]; }; -#define MAX_BODYSIZE 16384 +#define MAX_BODYSIZE 65536 struct pkt { struct virt_header vh; @@ -238,7 +238,6 @@ struct mac_range { /* ifname can be netmap:foo-xxxx */ #define MAX_IFNAMELEN 64 /* our buffer for ifname */ -//#define MAX_PKTSIZE 1536 #define MAX_PKTSIZE MAX_BODYSIZE /* XXX: + IP_HDR + ETH_HDR */ /* compact timestamp to fit into 60 byte packet. (enough to obtain RTT) */ @@ -263,7 +262,7 @@ struct glob_arg { int forever; uint64_t npackets; /* total packets to send */ int frags; /* fragments per packet */ - u_int mtu; /* size of each fragment */ + u_int frag_size; /* size of each fragment */ int nthreads; int cpus; /* cpus used for running */ int system_cpus; /* cpus on the system */ @@ -308,6 +307,11 @@ struct glob_arg { }; enum dev_type { DEV_NONE, DEV_NETMAP, DEV_PCAP, DEV_TAP }; +enum { + TD_TYPE_SENDER = 1, + TD_TYPE_RECEIVER, + TD_TYPE_OTHER, +}; /* * Arguments for a new thread. The same structure is used by @@ -509,6 +513,42 @@ extract_mac_range(struct mac_range *r) return 0; } +static int +get_if_mtu(const struct glob_arg *g) +{ + char ifname[IFNAMSIZ]; + struct ifreq ifreq; + int s, ret; + + if (!strncmp(g->ifname, "netmap:", 7) && !strchr(g->ifname, '{') + && !strchr(g->ifname, '}')) { + /* Parse the interface name and ask the kernel for the + * MTU value. */ + strncpy(ifname, g->ifname+7, IFNAMSIZ-1); + ifname[strcspn(ifname, "-*^{}/@")] = '\0'; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + D("socket() failed: %s", strerror(errno)); + return s; + } + + memset(&ifreq, 0, sizeof(ifreq)); + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(s, SIOCGIFMTU, &ifreq); + if (ret) { + D("ioctl(SIOCGIFMTU) failed: %s", strerror(errno)); + } + + return ifreq.ifr_mtu; + } + + /* This is a pipe or a VALE port, where the MTU is very large, + * so we use some practical limit. */ + return 65536; +} + static struct targ *targs; static int global_nthreads; @@ -1581,18 +1621,18 @@ sender_body(void *data) #endif /* NO_PCAP */ } else { int tosend = 0; - u_int bufsz, mtu = targ->g->mtu; + u_int bufsz, frag_size = targ->g->frag_size; nifp = targ->nmd->nifp; txring = NETMAP_TXRING(nifp, targ->nmd->first_tx_ring); bufsz = txring->nr_buf_size; - if (bufsz < mtu) - mtu = bufsz; + if (bufsz < frag_size) + frag_size = bufsz; targ->frag_size = targ->g->pkt_size / targ->frags; - if (targ->frag_size > mtu) { - targ->frags = targ->g->pkt_size / mtu; - targ->frag_size = mtu; - if (targ->g->pkt_size % mtu != 0) + if (targ->frag_size > frag_size) { + targ->frags = targ->g->pkt_size / frag_size; + targ->frag_size = frag_size; + if (targ->g->pkt_size % frag_size != 0) targ->frags++; } D("frags %u frag_size %u", targ->frags, targ->frag_size); @@ -2441,12 +2481,6 @@ usage(int errcode) exit(errcode); } -enum { - TD_TYPE_SENDER = 1, - TD_TYPE_RECEIVER, - TD_TYPE_OTHER, -}; - static void start_threads(struct glob_arg *g) { int i; @@ -2779,8 +2813,8 @@ main(int arc, char **argv) g.cpus = 1; /* default */ g.forever = 1; g.tx_rate = 0; - g.frags =1; - g.mtu = 1500; + g.frags = 1; + g.frag_size = (u_int)-1; /* use the netmap buffer size by default */ g.nmr_config = ""; g.virt_header = 0; g.wait_link = 2; /* wait 2 seconds for physical ports */ @@ -2824,7 +2858,7 @@ main(int arc, char **argv) break; case 'M': - g.mtu = atoi(optarg); + g.frag_size = atoi(optarg); break; case 'f': @@ -3102,6 +3136,16 @@ main(int arc, char **argv) if (g.nthreads < 1 || g.nthreads > devqueues) { D("bad nthreads %d, have %d queues", g.nthreads, devqueues); // continue, fail later + } + + if (g.td_type == TD_TYPE_SENDER) { + int mtu = get_if_mtu(&g); + + if (mtu > 0 && g.pkt_size > mtu) { + D("pkt_size (%d) must be <= mtu (%d)", + g.pkt_size, mtu); + return -1; + } } if (verbose) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812131018.wBDAIVhg093454>