diff --git a/Makefile b/Makefile index 2e91c328..67176bef 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,8 @@ ADDLIB+=mpls_ntop.o mpls_pton.o CC = gcc HOSTCC = gcc DEFINES += -D_GNU_SOURCE +# Turn on transparent support for LFS +DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE CCOPTS = -O2 WFLAGS := -Wall -Wstrict-prototypes -Wmissing-prototypes WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2 diff --git a/configure b/configure index f1325df8..1605464c 100755 --- a/configure +++ b/configure @@ -284,6 +284,17 @@ check_selinux() fi } +check_mnl() +{ + if ${PKG_CONFIG} libmnl --exists + then + echo "HAVE_MNL:=y" >>Config + echo -n "yes" + else + echo -n "no" + fi +} + echo "# Generated config based on" $INCLUDE >Config check_toolchain @@ -313,5 +324,10 @@ check_selinux echo -n "ELF support: " check_elf +echo -n "libmnl support: " +check_mnl +echo " (required by tipc)" + echo -e "\nDocs" check_docs +echo "" diff --git a/misc/ss.c b/misc/ss.c index dba09017..0db0a529 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -755,7 +755,7 @@ struct tcpstat int timer; int timeout; int probes; - char *cong_alg; + char cong_alg[16]; double rto, ato, rtt, rttvar; int qack, cwnd, ssthresh, backoff; double send_bps; @@ -860,8 +860,7 @@ static const char *print_ms_timer(int timeout) return buf; } -struct scache -{ +struct scache { struct scache *next; int port; char *name; @@ -951,11 +950,15 @@ static const char *__resolve_service(int port) return NULL; } +#define SCACHE_BUCKETS 1024 +static struct scache *cache_htab[SCACHE_BUCKETS]; static const char *resolve_service(int port) { static char buf[128]; - static struct scache cache[256]; + struct scache *c; + const char *res; + int hash; if (port == 0) { buf[0] = '*'; @@ -963,45 +966,35 @@ static const char *resolve_service(int port) return buf; } - if (resolve_services) { - if (dg_proto == RAW_PROTO) { - return inet_proto_n2a(port, buf, sizeof(buf)); - } else { - struct scache *c; - const char *res; - int hash = (port^(((unsigned long)dg_proto)>>2))&255; + if (!resolve_services) + goto do_numeric; - for (c = &cache[hash]; c; c = c->next) { - if (c->port == port && - c->proto == dg_proto) { - if (c->name) - return c->name; - goto do_numeric; - } - } + if (dg_proto == RAW_PROTO) + return inet_proto_n2a(port, buf, sizeof(buf)); - if ((res = __resolve_service(port)) != NULL) { - if ((c = malloc(sizeof(*c))) == NULL) - goto do_numeric; - } else { - c = &cache[hash]; - if (c->name) - free(c->name); - } - c->port = port; - c->name = NULL; - c->proto = dg_proto; - if (res) { - c->name = strdup(res); - c->next = cache[hash].next; - cache[hash].next = c; - } - if (c->name) - return c->name; - } + + hash = (port^(((unsigned long)dg_proto)>>2)) % SCACHE_BUCKETS; + + for (c = cache_htab[hash]; c; c = c->next) { + if (c->port == port && c->proto == dg_proto) + goto do_cache; } - do_numeric: + c = malloc(sizeof(*c)); + if (!c) + goto do_numeric; + res = __resolve_service(port); + c->port = port; + c->name = res ? strdup(res) : NULL; + c->proto = dg_proto; + c->next = cache_htab[hash]; + cache_htab[hash] = c; + +do_cache: + if (c->name) + return c->name; + +do_numeric: sprintf(buf, "%u", port); return buf; } @@ -1666,7 +1659,7 @@ static void tcp_stats_print(struct tcpstat *s) printf(" ecnseen"); if (s->has_fastopen_opt) printf(" fastopen"); - if (s->cong_alg) + if (s->cong_alg[0]) printf(" %s", s->cong_alg); if (s->has_wscale_opt) printf(" wscale:%d,%d", s->snd_wscale, s->rcv_wscale); @@ -1913,11 +1906,10 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r, s.has_fastopen_opt = TCPI_HAS_OPT(info, TCPI_OPT_SYN_DATA); } - if (tb[INET_DIAG_CONG]) { - const char *cong_attr = rta_getattr_str(tb[INET_DIAG_CONG]); - s.cong_alg = malloc(strlen(cong_attr + 1)); - strcpy(s.cong_alg, cong_attr); - } + if (tb[INET_DIAG_CONG]) + strncpy(s.cong_alg, + rta_getattr_str(tb[INET_DIAG_CONG]), + sizeof(s.cong_alg) - 1); if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) { s.has_wscale_opt = true; @@ -1993,8 +1985,6 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r, tcp_stats_print(&s); if (s.dctcp) free(s.dctcp); - if (s.cong_alg) - free(s.cong_alg); } } @@ -2218,6 +2208,8 @@ static int inet_show_netlink(struct filter *f, FILE *dump_fp, int protocol) return -1; rth.dump = MAGIC_SEQ; rth.dump_fp = dump_fp; + if (preferred_family == PF_INET6) + family = PF_INET6; again: if ((err = sockdiag_send(family, rth.fd, protocol, f))) @@ -2230,7 +2222,7 @@ again: } goto Exit; } - if (family == PF_INET) { + if (family == PF_INET && preferred_family != PF_INET) { family = PF_INET6; goto again; } diff --git a/tc/tc_util.c b/tc/tc_util.c index dc2b70fa..aa6de244 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -250,18 +250,19 @@ void print_rate(char *buf, int len, __u64 rate) extern int use_iec; unsigned long kilo = use_iec ? 1024 : 1000; const char *str = use_iec ? "i" : ""; - int i = 0; static char *units[5] = {"", "K", "M", "G", "T"}; + int i; rate <<= 3; /* bytes/sec -> bits/sec */ - for (i = 0; i < ARRAY_SIZE(units); i++) { + for (i = 0; i < ARRAY_SIZE(units) - 1; i++) { if (rate < kilo) break; if (((rate % kilo) != 0) && rate < 1000*kilo) break; rate /= kilo; } + snprintf(buf, len, "%.0f%s%sbit", (double)rate, units[i], str); } diff --git a/testsuite/Makefile b/testsuite/Makefile index 4b945b0c..20276500 100644 --- a/testsuite/Makefile +++ b/testsuite/Makefile @@ -52,6 +52,9 @@ endif @for i in $(IPVERS); do \ o=`echo $$i | sed -e 's/iproute2\///'`; \ echo -n "Running $@ [$$o/`uname -r`]: "; \ + TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX`; \ + TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX`; \ + STD_ERR="$$TMP_ERR" STD_OUT="$$TMP_OUT" \ TC="$$i/tc/tc" IP="$$i/ip/ip" DEV="$(DEV)" IPVER="$@" SNAME="$$i" \ ERRF="$(RESULTS_DIR)/$@.$$o.err" $(KENV) $(PREFIX) tests/$@ > $(RESULTS_DIR)/$@.$$o.out; \ if [ "$$?" = "127" ]; then \ @@ -61,5 +64,6 @@ endif else \ echo "PASS"; \ fi; \ + rm "$$TMP_ERR" "$$TMP_OUT"; \ dmesg > $(RESULTS_DIR)/$@.$$o.dmesg; \ done diff --git a/testsuite/lib/generic.sh b/testsuite/lib/generic.sh index 3473cc13..b7de7044 100644 --- a/testsuite/lib/generic.sh +++ b/testsuite/lib/generic.sh @@ -30,57 +30,49 @@ ts_tc() { SCRIPT=$1; shift DESC=$1; shift - TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - $TC $@ 2> $TMP_ERR > $TMP_OUT + $TC $@ 2> $STD_ERR > $STD_OUT - if [ -s $TMP_ERR ]; then + if [ -s $STD_ERR ]; then ts_err "${SCRIPT}: ${DESC} failed:" ts_err "command: $TC $@" ts_err "stderr output:" - ts_err_cat $TMP_ERR - if [ -s $TMP_OUT ]; then + ts_err_cat $STD_ERR + if [ -s $STD_OUT ]; then ts_err "stdout output:" - ts_err_cat $TMP_OUT + ts_err_cat $STD_OUT fi - elif [ -s $TMP_OUT ]; then + elif [ -s $STD_OUT ]; then echo "${SCRIPT}: ${DESC} succeeded with output:" - cat $TMP_OUT + cat $STD_OUT else echo "${SCRIPT}: ${DESC} succeeded" fi - - rm $TMP_ERR $TMP_OUT } ts_ip() { SCRIPT=$1; shift DESC=$1; shift - TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - $IP $@ 2> $TMP_ERR > $TMP_OUT + $IP $@ 2> $STD_ERR > $STD_OUT RET=$? - if [ -s $TMP_ERR ] || [ "$RET" != "0" ]; then + if [ -s $STD_ERR ] || [ "$RET" != "0" ]; then ts_err "${SCRIPT}: ${DESC} failed:" ts_err "command: $IP $@" ts_err "stderr output:" - ts_err_cat $TMP_ERR - if [ -s $TMP_OUT ]; then + ts_err_cat $STD_ERR + if [ -s $STD_OUT ]; then ts_err "stdout output:" - ts_err_cat $TMP_OUT + ts_err_cat $STD_OUT fi - elif [ -s $TMP_OUT ]; then + elif [ -s $STD_OUT ]; then echo "${SCRIPT}: ${DESC} succeeded with output:" - cat $TMP_OUT + cat $STD_OUT else echo "${SCRIPT}: ${DESC} succeeded" fi - - rm $TMP_ERR $TMP_OUT } ts_qdisc_available() @@ -97,3 +89,47 @@ rand_dev() { echo "dev-$(tr -dc "[:alpha:]" < /dev/urandom | head -c 6)" } + +pr_failed() +{ + echo " [FAILED]" + ts_err "matching failed" +} + +pr_success() +{ + echo " [SUCCESS]" +} + +test_on() +{ + echo -n "test on: \"$1\"" + if cat "$STD_OUT" | grep -qE "$1" + then + pr_success + else + pr_failed + fi +} + +test_on_not() +{ + echo -n "test on: \"$1\"" + if cat "$STD_OUT" | grep -vqE "$1" + then + pr_success + else + pr_failed + fi +} + +test_lines_count() +{ + echo -n "test on lines count ($1): " + if cat "$STD_OUT" | wc -l | grep -q "$1" + then + pr_success + else + pr_failed + fi +} diff --git a/testsuite/tests/ip/link/new_link.t b/testsuite/tests/ip/link/new_link.t index 549ff256..699adbcd 100755 --- a/testsuite/tests/ip/link/new_link.t +++ b/testsuite/tests/ip/link/new_link.t @@ -7,5 +7,9 @@ ts_log "[Testing add/del virtual links]" NEW_DEV="$(rand_dev)" ts_ip "$0" "Add $NEW_DEV dummy interface" link add dev $NEW_DEV type dummy + ts_ip "$0" "Show $NEW_DEV dummy interface" link show dev $NEW_DEV +test_on "$NEW_DEV" +test_lines_count 2 + ts_ip "$0" "Del $NEW_DEV dummy interface" link del dev $NEW_DEV diff --git a/testsuite/tests/ip/route/add_default_route.t b/testsuite/tests/ip/route/add_default_route.t index 29085288..e5ea6473 100755 --- a/testsuite/tests/ip/route/add_default_route.t +++ b/testsuite/tests/ip/route/add_default_route.t @@ -8,5 +8,26 @@ DEV=dummy0 ts_ip "$0" "Add new interface $DEV" link add $DEV type dummy ts_ip "$0" "Set $DEV into UP state" link set up dev $DEV + ts_ip "$0" "Add 1.1.1.1/24 addr on $DEV" addr add 1.1.1.1/24 dev $DEV -ts_ip "$0" "Add default route via 1.1.1.1" route add default via 1.1.1.1 +ts_ip "$0" "Add default route via 1.1.1.2" route add default via 1.1.1.2 + +ts_ip "$0" "Show IPv4 default route" -4 route show default +test_on "default via 1.1.1.2 dev $DEV" +test_lines_count 1 + +ts_ip "$0" "Add another IPv4 route dst 2.2.2.0/24" -4 route add 2.2.2.0/24 dev $DEV +ts_ip "$0" "Show IPv4 default route" -4 route show default +test_on "default via 1.1.1.2 dev $DEV" +test_lines_count 1 + +ts_ip "$0" "Add dead:beef::1/64 addr on $DEV" -6 addr add dead:beef::1/64 dev $DEV +ts_ip "$0" "Add default route via dead:beef::2" route add default via dead:beef::2 +ts_ip "$0" "Show IPv6 default route" -6 route show default +test_on "default via dead:beef::2 dev $DEV" +test_lines_count 1 + +ts_ip "$0" "Add another IPv6 route dst cafe:babe::/64" -6 route add cafe:babe::/64 dev $DEV +ts_ip "$0" "Show IPv6 default route" -6 route show default +test_on "default via dead:beef::2 dev $DEV" +test_lines_count 1