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 8 years ago
- Assignee set to Renato Botelho
- Target version set to 2.4.2
Updated by Jim Thompson about 8 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 8 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 8 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 8 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 8 years ago
- Assignee changed from Renato Botelho to Luiz Souza
Updated by Luiz Souza about 8 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 8 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 8 years ago
- Status changed from Feedback to Resolved
Updated by Viktor Gurov almost 4 years ago
- Related to Bug #12661: Increase Maximum Allowable Bandwidth on Limiters added