From 7c73e1bd21bc54b20b2d4ad0fc1a94ca0b76c285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Fri, 21 Dec 2007 22:58:04 +0900 Subject: [PATCH 01/15] rto_min value display overflow Reported by: Satoru SATOH "ip route show" does not print correct value when larger rto_min is set (e.g. 3sec). This problem is because of overflow in print_route() and the patch below is a workaround fix for that. [root test]# ./iproute2.git.org/ip/ip route show dev eth1 192.168.140.0/24 proto kernel scope link src 192.168.140.130 169.254.0.0/16 scope link [root test]# ./iproute2.git.org/ip/ip route change 192.168.140.0/24 dev eth1 rto_min 3s [root test]# ./iproute2.git.org/ip/ip route show dev eth1 192.168.140.0/24 scope link rto_min lock 2ms <-- wrong 169.254.0.0/16 scope link [root test]# ./iproute2.git/ip/ip route show dev eth1 # patched version 192.168.140.0/24 scope link rto_min lock 3000ms <-- correct 169.254.0.0/16 scope link This is a simpler fix. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stephen Hemminger --- ip/iproute.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index f4200aef..7a885b0c 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -509,7 +509,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) i != RTAX_RTO_MIN) fprintf(fp, " %u", *(unsigned*)RTA_DATA(mxrta[i])); else { - unsigned val = *(unsigned*)RTA_DATA(mxrta[i]); + unsigned long long val = *(unsigned*)RTA_DATA(mxrta[i]); val *= 1000; if (i == RTAX_RTT) @@ -517,7 +517,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) else if (i == RTAX_RTTVAR) val /= 4; if (val >= hz) - fprintf(fp, " %ums", val/hz); + fprintf(fp, " %llums", val/hz); else fprintf(fp, " %.2fms", (float)val/hz); } From d84914a0c566516e13502fa555a92a2fb7968bb5 Mon Sep 17 00:00:00 2001 From: Vitaliy Gusev Date: Mon, 17 Dec 2007 16:06:38 +0300 Subject: [PATCH 02/15] Fix lost export-dynamic get_link_kind() fails for statically linked modules (vlan, veth, etc.) if "ip" was linked without "export-dynamic". Signed-off-by: Vitaliy Gusev -- Thank, Vitaliy Gusev Signed-off-by: Stephen Hemminger --- ip/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ip/Makefile b/ip/Makefile index 448efb90..b427d581 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -24,3 +24,5 @@ clean: rm -f $(ALLOBJ) $(TARGETS) LDLIBS += -ldl + +LDFLAGS += -Wl,-export-dynamic From 909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 19 Jul 2007 13:32:31 +0400 Subject: [PATCH 03/15] iplink_parse() routine This routine parses CLI attributes, describing generic link parameters such as name, address, etc. This is mostly copy-pasted from iplink_modify(). Signed-off-by: Pavel Emelyanov Acked-by: Patrick McHardy Signed-off-by: Stephen Hemminger --- include/utils.h | 3 + ip/iplink.c | 251 ++++++++++++++++++++++++++---------------------- 2 files changed, 138 insertions(+), 116 deletions(-) diff --git a/include/utils.h b/include/utils.h index 9ee55fdc..7223a10d 100644 --- a/include/utils.h +++ b/include/utils.h @@ -147,4 +147,7 @@ extern int cmdlineno; extern ssize_t getcmdline(char **line, size_t *len, FILE *in); extern int makeargs(char *line, char *argv[], int maxargs); +struct iplink_req; +int iplink_parse(int argc, char **argv, struct iplink_req *req, + char **name, char **type, char **link, char **dev); #endif /* __UTILS_H__ */ diff --git a/ip/iplink.c b/ip/iplink.c index f28f91c3..95801a6c 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -143,22 +143,145 @@ static int iplink_have_newlink(void) } #endif /* ! IPLINK_IOCTL_COMPAT */ -static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) +struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[1024]; +}; + +int iplink_parse(int argc, char **argv, struct iplink_req *req, + char **name, char **type, char **link, char **dev) { + int ret, len; + char abuf[32]; int qlen = -1; int mtu = -1; + + ret = argc; + + while (argc > 0) { + if (strcmp(*argv, "up") == 0) { + req->i.ifi_change |= IFF_UP; + req->i.ifi_flags |= IFF_UP; + } else if (strcmp(*argv, "down") == 0) { + req->i.ifi_change |= IFF_UP; + req->i.ifi_flags &= ~IFF_UP; + } else if (strcmp(*argv, "name") == 0) { + NEXT_ARG(); + *name = *argv; + } else if (matches(*argv, "link") == 0) { + NEXT_ARG(); + *link = *argv; + } else if (matches(*argv, "address") == 0) { + NEXT_ARG(); + len = ll_addr_a2n(abuf, sizeof(abuf), *argv); + addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); + } else if (matches(*argv, "broadcast") == 0 || + strcmp(*argv, "brd") == 0) { + NEXT_ARG(); + len = ll_addr_a2n(abuf, sizeof(abuf), *argv); + addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); + } else if (matches(*argv, "txqueuelen") == 0 || + strcmp(*argv, "qlen") == 0 || + matches(*argv, "txqlen") == 0) { + NEXT_ARG(); + if (qlen != -1) + duparg("txqueuelen", *argv); + if (get_integer(&qlen, *argv, 0)) + invarg("Invalid \"txqueuelen\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); + } else if (strcmp(*argv, "mtu") == 0) { + NEXT_ARG(); + if (mtu != -1) + duparg("mtu", *argv); + if (get_integer(&mtu, *argv, 0)) + invarg("Invalid \"mtu\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); + } else if (strcmp(*argv, "multicast") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_MULTICAST; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_MULTICAST; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_MULTICAST; + } else + return on_off("multicast"); + } else if (strcmp(*argv, "allmulticast") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_ALLMULTI; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_ALLMULTI; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_ALLMULTI; + } else + return on_off("allmulticast"); + } else if (strcmp(*argv, "promisc") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_PROMISC; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_PROMISC; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_PROMISC; + } else + return on_off("promisc"); + } else if (strcmp(*argv, "trailers") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_NOTRAILERS; + if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags |= IFF_NOTRAILERS; + } else if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags &= ~IFF_NOTRAILERS; + } else + return on_off("trailers"); + } else if (strcmp(*argv, "arp") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_NOARP; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags &= ~IFF_NOARP; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags |= IFF_NOARP; + } else + return on_off("noarp"); +#ifdef IFF_DYNAMIC + } else if (matches(*argv, "dynamic") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_DYNAMIC; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_DYNAMIC; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_DYNAMIC; + } else + return on_off("dynamic"); +#endif + } else if (matches(*argv, "type") == 0) { + NEXT_ARG(); + *type = *argv; + argc--; argv++; + break; + } else { + if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + } + if (*dev) + duparg2("dev", *argv); + *dev = *argv; + } + argc--; argv++; + } + + return ret - argc; +} + +static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) +{ int len; - char abuf[32]; char *dev = NULL; char *name = NULL; char *link = NULL; char *type = NULL; struct link_util *lu = NULL; - struct { - struct nlmsghdr n; - struct ifinfomsg i; - char buf[1024]; - } req; + struct iplink_req req; + int ret; memset(&req, 0, sizeof(req)); @@ -167,116 +290,12 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) req.n.nlmsg_type = cmd; req.i.ifi_family = preferred_family; - while (argc > 0) { - if (strcmp(*argv, "up") == 0) { - req.i.ifi_change |= IFF_UP; - req.i.ifi_flags |= IFF_UP; - } else if (strcmp(*argv, "down") == 0) { - req.i.ifi_change |= IFF_UP; - req.i.ifi_flags &= ~IFF_UP; - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); - name = *argv; - } else if (matches(*argv, "link") == 0) { - NEXT_ARG(); - link = *argv; - } else if (matches(*argv, "address") == 0) { - NEXT_ARG(); - len = ll_addr_a2n(abuf, sizeof(abuf), *argv); - addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len); - } else if (matches(*argv, "broadcast") == 0 || - strcmp(*argv, "brd") == 0) { - NEXT_ARG(); - len = ll_addr_a2n(abuf, sizeof(abuf), *argv); - addattr_l(&req.n, sizeof(req), IFLA_BROADCAST, abuf, len); - } else if (matches(*argv, "txqueuelen") == 0 || - strcmp(*argv, "qlen") == 0 || - matches(*argv, "txqlen") == 0) { - NEXT_ARG(); - if (qlen != -1) - duparg("txqueuelen", *argv); - if (get_integer(&qlen, *argv, 0)) - invarg("Invalid \"txqueuelen\" value\n", *argv); - addattr_l(&req.n, sizeof(req), IFLA_TXQLEN, &qlen, 4); - } else if (strcmp(*argv, "mtu") == 0) { - NEXT_ARG(); - if (mtu != -1) - duparg("mtu", *argv); - if (get_integer(&mtu, *argv, 0)) - invarg("Invalid \"mtu\" value\n", *argv); - addattr_l(&req.n, sizeof(req), IFLA_MTU, &mtu, 4); - } else if (strcmp(*argv, "multicast") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_MULTICAST; - if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags |= IFF_MULTICAST; - } else if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags &= ~IFF_MULTICAST; - } else - return on_off("multicast"); - } else if (strcmp(*argv, "allmulticast") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_ALLMULTI; - if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags |= IFF_ALLMULTI; - } else if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags &= ~IFF_ALLMULTI; - } else - return on_off("allmulticast"); - } else if (strcmp(*argv, "promisc") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_PROMISC; - if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags |= IFF_PROMISC; - } else if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags &= ~IFF_PROMISC; - } else - return on_off("promisc"); - } else if (strcmp(*argv, "trailers") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_NOTRAILERS; - if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags |= IFF_NOTRAILERS; - } else if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags &= ~IFF_NOTRAILERS; - } else - return on_off("trailers"); - } else if (strcmp(*argv, "arp") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_NOARP; - if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags &= ~IFF_NOARP; - } else if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags |= IFF_NOARP; - } else - return on_off("noarp"); -#ifdef IFF_DYNAMIC - } else if (matches(*argv, "dynamic") == 0) { - NEXT_ARG(); - req.i.ifi_change |= IFF_DYNAMIC; - if (strcmp(*argv, "on") == 0) { - req.i.ifi_flags |= IFF_DYNAMIC; - } else if (strcmp(*argv, "off") == 0) { - req.i.ifi_flags &= ~IFF_DYNAMIC; - } else - return on_off("dynamic"); -#endif - } else if (matches(*argv, "type") == 0) { - NEXT_ARG(); - type = *argv; - argc--; argv++; - break; - } else { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - } - if (dev) - duparg2("dev", *argv); - dev = *argv; - } - argc--; argv++; - } + ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev); + if (ret < 0) + return ret; + argc -= ret; + argv += ret; ll_init_map(&rth); if (type) { From f9329ccaf933a9dee5760de6979c7be6f17e253f Mon Sep 17 00:00:00 2001 From: Vitaliy Gusev Date: Tue, 18 Dec 2007 15:15:38 +0300 Subject: [PATCH 04/15] veth device link management Signed-off-by: Vitaliy Gusev Signed-off-by: Stephen Hemminger --- ip/link_veth.c | 80 +++++++++++++++++--------------------------------- ip/veth.h | 2 -- 2 files changed, 27 insertions(+), 55 deletions(-) diff --git a/ip/link_veth.c b/ip/link_veth.c index a4764f2e..226b4ef4 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -10,78 +10,52 @@ * */ -#include #include #include "utils.h" #include "ip_common.h" #include "veth.h" -#define ETH_ALEN 6 +#define IFNAMSIZ 16 static void usage(void) { - printf("Usage: ip link add ... type veth " - "[peer ] [mac ] [peer_mac ]\n"); + printf("Usage: ip link type veth " + "[peer ]\nTo get type " + "'ip link add help'\n"); } static int veth_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *hdr) { - __u8 mac[ETH_ALEN]; - - for (; argc != 0; argv++, argc--) { - if (strcmp(*argv, "peer") == 0) { - argv++; - argc--; - if (argc == 0) { - usage(); - return -1; - } - - addattr_l(hdr, 1024, VETH_INFO_PEER, - *argv, strlen(*argv)); - - continue; - } - - if (strcmp(*argv, "mac") == 0) { - argv++; - argc--; - if (argc == 0) { - usage(); - return -1; - } - - if (hexstring_a2n(*argv, mac, sizeof(mac)) == NULL) - return -1; - - addattr_l(hdr, 1024, VETH_INFO_MAC, - mac, ETH_ALEN); - continue; - } - - if (strcmp(*argv, "peer_mac") == 0) { - argv++; - argc--; - if (argc == 0) { - usage(); - return -1; - } - - if (hexstring_a2n(*argv, mac, sizeof(mac)) == NULL) - return -1; - - addattr_l(hdr, 1024, VETH_INFO_PEER_MAC, - mac, ETH_ALEN); - continue; - } + char *name, *type, *link, *dev; + int err, len; + struct rtattr * data; + if (strcmp(argv[0], "peer") != 0) { usage(); return -1; } - return 0; + data = NLMSG_TAIL(hdr); + addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0); + + hdr->nlmsg_len += sizeof(struct ifinfomsg); + + err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr, + &name, &type, &link, &dev); + if (err < 0) + return err; + + if (name) { + len = strlen(name) + 1; + if (len > IFNAMSIZ) + invarg("\"name\" too long\n", *argv); + addattr_l(hdr, 1024, IFLA_IFNAME, name, len); + } + + data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data; + return argc - 1 - err; } struct link_util veth_link_util = { diff --git a/ip/veth.h b/ip/veth.h index b84a5301..aa2e6f91 100644 --- a/ip/veth.h +++ b/ip/veth.h @@ -3,9 +3,7 @@ enum { VETH_INFO_UNSPEC, - VETH_INFO_MAC, VETH_INFO_PEER, - VETH_INFO_PEER_MAC, __VETH_INFO_MAX #define VETH_INFO_MAX (__VETH_INFO_MAX - 1) From c595fda55bfed9753851de5675aa310f523564b3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 21 Dec 2007 09:37:30 -0800 Subject: [PATCH 05/15] veth: use kernel header file Use santized kernel header for veth.h and put in correct place to prevent possible future problems with API. Signed-off-by: Stephen Hemminger --- {ip => include/net}/veth.h | 4 ++-- ip/link_veth.c | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) rename {ip => include/net}/veth.h (71%) diff --git a/ip/veth.h b/include/net/veth.h similarity index 71% rename from ip/veth.h rename to include/net/veth.h index aa2e6f91..3354c1eb 100644 --- a/ip/veth.h +++ b/include/net/veth.h @@ -1,5 +1,5 @@ -#ifndef __NET_VETH_H__ -#define __NET_VETH_H__ +#ifndef __NET_VETH_H_ +#define __NET_VETH_H_ enum { VETH_INFO_UNSPEC, diff --git a/ip/link_veth.c b/ip/link_veth.c index 226b4ef4..9dfb78f6 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -11,22 +11,21 @@ */ #include +#include +#include #include "utils.h" #include "ip_common.h" -#include "veth.h" - -#define IFNAMSIZ 16 static void usage(void) { printf("Usage: ip link type veth " - "[peer ]\nTo get type " - "'ip link add help'\n"); + "[peer ]\nTo get type " + "'ip link add help'\n"); } static int veth_parse_opt(struct link_util *lu, int argc, char **argv, - struct nlmsghdr *hdr) + struct nlmsghdr *hdr) { char *name, *type, *link, *dev; int err, len; @@ -43,7 +42,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, hdr->nlmsg_len += sizeof(struct ifinfomsg); err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr, - &name, &type, &link, &dev); + &name, &type, &link, &dev); if (err < 0) return err; From 235ac6a41d9d0439cce4eca8acdd31cac28605fc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 21 Dec 2007 09:53:45 -0800 Subject: [PATCH 06/15] snapshot target Add Makefile target to create snapshot file. Signed-off-by: Stephen Hemminger --- Makefile | 4 ++++ include/SNAPSHOT.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6c976dd9..de04176d 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,10 @@ install: all install -m 0755 -d $(DESTDIR)$(MANDIR)/man3 install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3 +snapshot: + echo "static const char SNAPSHOT[] = \""`date +%y%m%d`"\";" \ + > include/SNAPSHOT.h + clean: rm -f cscope.* @for i in $(SUBDIRS) doc; \ diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index dde2804d..cdeb2067 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static char SNAPSHOT[] = "071016"; +static const char SNAPSHOT[] = "071221"; From 118c923cc09551d3428e2905a69c07c5719988e5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Dec 2007 12:38:08 -0800 Subject: [PATCH 07/15] veth.h move to linux/ Move veth.h to linux/ since it is an API. Signed-off-by: Stephen Hemminger --- include/{net => linux}/veth.h | 0 ip/link_veth.c | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename include/{net => linux}/veth.h (100%) diff --git a/include/net/veth.h b/include/linux/veth.h similarity index 100% rename from include/net/veth.h rename to include/linux/veth.h diff --git a/ip/link_veth.c b/ip/link_veth.c index 9dfb78f6..9f5e8715 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include "utils.h" #include "ip_common.h" From ea5dd59c03b36fe2acec8f03a8d7a2f7b7036b04 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 31 Dec 2007 10:15:03 -0800 Subject: [PATCH 08/15] Manual page fixes These are from debian sid. Signed-off-by: Stephen Hemminger --- man/man8/ip.8 | 2 +- man/man8/ss.8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 8fd6d528..84ec6f3d 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -32,7 +32,7 @@ maddr " | " mroute " | " monitor " }" .br .BR promisc " { " on " | " off " } |" .br -.BR allmulti " { " on " | " off " } |" +.BR allmulticast " { " on " | " off " } |" .br .BR dynamic " { " on " | " off " } |" .br diff --git a/man/man8/ss.8 b/man/man8/ss.8 index 19f341e6..015feb38 100644 --- a/man/man8/ss.8 +++ b/man/man8/ss.8 @@ -107,7 +107,7 @@ Display all UDP sockets. .B ss -o state established '( dport = :ssh or sport = :ssh )' Display all established ssh connections. .TP -.B ss -x src \"/tmp/.X11-unix/*\" +.B ss -x src /tmp/.X11-unix/* Find all local processes connected to X server. .TP .B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24 From 6b1ac654e9364ad279d3c82d8a3ef93efa9f3dfa Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 31 Dec 2007 10:29:52 -0800 Subject: [PATCH 09/15] add decode of match rules Show ip address etc when decoding output of tc filter show Signed-off-by: Stephen Hemminger --- include/utils.h | 1 + lib/utils.c | 35 ++++++++++++---------------- tc/f_u32.c | 61 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/include/utils.h b/include/utils.h index 7223a10d..5daed6b3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -74,6 +74,7 @@ extern int get_addr_1(inet_prefix *dst, const char *arg, int family); extern int get_prefix_1(inet_prefix *dst, char *arg, int family); extern int get_addr(inet_prefix *dst, const char *arg, int family); extern int get_prefix(inet_prefix *dst, char *arg, int family); +extern int mask2bits(__u32 netmask); extern int get_integer(int *val, const char *arg, int base); extern int get_unsigned(unsigned *val, const char *arg, int base); diff --git a/lib/utils.c b/lib/utils.c index 84948513..d99deacd 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -47,27 +47,18 @@ int get_integer(int *val, const char *arg, int base) return 0; } -/* a valid netmask must be 2^n - 1 */ -static int is_valid_netmask(const inet_prefix *addr) -{ - uint32_t host; - - if (addr->family != AF_INET) - return 0; - - host = ~ntohl(addr->data[0]); - - return (host & (host + 1)) == 0; -} - -static unsigned cidr(const inet_prefix *addr) +int mask2bits(__u32 netmask) { unsigned bits = 0; - u_int32_t mask; + __u32 mask = ntohl(netmask); + __u32 host = ~mask; - for (mask = ntohl(addr->data[0]); mask; mask <<= 1) + /* a valid netmask must be 2^n - 1 */ + if ((host & (host + 1)) != 0) + return -1; + + for (; mask; mask <<= 1) ++bits; - return bits; } @@ -79,11 +70,13 @@ static int get_netmask(unsigned *val, const char *arg, int base) return 0; /* try coverting dotted quad to CIDR */ - if (!get_addr_1(&addr, arg, AF_INET)) { - if (is_valid_netmask(&addr)) + if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) { + int b = mask2bits(addr.data[0]); + + if (b >= 0) { + *val = b; return 0; - - *val = cidr(&addr); + } } return -1; diff --git a/tc/f_u32.c b/tc/f_u32.c index 1ac671b3..91f2838b 100644 --- a/tc/f_u32.c +++ b/tc/f_u32.c @@ -473,7 +473,7 @@ done: *argv_p = argv; return res; } - + static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; @@ -564,6 +564,7 @@ done: return res; } + static int parse_icmp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; @@ -771,7 +772,47 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) return 0; } -static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) +static void show_key(FILE *f, const struct tc_u32_key *key) +{ + char abuf[256]; + + if (show_raw) + goto raw; + + switch (key->off) { + case 12: + case 16: { + int bits = mask2bits(key->mask); + if (bits >= 0) { + fprintf(f, "\n %s %s/%d\n", + key->off == 12 ? "src" : "dst", + inet_ntop(AF_INET, &key->val, abuf, sizeof(abuf)), + bits); + return; + } + } + break; + + case 20: + case 22: + if (key->mask == ntohl(0xffff)) { + fprintf(f, "\n %s %u\n", + key->off == 20 ? "sport" : "dport", + (unsigned short) ntohl(key->val)); + return; + } + } + +raw: + fprintf(f, "\n match %08x/%08x at %s%d", + (unsigned int)ntohl(key->val), + (unsigned int)ntohl(key->mask), + key->offmask ? "nexthdr+" : "", + key->off); +} + +static int u32_parse_opt(struct filter_util *qu, char *handle, + int argc, char **argv, struct nlmsghdr *n) { struct { struct tc_u32_sel sel; @@ -966,7 +1007,8 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char ** return 0; } -static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) +static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, + __u32 handle) { struct rtattr *tb[TCA_U32_MAX+1]; struct tc_u32_sel *sel = NULL; @@ -1037,17 +1079,12 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __ } if (sel) { - int i; - struct tc_u32_key *key = sel->keys; if (sel->nkeys) { - for (i=0; inkeys; i++, key++) { - fprintf(f, "\n match %08x/%08x at %s%d", - (unsigned int)ntohl(key->val), - (unsigned int)ntohl(key->mask), - key->offmask ? "nexthdr+" : "", - key->off); + int i; + for (i=0; inkeys; i++) { + show_key(f, sel->keys + i); if (show_stats && NULL != pf) - fprintf(f, " (success %lld ) ", + fprintf(f, " (success %llu ) ", (unsigned long long) pf->kcnts[i]); } } From 2188a84d1c43ccf2d0b75829898f203891d4a7e5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 31 Dec 2007 10:30:40 -0800 Subject: [PATCH 10/15] snapshot 31 Dec 2007 Signed-off-by: Stephen Hemminger --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index cdeb2067..56a58ac0 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "071221"; +static const char SNAPSHOT[] = "071231"; From 77aa4d03a7e54dc1cb40f4497a8882fb0c7deb48 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 31 Dec 2007 10:41:18 -0800 Subject: [PATCH 11/15] Use netinet/tcp.h (with correction) rather than kernel headers Fix the userspace header file rather than importing more kernel headers. Signed-off-by: Stephen Hemminger --- include/linux/tcp.h | 174 --------------------------------------- include/net/tcp_states.h | 50 ----------- misc/ss.c | 3 +- 3 files changed, 1 insertion(+), 226 deletions(-) delete mode 100644 include/linux/tcp.h delete mode 100644 include/net/tcp_states.h diff --git a/include/linux/tcp.h b/include/linux/tcp.h deleted file mode 100644 index dd2985e7..00000000 --- a/include/linux/tcp.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the TCP protocol. - * - * Version: @(#)tcp.h 1.0.2 04/28/93 - * - * Author: Fred N. van Kempen, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _LINUX_TCP_H -#define _LINUX_TCP_H - -#include -#include -#include - -struct tcphdr { - __be16 source; - __be16 dest; - __be32 seq; - __be32 ack_seq; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u16 res1:4, - doff:4, - fin:1, - syn:1, - rst:1, - psh:1, - ack:1, - urg:1, - ece:1, - cwr:1; -#elif defined(__BIG_ENDIAN_BITFIELD) - __u16 doff:4, - res1:4, - cwr:1, - ece:1, - urg:1, - ack:1, - psh:1, - rst:1, - syn:1, - fin:1; -#else -#error "Adjust your defines" -#endif - __be16 window; - __sum16 check; - __be16 urg_ptr; -}; - -/* - * The union cast uses a gcc extension to avoid aliasing problems - * (union is compatible to any of its members) - * This means this part of the code is -fstrict-aliasing safe now. - */ -union tcp_word_hdr { - struct tcphdr hdr; - __be32 words[5]; -}; - -#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) - -enum { - TCP_FLAG_CWR = __constant_htonl(0x00800000), - TCP_FLAG_ECE = __constant_htonl(0x00400000), - TCP_FLAG_URG = __constant_htonl(0x00200000), - TCP_FLAG_ACK = __constant_htonl(0x00100000), - TCP_FLAG_PSH = __constant_htonl(0x00080000), - TCP_FLAG_RST = __constant_htonl(0x00040000), - TCP_FLAG_SYN = __constant_htonl(0x00020000), - TCP_FLAG_FIN = __constant_htonl(0x00010000), - TCP_RESERVED_BITS = __constant_htonl(0x0F000000), - TCP_DATA_OFFSET = __constant_htonl(0xF0000000) -}; - -/* TCP socket options */ -#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */ -#define TCP_MAXSEG 2 /* Limit MSS */ -#define TCP_CORK 3 /* Never send partially complete segments */ -#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ -#define TCP_KEEPINTVL 5 /* Interval between keepalives */ -#define TCP_KEEPCNT 6 /* Number of keepalives before death */ -#define TCP_SYNCNT 7 /* Number of SYN retransmits */ -#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ -#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ -#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ -#define TCP_INFO 11 /* Information about this connection. */ -#define TCP_QUICKACK 12 /* Block/reenable quick acks */ -#define TCP_CONGESTION 13 /* Congestion control algorithm */ -#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ - -#define TCPI_OPT_TIMESTAMPS 1 -#define TCPI_OPT_SACK 2 -#define TCPI_OPT_WSCALE 4 -#define TCPI_OPT_ECN 8 - -enum tcp_ca_state -{ - TCP_CA_Open = 0, -#define TCPF_CA_Open (1< #include -#include -#include int resolve_hosts = 0; int resolve_services = 1; From bccd014b866daa21002f7ac682cee57a9fe003e3 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Tue, 11 Sep 2007 16:59:58 +0200 Subject: [PATCH 12/15] Overhead calculation is now done in the kernel. The only current user is HTB. HTB overhead argument is now passed on to the kernel (in the struct tc_ratespec). Also correct the data types. Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Stephen Hemminger --- tc/q_htb.c | 17 ++++++++++------- tc/tc_core.c | 4 ---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/tc/q_htb.c b/tc/q_htb.c index 53e3f787..310d36d1 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -107,8 +107,9 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str __u32 rtab[256],ctab[256]; unsigned buffer=0,cbuffer=0; int cell_log=-1,ccell_log = -1; - unsigned mtu, mpu; - unsigned char mpu8 = 0, overhead = 0; + unsigned mtu; + unsigned short mpu = 0; + unsigned short overhead = 0; struct rtattr *tail; memset(&opt, 0, sizeof(opt)); mtu = 1600; /* eth packet len */ @@ -127,12 +128,12 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str } } else if (matches(*argv, "mpu") == 0) { NEXT_ARG(); - if (get_u8(&mpu8, *argv, 10)) { + if (get_u16(&mpu, *argv, 10)) { explain1("mpu"); return -1; } } else if (matches(*argv, "overhead") == 0) { NEXT_ARG(); - if (get_u8(&overhead, *argv, 10)) { + if (get_u16(&overhead, *argv, 10)) { explain1("overhead"); return -1; } } else if (matches(*argv, "quantum") == 0) { @@ -206,9 +207,11 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str if (!buffer) buffer = opt.rate.rate / get_hz() + mtu; if (!cbuffer) cbuffer = opt.ceil.rate / get_hz() + mtu; -/* encode overhead and mpu, 8 bits each, into lower 16 bits */ - mpu = (unsigned)mpu8 | (unsigned)overhead << 8; - opt.ceil.mpu = mpu; opt.rate.mpu = mpu; + opt.ceil.overhead = overhead; + opt.rate.overhead = overhead; + + opt.ceil.mpu = mpu; + opt.rate.mpu = mpu; if ((cell_log = tc_calc_rtable(opt.rate.rate, rtab, cell_log, mtu, mpu)) < 0) { fprintf(stderr, "htb: failed to calculate rate table.\n"); diff --git a/tc/tc_core.c b/tc/tc_core.c index 1365e081..3908c886 100644 --- a/tc/tc_core.c +++ b/tc/tc_core.c @@ -73,8 +73,6 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, unsigned mpu) { int i; - unsigned overhead = (mpu >> 8) & 0xFF; - mpu = mpu & 0xFF; if (mtu == 0) mtu = 2047; @@ -86,8 +84,6 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, } for (i=0; i<256; i++) { unsigned sz = (i< Date: Wed, 5 Sep 2007 10:47:47 +0200 Subject: [PATCH 13/15] Cleanup: tc_calc_rtable(). Change tc_calc_rtable() to take a tc_ratespec struct as an argument. (cell_log still needs to be passed on as a parameter, because -1 indicate that the cell_log needs to be computed by the function.). Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Stephen Hemminger --- tc/m_police.c | 10 ++++------ tc/q_cbq.c | 10 ++++------ tc/q_htb.c | 6 ++---- tc/q_tbf.c | 11 +++++------ tc/tc_core.c | 6 ++++-- tc/tc_core.h | 2 +- 6 files changed, 20 insertions(+), 25 deletions(-) diff --git a/tc/m_police.c b/tc/m_police.c index 5d2528b8..acdfd223 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -263,22 +263,20 @@ int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_ } if (p.rate.rate) { - if ((Rcell_log = tc_calc_rtable(p.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { + p.rate.mpu = mpu; + if (tc_calc_rtable(&p.rate, rtab, Rcell_log, mtu) < 0) { fprintf(stderr, "TBF: failed to calculate rate table.\n"); return -1; } p.burst = tc_calc_xmittime(p.rate.rate, buffer); - p.rate.cell_log = Rcell_log; - p.rate.mpu = mpu; } p.mtu = mtu; if (p.peakrate.rate) { - if ((Pcell_log = tc_calc_rtable(p.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { + p.peakrate.mpu = mpu; + if (tc_calc_rtable(&p.peakrate, ptab, Pcell_log, mtu) < 0) { fprintf(stderr, "POLICE: failed to calculate peak rate table.\n"); return -1; } - p.peakrate.cell_log = Pcell_log; - p.peakrate.mpu = mpu; } tail = NLMSG_TAIL(n); diff --git a/tc/q_cbq.c b/tc/q_cbq.c index f2b4ce87..df98312e 100644 --- a/tc/q_cbq.c +++ b/tc/q_cbq.c @@ -137,12 +137,11 @@ static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl if (allot < (avpkt*3)/2) allot = (avpkt*3)/2; - if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, allot, mpu)) < 0) { + r.mpu = mpu; + if (tc_calc_rtable(&r, rtab, cell_log, allot) < 0) { fprintf(stderr, "CBQ: failed to calculate rate table.\n"); return -1; } - r.cell_log = cell_log; - r.mpu = mpu; if (ewma_log < 0) ewma_log = TC_CBQ_DEF_EWMA; @@ -336,12 +335,11 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str unsigned pktsize = wrr.allot; if (wrr.allot < (lss.avpkt*3)/2) wrr.allot = (lss.avpkt*3)/2; - if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, pktsize, mpu)) < 0) { + r.mpu = mpu; + if (tc_calc_rtable(&r, rtab, cell_log, pktsize) < 0) { fprintf(stderr, "CBQ: failed to calculate rate table.\n"); return -1; } - r.cell_log = cell_log; - r.mpu = mpu; } if (ewma_log < 0) ewma_log = TC_CBQ_DEF_EWMA; diff --git a/tc/q_htb.c b/tc/q_htb.c index 310d36d1..e24ad6de 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -213,19 +213,17 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str opt.ceil.mpu = mpu; opt.rate.mpu = mpu; - if ((cell_log = tc_calc_rtable(opt.rate.rate, rtab, cell_log, mtu, mpu)) < 0) { + if (tc_calc_rtable(&opt.rate, rtab, cell_log, mtu) < 0) { fprintf(stderr, "htb: failed to calculate rate table.\n"); return -1; } opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); - opt.rate.cell_log = cell_log; - if ((ccell_log = tc_calc_rtable(opt.ceil.rate, ctab, cell_log, mtu, mpu)) < 0) { + if (tc_calc_rtable(&opt.ceil, ctab, ccell_log, mtu) < 0) { fprintf(stderr, "htb: failed to calculate ceil rate table.\n"); return -1; } opt.cbuffer = tc_calc_xmittime(opt.ceil.rate, cbuffer); - opt.ceil.cell_log = ccell_log; tail = NLMSG_TAIL(n); addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); diff --git a/tc/q_tbf.c b/tc/q_tbf.c index 1fc05f49..c7b4f0f4 100644 --- a/tc/q_tbf.c +++ b/tc/q_tbf.c @@ -170,21 +170,20 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl opt.limit = lim; } - if ((Rcell_log = tc_calc_rtable(opt.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { + opt.rate.mpu = mpu; + if (tc_calc_rtable(&opt.rate, rtab, Rcell_log, mtu) < 0) { fprintf(stderr, "TBF: failed to calculate rate table.\n"); return -1; } opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); - opt.rate.cell_log = Rcell_log; - opt.rate.mpu = mpu; + if (opt.peakrate.rate) { - if ((Pcell_log = tc_calc_rtable(opt.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { + opt.peakrate.mpu = mpu; + if (tc_calc_rtable(&opt.peakrate, ptab, Pcell_log, mtu) < 0) { fprintf(stderr, "TBF: failed to calculate peak rate table.\n"); return -1; } opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu); - opt.peakrate.cell_log = Pcell_log; - opt.peakrate.mpu = mpu; } tail = NLMSG_TAIL(n); diff --git a/tc/tc_core.c b/tc/tc_core.c index 3908c886..b5e362fa 100644 --- a/tc/tc_core.c +++ b/tc/tc_core.c @@ -69,10 +69,11 @@ unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks) rtab[pkt_len>>cell_log] = pkt_xmit_time */ -int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, - unsigned mpu) +int tc_calc_rtable(struct tc_ratespec *r, __u32 *rtab, int cell_log, unsigned mtu) { int i; + unsigned bps = r->rate; + unsigned mpu = r->mpu; if (mtu == 0) mtu = 2047; @@ -88,6 +89,7 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, sz = mpu; rtab[i] = tc_calc_xmittime(bps, sz); } + r->cell_log=cell_log; return cell_log; } diff --git a/tc/tc_core.h b/tc/tc_core.h index 3a0ed7cc..080a0cda 100644 --- a/tc/tc_core.h +++ b/tc/tc_core.h @@ -13,7 +13,7 @@ unsigned tc_core_time2ktime(unsigned time); unsigned tc_core_ktime2time(unsigned ktime); unsigned tc_calc_xmittime(unsigned rate, unsigned size); unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks); -int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, unsigned mpu); +int tc_calc_rtable(struct tc_ratespec *r, __u32 *rtab, int cell_log, unsigned mtu); int tc_setup_estimator(unsigned A, unsigned time_const, struct tc_estimator *est); From eeee367d91c4004c9f75749b5b09e21fa9244b51 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Wed, 5 Sep 2007 15:24:51 +0200 Subject: [PATCH 14/15] Change the rate table calc of transmit cost to use upper bound value. Patrick McHardy, Cite: 'its better to overestimate than underestimate to stay in control of the queue'. Illustrating the rate table array: Legend description rtab[x] : Array index x of rtab[x] xmit_sz : Transmit size contained in rtab[x] (normally transmit time) maps[a-b] : Packet sizes from a to b, will map into rtab[x] Current/old rate table mapping (cell_log:3): rtab[0]:=xmit_sz:0 maps[0-7] rtab[1]:=xmit_sz:8 maps[8-15] rtab[2]:=xmit_sz:16 maps[16-23] rtab[3]:=xmit_sz:24 maps[24-31] rtab[4]:=xmit_sz:32 maps[32-39] rtab[5]:=xmit_sz:40 maps[40-47] rtab[6]:=xmit_sz:48 maps[48-55] New rate table mapping, with kernel cell_align support. rtab[0]:=xmit_sz:8 maps[0-8] rtab[1]:=xmit_sz:16 maps[9-16] rtab[2]:=xmit_sz:24 maps[17-24] rtab[3]:=xmit_sz:32 maps[25-32] rtab[4]:=xmit_sz:40 maps[33-40] rtab[5]:=xmit_sz:48 maps[41-48] rtab[6]:=xmit_sz:56 maps[49-56] New TC util on a kernel WITHOUT support for cell_align rtab[0]:=xmit_sz:8 maps[0-7] rtab[1]:=xmit_sz:16 maps[8-15] rtab[2]:=xmit_sz:24 maps[16-23] rtab[3]:=xmit_sz:32 maps[24-31] rtab[4]:=xmit_sz:40 maps[32-39] rtab[5]:=xmit_sz:48 maps[40-47] rtab[6]:=xmit_sz:56 maps[48-55] Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Stephen Hemminger --- tc/tc_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tc/tc_core.c b/tc/tc_core.c index b5e362fa..9ae4d8e5 100644 --- a/tc/tc_core.c +++ b/tc/tc_core.c @@ -84,11 +84,12 @@ int tc_calc_rtable(struct tc_ratespec *r, __u32 *rtab, int cell_log, unsigned mt cell_log++; } for (i=0; i<256; i++) { - unsigned sz = (i<cell_align=-1; // Due to the sz calc r->cell_log=cell_log; return cell_log; } From 53c017880b311d7d68926109d4248c900286f6b7 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Mon, 24 Dec 2007 11:51:11 -0500 Subject: [PATCH 15/15] iptables compatiablity New iptables 1.4.0 has some library names changed from libipt to libxt. It is prefferable also to open libxt_ first, as newer "style". Signed-off-by: Denys Fedoryshchenko Signed-off-by: Jamal Hadi Salim Signed-off-by: Stephen Hemminger --- tc/m_ipt.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tc/m_ipt.c b/tc/m_ipt.c index acbb8d2d..f2a9305d 100644 --- a/tc/m_ipt.c +++ b/tc/m_ipt.c @@ -68,6 +68,13 @@ register_target(struct iptables_target *me) } +void +xtables_register_target(struct iptables_target *me) +{ + me->next = t_list; + t_list = me; +} + void exit_tryhelp(int status) { @@ -248,11 +255,24 @@ get_target_name(const char *name) } } - sprintf(path, "%s/libipt_%s.so",lib_dir, new_name); + /* try libxt_xx first */ + sprintf(path, "%s/libxt_%s.so", lib_dir, new_name); handle = dlopen(path, RTLD_LAZY); if (!handle) { - sprintf(path, lib_dir, "/libipt_%s.so", lname); + /* try libipt_xx next */ + sprintf(path, "%s/libipt_%s.so", lib_dir, new_name); handle = dlopen(path, RTLD_LAZY); + + if (!handle) { + sprintf(path, "%s/libxt_%s.so", lib_dir , lname); + handle = dlopen(path, RTLD_LAZY); + } + + if (!handle) { + sprintf(path, "%s/libipt_%s.so", lib_dir , lname); + handle = dlopen(path, RTLD_LAZY); + } + /* ok, lets give up .. */ if (!handle) { fputs(dlerror(), stderr); printf("\n");