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..56a58ac0 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static char SNAPSHOT[] = "071016"; +static const char SNAPSHOT[] = "071231"; 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< 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) { 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); } diff --git a/ip/link_veth.c b/ip/link_veth.c index a4764f2e..9f5e8715 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -10,78 +10,51 @@ * */ -#include #include +#include +#include #include "utils.h" #include "ip_common.h" -#include "veth.h" - -#define ETH_ALEN 6 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) + 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/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/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 diff --git a/misc/ss.c b/misc/ss.c index 5d14f132..53558515 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -33,9 +33,8 @@ #include "libnetlink.h" #include "SNAPSHOT.h" +#include #include -#include -#include int resolve_hosts = 0; int resolve_services = 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]); } } diff --git a/tc/m_ipt.c b/tc/m_ipt.c index 1539dc18..042fe8b8 100644 --- a/tc/m_ipt.c +++ b/tc/m_ipt.c @@ -69,6 +69,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) { @@ -249,11 +256,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"); 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 53e3f787..e24ad6de 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,23 +207,23 @@ 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; - if ((cell_log = tc_calc_rtable(opt.rate.rate, rtab, cell_log, mtu, mpu)) < 0) { + opt.ceil.mpu = mpu; + opt.rate.mpu = mpu; + + 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 1365e081..9ae4d8e5 100644 --- a/tc/tc_core.c +++ b/tc/tc_core.c @@ -69,12 +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 overhead = (mpu >> 8) & 0xFF; - mpu = mpu & 0xFF; + unsigned bps = r->rate; + unsigned mpu = r->mpu; if (mtu == 0) mtu = 2047; @@ -85,13 +84,13 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, 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; } 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);