Bug #7979
closedError setting limiter over 2GB/s
100%
Description
Setting a bandwidth limiter over unsigned 32bit int max bps seems to fail.
Found initially when I tried to create a 4096 mbps limiter and the rules failed to reload
/rc.filter_configure_sync: The command '/sbin/ipfw /tmp/rules.limiter' returned exit code '65', the output was 'Line 8: bandwidth too large'
Seems to be related to a known issue with dummynet.
https://lists.freebsd.org/pipermail/freebsd-net/2014-October/040218.html
Related issues
Updated by Jim Thompson about 7 years ago
- Assignee set to Renato Botelho
- Target version set to 2.4.2
Updated by Jim Thompson about 7 years ago
That FreeBSD-net posting is 3 years old.
Current code looks better (function: read_bandwidth())
https://svnweb.freebsd.org/base/releng/11.1/sbin/ipfw/dummynet.c?revision=320486&view=markup#l829
Support was added in June for a 'G' suffix:
https://svnweb.freebsd.org/base?view=revision&revision=320268
So I don't know that it's a signed 32-bit int overflow.
Updated by Mat Richmond about 7 years ago
# Function definition # unsigned long int strtoul (const char* str, char** endptr, int base); # Usage in dummynet code # int bw; # bw = strtoul(arg, &end, 0);
... Could be because bw isn't an unsigned long int and is just a regular (signed) int ?
Updated by Mat Richmond about 7 years ago
#include <stdint.h> #include <err.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> int _substrcmp2(const char *str1, const char* str2, const char* str3) { if (strncmp(str1, str2, strlen(str2)) != 0) return 1; if (strcmp(str1, str3) != 0) warnx("DEPRECATED: '%s' matched '%s'", str1, str3); return 0; } static void read_bandwidth(char *arg) { int bw; char *end = NULL; bw = strtoul(arg, &end, 0); if (*end == 'K' || *end == 'k') { end++; bw *= 1000; } else if (*end == 'M' || *end == 'm') { end++; bw *= 1000000; } else if (*end == 'G' || *end == 'g') { end++; bw *= 1000000000; } if ((*end == 'B' && _substrcmp2(end, "Bi", "Bit/s") != 0) || _substrcmp2(end, "by", "bytes") == 0) bw *= 8; if (bw < 0) errx(EX_DATAERR, "bandwidth too large"); printf("%i\n",bw); } int main(void) { char *stuff = "2GBit/s"; char *stuff2 = "4GBit/s"; read_bandwidth(stuff); read_bandwidth(stuff2); }
Example program calling that function can causing a failure.
Updated by Mat Richmond about 7 years ago
If you print before the bandwidth too large message you get this.
2000000000 -294967296 a.out: bandwidth too large
I should note I am doing all this on a 64bit Ubuntu VM. No idea if there are differences in output on a *BSD box.
Updated by Luiz Souza about 7 years ago
- Assignee changed from Renato Botelho to Luiz Souza
Updated by Luiz Souza about 7 years ago
- Status changed from New to Feedback
- % Done changed from 0 to 100
Fixed.
The limit is now ~4Gb (4294967295).
Updated by Constantine Kormashev about 7 years ago
Tried 4096Mb/s looks fine
00001: 4.096 Gbit/s 0 ms burst 0
q131073 50 sl. 0 flows (1 buckets) sched 65537 weight 0 lmax 0 pri 0 droptail
sched 65537 type FIFO flags 0x1 256 buckets 1 active
mask: 0x00 0xffffffff/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
176 ip 192.168.128.12/0 0.0.0.0/0 15 5540 0 0 0
Updated by Luiz Souza about 7 years ago
- Status changed from Feedback to Resolved
Updated by Viktor Gurov almost 3 years ago
- Related to Bug #12661: Increase Maximum Allowable Bandwidth on Limiters added