Commit 4c7abb27 authored by Stephen Hemminger's avatar Stephen Hemminger

Merge branch 'master' into net-2.6.25

parents c1b81cb5 53c01788
......@@ -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; \
......
static char SNAPSHOT[] = "071016";
static const char SNAPSHOT[] = "071231";
/*
* 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, <waltje@uWalt.NL.Mugnet.ORG>
*
* 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 <linux/types.h>
#include <asm/byteorder.h>
#include <linux/socket.h>
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 <asm/byteorder.h> 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<<TCP_CA_Open)
TCP_CA_Disorder = 1,
#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
TCP_CA_CWR = 2,
#define TCPF_CA_CWR (1<<TCP_CA_CWR)
TCP_CA_Recovery = 3,
#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
TCP_CA_Loss = 4
#define TCPF_CA_Loss (1<<TCP_CA_Loss)
};
struct tcp_info
{
__u8 tcpi_state;
__u8 tcpi_ca_state;
__u8 tcpi_retransmits;
__u8 tcpi_probes;
__u8 tcpi_backoff;
__u8 tcpi_options;
__u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
__u32 tcpi_rto;
__u32 tcpi_ato;
__u32 tcpi_snd_mss;
__u32 tcpi_rcv_mss;
__u32 tcpi_unacked;
__u32 tcpi_sacked;
__u32 tcpi_lost;
__u32 tcpi_retrans;
__u32 tcpi_fackets;
/* Times. */
__u32 tcpi_last_data_sent;
__u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
__u32 tcpi_last_data_recv;
__u32 tcpi_last_ack_recv;
/* Metrics. */
__u32 tcpi_pmtu;
__u32 tcpi_rcv_ssthresh;
__u32 tcpi_rtt;
__u32 tcpi_rttvar;
__u32 tcpi_snd_ssthresh;
__u32 tcpi_snd_cwnd;
__u32 tcpi_advmss;
__u32 tcpi_reordering;
__u32 tcpi_rcv_rtt;
__u32 tcpi_rcv_space;
__u32 tcpi_total_retrans;
};
/* for TCP_MD5SIG socket option */
#define TCP_MD5SIG_MAXKEYLEN 80
struct tcp_md5sig {
struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
__u16 __tcpm_pad1; /* zero */
__u16 tcpm_keylen; /* key length */
__u32 __tcpm_pad2; /* zero */
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
};
#endif /* _LINUX_TCP_H */
#ifndef __NET_VETH_H__
#define __NET_VETH_H__
#ifndef __NET_VETH_H_
#define __NET_VETH_H_
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)
......
/*
* 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 sk_state field.
*
* 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_STATES_H
#define _LINUX_TCP_STATES_H
enum {
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING, /* Now a valid state */
TCP_MAX_STATES /* Leave at the end! */
};
#define TCP_STATE_MASK 0xF
#define TCP_ACTION_FIN (1 << 7)
enum {
TCPF_ESTABLISHED = (1 << 1),
TCPF_SYN_SENT = (1 << 2),
TCPF_SYN_RECV = (1 << 3),
TCPF_FIN_WAIT1 = (1 << 4),
TCPF_FIN_WAIT2 = (1 << 5),
TCPF_TIME_WAIT = (1 << 6),
TCPF_CLOSE = (1 << 7),
TCPF_CLOSE_WAIT = (1 << 8),
TCPF_LAST_ACK = (1 << 9),
TCPF_LISTEN = (1 << 10),
TCPF_CLOSING = (1 << 11)
};
#endif /* _LINUX_TCP_STATES_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);
......@@ -147,4 +148,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__ */
......@@ -24,3 +24,5 @@ clean:
rm -f $(ALLOBJ) $(TARGETS)
LDLIBS += -ldl
LDFLAGS += -Wl,-export-dynamic
......@@ -143,52 +143,44 @@ static int iplink_have_newlink(void)
}
#endif /* ! IPLINK_IOCTL_COMPAT */
static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
{
int qlen = -1;
int mtu = -1;
int len;
char abuf[32];
char *dev = NULL;
char *name = NULL;
char *link = NULL;
char *type = NULL;
struct link_util *lu = NULL;
struct {
struct iplink_req {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
} req;
};
memset(&req, 0, sizeof(req));
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;
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.i.ifi_family = preferred_family;
ret = argc;
while (argc > 0) {
if (strcmp(*argv, "up") == 0) {
req.i.ifi_change |= IFF_UP;
req.i.ifi_flags |= IFF_UP;
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;
req->i.ifi_change |= IFF_UP;
req->i.ifi_flags &= ~IFF_UP;
} else if (strcmp(*argv, "name") == 0) {
NEXT_ARG();
name = *argv;
*name = *argv;
} else if (matches(*argv, "link") == 0) {
NEXT_ARG();
link = *argv;
*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);
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);
addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
} else if (matches(*argv, "txqueuelen") == 0 ||
strcmp(*argv, "qlen") == 0 ||
matches(*argv, "txqlen") == 0) {
......@@ -197,86 +189,113 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
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);
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);
addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
} else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG();
req.i.ifi_change |= IFF_MULTICAST;
req->i.ifi_change |= IFF_MULTICAST;
if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_MULTICAST;
req->i.ifi_flags |= IFF_MULTICAST;
} else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_MULTICAST;
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;
req->i.ifi_change |= IFF_ALLMULTI;
if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_ALLMULTI;
req->i.ifi_flags |= IFF_ALLMULTI;
} else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_ALLMULTI;
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;
req->i.ifi_change |= IFF_PROMISC;
if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_PROMISC;
req->i.ifi_flags |= IFF_PROMISC;
} else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_PROMISC;
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;
req->i.ifi_change |= IFF_NOTRAILERS;
if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags |= IFF_NOTRAILERS;
req->i.ifi_flags |= IFF_NOTRAILERS;
} else if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags &= ~IFF_NOTRAILERS;
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;
req->i.ifi_change |= IFF_NOARP;
if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags &= ~IFF_NOARP;
req->i.ifi_flags &= ~IFF_NOARP;
} else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags |= IFF_NOARP;
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;
req->i.ifi_change |= IFF_DYNAMIC;
if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_DYNAMIC;
req->i.ifi_flags |= IFF_DYNAMIC;
} else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_DYNAMIC;
req->i.ifi_flags &= ~IFF_DYNAMIC;
} else
return on_off("dynamic");
#endif
} else if (matches(*argv, "type") == 0) {
NEXT_ARG();
type = *argv;
*type = *argv;
argc--; argv++;
break;
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
}
if (dev)
if (*dev)
duparg2("dev", *argv);
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 *dev = NULL;
char *name = NULL;
char *link = NULL;
char *type = NULL;
struct link_util *lu = NULL;
struct iplink_req req;
int ret;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.i.ifi_family = preferred_family;
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) {
......
......@@ -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);
}
......
......@@ -10,78 +10,51 @@
*
*/
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <linux/veth.h>
#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 <peer-name>] [mac <mac>] [peer_mac <mac>]\n");
printf("Usage: ip link <options> type veth "
"[peer <options>]\nTo get <options> 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];
char *name, *type, *link, *dev;
int err, len;
struct rtattr * data;
for (; argc != 0; argv++, argc--) {
if (strcmp(*argv, "peer") == 0) {
argv++;
argc--;
if (argc == 0) {
if (strcmp(argv[0], "peer") != 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;
}
data = NLMSG_TAIL(hdr);
addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0);
if (hexstring_a2n(*argv, mac, sizeof(mac)) == NULL)
return -1;
hdr->nlmsg_len += sizeof(struct ifinfomsg);
addattr_l(hdr, 1024, VETH_INFO_MAC,
mac, ETH_ALEN);
continue;
}
err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
&name, &type, &link, &dev);
if (err < 0)
return err;
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;
}
usage();
return -1;
if (name) {
len = strlen(name) + 1;
if (len > IFNAMSIZ)
invarg("\"name\" too long\n", *argv);
addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
}
return 0;
data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data;
return argc - 1 - err;
}
struct link_util veth_link_util = {
......
......@@ -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)
++bits;
/* 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))
return 0;
if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) {
int b = mask2bits(addr.data[0]);
*val = cidr(&addr);
if (b >= 0) {
*val = b;
return 0;
}
}
return -1;
......
......@@ -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
......
......@@ -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
......
......@@ -33,9 +33,8 @@
#include "libnetlink.h"
#include "SNAPSHOT.h"
#include <netinet/tcp.h>
#include <linux/inet_diag.h>
#include <linux/tcp.h>
#include <net/tcp_states.h>
int resolve_hosts = 0;
int resolve_services = 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; i<sel->nkeys; 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; i<sel->nkeys; 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]);
}
}
......
......@@ -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) {
/* 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, lib_dir, "/libipt_%s.so", lname);
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");
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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_log);
if (overhead)
sz += overhead;
unsigned sz = ((i+1)<<cell_log);
if (sz < mpu)
sz = mpu;
rtab[i] = tc_calc_xmittime(bps, sz);
}
r->cell_align=-1; // Due to the sz calc
r->cell_log=cell_log;
return cell_log;
}
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment