Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2

This commit is contained in:
Stephen Hemminger 2008-07-08 15:58:07 -07:00
commit f63bb3e4ad
27 changed files with 320 additions and 151 deletions

View File

@ -56,6 +56,7 @@ install: all
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/rtstat.8
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/ctstat.8
ln -sf rtacct.8 $(DESTDIR)$(MANDIR)/man8/nstat.8
ln -sf routel.8 $(DESTDIR)$(MANDIR)/man8/routef.8
install -m 0755 -d $(DESTDIR)$(MANDIR)/man3
install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3

View File

@ -294,6 +294,10 @@ broadcast address will break networking.
Do not use it, if you do not understand what this operation really does.
\end{NB}
\item \verb|netns PID|
--- move the device to the network namespace associated with the process PID.
\end{itemize}
\vskip 1mm

View File

@ -19,6 +19,7 @@
#include <linux/atmapi.h>
#include <linux/atmsap.h>
#include <linux/atmioc.h>
#include <linux/types.h>
/* general ATM constants */
@ -207,7 +208,7 @@ struct sockaddr_atmsvc {
char pub[ATM_E164_LEN+1]; /* public address (E.164) */
/* unused addresses must be bzero'ed */
char lij_type; /* role in LIJ call; one of ATM_LIJ* */
uint32_t lij_id; /* LIJ call identifier */
__u32 lij_id; /* LIJ call identifier */
} sas_addr __ATM_API_ALIGN; /* SVC address */
};

View File

@ -7,6 +7,10 @@
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
#define GRE_CSUM __constant_htons(0x8000)
#define GRE_ROUTING __constant_htons(0x4000)
@ -17,9 +21,6 @@
#define GRE_FLAGS __constant_htons(0x00F8)
#define GRE_VERSION __constant_htons(0x0007)
/* i_flags values for SIT mode */
#define SIT_ISATAP 0x0001
struct ip_tunnel_parm
{
char name[IFNAMSIZ];
@ -31,4 +32,19 @@ struct ip_tunnel_parm
struct iphdr iph;
};
/* SIT-mode i_flags */
#define SIT_ISATAP 0x0001
struct ip_tunnel_prl {
__be32 addr;
__u16 flags;
__u16 __reserved;
__u32 datalen;
__u32 __reserved2;
/* data follows */
};
/* PRL flags */
#define PRL_DEFAULT 0x0001
#endif /* _IF_TUNNEL_H_ */

View File

@ -1,6 +1,7 @@
#ifndef __LINUX_NETFILTER_H
#define __LINUX_NETFILTER_H
#include <linux/types.h>
/* Responses from hook functions. */
#define NF_DROP 0

View File

@ -60,8 +60,6 @@ enum nf_ip_hook_priorities {
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
};

View File

@ -246,6 +246,7 @@ enum rt_class_t
{
RT_TABLE_UNSPEC=0,
/* User defined values */
RT_TABLE_COMPAT=252,
RT_TABLE_DEFAULT=253,
RT_TABLE_MAIN=254,
RT_TABLE_LOCAL=255,
@ -267,10 +268,10 @@ enum rtattr_type_t
RTA_PREFSRC,
RTA_METRICS,
RTA_MULTIPATH,
RTA_PROTOINFO,
RTA_PROTOINFO, /* no longer used */
RTA_FLOW,
RTA_CACHEINFO,
RTA_SESSION,
RTA_SESSION, /* no longer used */
RTA_MP_ALGO, /* no longer used */
RTA_TABLE,
__RTA_MAX

View File

@ -162,11 +162,4 @@ typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};
#endif /* _LINUX_TYPES_H */

View File

@ -97,10 +97,10 @@ struct xfrm_algo {
};
struct xfrm_algo_aead {
char alg_name[64];
int alg_key_len; /* in bits */
int alg_icv_len; /* in bits */
char alg_key[0];
char alg_name[64];
unsigned int alg_key_len; /* in bits */
unsigned int alg_icv_len; /* in bits */
char alg_key[0];
};
struct xfrm_stats {
@ -113,7 +113,8 @@ enum
{
XFRM_POLICY_TYPE_MAIN = 0,
XFRM_POLICY_TYPE_SUB = 1,
XFRM_POLICY_TYPE_MAX = 2
XFRM_POLICY_TYPE_MAX = 2,
XFRM_POLICY_TYPE_ANY = 255
};
enum

View File

@ -49,6 +49,7 @@ void iplink_usage(void)
fprintf(stderr, " name NEWNAME |\n");
fprintf(stderr, " address LLADDR | broadcast LLADDR |\n");
fprintf(stderr, " mtu MTU }\n");
fprintf(stderr, " netns PID }\n");
fprintf(stderr, " ip link show [ DEVICE ]\n");
exit(-1);
}
@ -156,6 +157,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
char abuf[32];
int qlen = -1;
int mtu = -1;
int netns = -1;
ret = argc;
@ -197,6 +199,13 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
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, "netns") == 0) {
NEXT_ARG();
if (netns != -1)
duparg("netns", *argv);
if (get_integer(&netns, *argv, 0))
invarg("Invalid \"netns\" value\n", *argv);
addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
} else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG();
req->i.ifi_change |= IFF_MULTICAST;

View File

@ -272,10 +272,9 @@ int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " router");
}
if (tb[NDA_CACHEINFO] && show_stats) {
static int hz;
struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
if (!hz)
hz = get_hz();
int hz = get_user_hz();
if (ci->ndm_refcnt)
printf(" ref %d", ci->ndm_refcnt);
fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,

View File

@ -57,7 +57,8 @@ static void usage(void)
{
fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ XFRM_OPT ] [ mode MODE ]\n");
fprintf(stderr, " [ reqid REQID ] [ seq SEQ ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n");
fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ LIMIT-LIST ]\n");
fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ replay-seq SEQ ]\n");
fprintf(stderr, " [ replay-oseq SEQ ] [ LIMIT-LIST ]\n");
fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ reqid REQID ] [ seq SEQ ]\n");
fprintf(stderr, " [ min SPI max SPI ]\n");
fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n");
@ -232,6 +233,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
struct xfrm_usersa_info xsinfo;
char buf[RTA_BUF_SIZE];
} req;
struct xfrm_replay_state replay;
char *idp = NULL;
char *ealgop = NULL;
char *aalgop = NULL;
@ -239,6 +241,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
char *coap = NULL;
memset(&req, 0, sizeof(req));
memset(&replay, 0, sizeof(replay));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
@ -264,6 +267,14 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
NEXT_ARG();
if (get_u8(&req.xsinfo.replay_window, *argv, 0))
invarg("\"replay-window\" value is invalid", *argv);
} else if (strcmp(*argv, "replay-seq") == 0) {
NEXT_ARG();
if (get_u32(&replay.seq, *argv, 0))
invarg("\"replay-seq\" value is invalid", *argv);
} else if (strcmp(*argv, "replay-oseq") == 0) {
NEXT_ARG();
if (get_u32(&replay.oseq, *argv, 0))
invarg("\"replay-oseq\" value is invalid", *argv);
} else if (strcmp(*argv, "flag") == 0) {
NEXT_ARG();
xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv);
@ -386,6 +397,10 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
argc--; argv++;
}
if (replay.seq || replay.oseq)
addattr_l(&req.n, sizeof(req.buf), XFRMA_REPLAY_VAL,
(void *)&replay, sizeof(replay));
if (!idp) {
fprintf(stderr, "Not enough information: \"ID\" is required\n");
exit(1);

View File

@ -246,10 +246,6 @@ int get_s8(__s8 *val, const char *arg, int base)
int get_addr_1(inet_prefix *addr, const char *name, int family)
{
const char *cp;
unsigned char *ap = (unsigned char*)addr->data;
int i;
memset(addr, 0, sizeof(*addr));
if (strcmp(name, "default") == 0 ||
@ -288,17 +284,10 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
addr->family = AF_INET;
if (family != AF_UNSPEC && family != AF_INET)
return -1;
if (inet_pton(AF_INET, name, addr->data) <= 0)
return -1;
addr->bytelen = 4;
addr->bitlen = -1;
for (cp=name, i=0; *cp; cp++) {
if (*cp <= '9' && *cp >= '0') {
ap[i] = 10*ap[i] + (*cp-'0');
continue;
}
if (*cp == '.' && ++i <= 3)
continue;
return -1;
}
return 0;
}
@ -518,13 +507,14 @@ const char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen
struct namerec
{
struct namerec *next;
const char *name;
inet_prefix addr;
char *name;
};
static struct namerec *nht[256];
#define NHASH 257
static struct namerec *nht[NHASH];
char *resolve_address(const char *addr, int len, int af)
static const char *resolve_address(const void *addr, int len, int af)
{
struct namerec *n;
struct hostent *h_ent;
@ -539,7 +529,7 @@ char *resolve_address(const char *addr, int len, int af)
len = 4;
}
hash = addr[len-1] ^ addr[len-2] ^ addr[len-3] ^ addr[len-4];
hash = *(__u32 *)(addr + len - 4) % NHASH;
for (n = nht[hash]; n; n = n->next) {
if (n->addr.family == af &&
@ -573,7 +563,8 @@ const char *format_host(int af, int len, const void *addr,
{
#ifdef RESOLVE_HOSTNAMES
if (resolve_hosts) {
char *n;
const char *n;
if (len <= 0) {
switch (af) {
case AF_INET:

View File

@ -50,7 +50,10 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.IR LLADDR " |"
.br
.B mtu
.IR MTU " }"
.IR MTU " |"
.br
.B netns
.IR PID " }"
.ti -8
.B ip link show
@ -873,6 +876,11 @@ change the link layer broadcast address or the peer address when
the interface is
.IR "POINTOPOINT" .
.TP
.BI netns " PID"
move the device to the network namespace associated with the process
.IR "PID" .
.PP
.B Warning:
If multiple parameter changes are requested,

32
man/man8/routel.8 Normal file
View File

@ -0,0 +1,32 @@
.TH "ROUTEL" "8" "3 Jan, 2008" "iproute2" "Linux"
.SH "NAME"
.LP
routel \- list routes with pretty output format
.br
routef \- flush routes
.SH "SYNTAX"
.LP
routel [\fItablenr\fP [\fIraw ip args...\fP]]
.br
routef
.SH "DESCRIPTION"
.LP
These programs are a set of helper scripts you can use instead of raw iproute2 commands.
.br
The routel script will list routes in a format that some might consider easier to interpret then the ip route list equivalent.
.br
The routef script does not take any arguments and will simply flush the routing table down the drain. Beware! This means deleting all routes which will make your network unusable!
.SH "FILES"
.LP
\fI/usr/bin/routef\fP
.br
\fI/usr/bin/routel\fP
.SH "AUTHORS"
.LP
The routel script was written by Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18 and donated to the public domain.
.br
This manual page was written by Andreas Henriksson <andreas@fatal.se>, for the Debian GNU/Linux system.
.SH "SEE ALSO"
.LP
ip(8)

View File

@ -34,16 +34,28 @@ priority filtertype
.B flowid
flow-id
.B tc [-s | -d ] qdisc show [ dev
.B tc
.RI "[ " FORMAT " ]"
.B qdisc show [ dev
DEV
.B ]
.P
.B tc [-s | -d ] class show dev
.B tc
.RI "[ " FORMAT " ]"
.B class show dev
DEV
.P
.B tc filter show dev
DEV
.ti -8
.IR FORMAT " := {"
\fB\-s\fR[\fItatistics\fR] |
\fB\-d\fR[\fIetails\fR] |
\fB\-r\fR[\fIaw\fR] |
\fB\-p\fR[\fIretty\fR] |
\fB\i\fR[\fIec\fR] }
.SH DESCRIPTION
.B Tc
is used to configure Traffic Control in the Linux kernel. Traffic Control consists
@ -326,6 +338,29 @@ link
Only available for qdiscs and performs a replace where the node
must exist already.
.SH FORMAT
The show command has additional formatting options:
.TP
.BR "\-s" , " \-stats", " \-statistics"
output more statistics about packet usage.
.TP
.BR "\-d", " \-details"
output more detailed information about rates and cell sizes.
.TP
.BR "\-r", " \-raw"
output raw hex values for handles.
.TP
.BR "\-p", " \-pretty"
decode filter offset and mask values to equivalent filter commands based on TCP/IP.
.TP
.BR "\-iec"
print rates in IEC units (ie. 1K = 1024).
.SH HISTORY
.B tc

View File

@ -17,7 +17,7 @@
*/
/* Maximum number of fields that can be displayed */
#define MAX_FIELDS 64
#define MAX_FIELDS 128
/* Maximum number of header lines */
#define HDR_LINES 10
@ -121,9 +121,17 @@ static int map_field_params(struct lnstat_file *lnstat_files,
if (!fps->params[j].print.width)
fps->params[j].print.width =
FIELD_WIDTH_DEFAULT;
j++;
if (++j >= MAX_FIELDS - 1) {
fprintf(stderr,
"WARN: MAX_FIELDS (%d) reached,"
" truncating number of keys\n",
MAX_FIELDS);
goto full;
}
}
}
full:
fps->num = j;
return 1;
}
@ -269,8 +277,13 @@ int main(int argc, char **argv)
for (tok = strtok(tmp, ",");
tok;
tok = strtok(NULL, ",")) {
if (fp.num >= MAX_FIELDS)
if (fp.num >= MAX_FIELDS) {
fprintf(stderr,
"WARN: too many keys"
" requested: (%d max)\n",
MAX_FIELDS);
break;
}
fp.params[fp.num++].name = tok;
}
break;

View File

@ -43,7 +43,7 @@ int npatterns;
char info_source[128];
int source_mismatch;
int generic_proc_open(char *env, char *name)
static int generic_proc_open(const char *env, char *name)
{
char store[128];
char *p = getenv(env);
@ -52,7 +52,7 @@ int generic_proc_open(char *env, char *name)
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
p = store;
}
return open(store, O_RDONLY);
return open(p, O_RDONLY);
}
int net_netstat_open(void)

View File

@ -43,7 +43,7 @@ int dump_zeros = 0;
unsigned long magic_number = 0;
double W;
int generic_proc_open(char *env, char *name)
static int generic_proc_open(const char *env, const char *name)
{
char store[1024];
char *p = getenv(env);
@ -52,7 +52,7 @@ int generic_proc_open(char *env, char *name)
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
p = store;
}
return open(store, O_RDONLY);
return open(p, O_RDONLY);
}
int net_rtacct_open(void)

View File

@ -420,7 +420,7 @@ const char *print_ms_timer(int timeout)
const char *print_hz_timer(int timeout)
{
int hz = get_hz();
int hz = get_user_hz();
return print_ms_timer(((timeout*1000) + hz-1)/hz);
}
@ -1191,10 +1191,11 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
}
}
if (show_tcpinfo) {
if (s.rto && s.rto != 3*get_hz())
printf(" rto:%g", (double)s.rto/get_hz());
int hz = get_user_hz();
if (s.rto && s.rto != 3*hz)
printf(" rto:%g", (double)s.rto/hz);
if (s.ato)
printf(" ato:%g", (double)s.ato/get_hz());
printf(" ato:%g", (double)s.ato/hz);
if (s.cwnd != 2)
printf(" cwnd:%d", s.cwnd);
if (s.ssthresh != -1)

View File

@ -2,6 +2,7 @@ DISTGEN = maketable normal pareto paretonormal
DISTDATA = normal.dist pareto.dist paretonormal.dist experimental.dist
HOSTCC ?= $(CC)
CCOPTS = $(CBUILD_CFLAGS)
LDLIBS += -lm
all: $(DISTGEN) $(DISTDATA)

View File

@ -21,10 +21,13 @@
#include <arpa/inet.h>
#include <string.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include "utils.h"
#include "tc_util.h"
extern int show_pretty;
static void explain(void)
{
fprintf(stderr, "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ]"
@ -789,27 +792,24 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
return 0;
}
static void show_key(FILE *f, const struct tc_u32_key *key)
static void print_ipv4(FILE *f, const struct tc_u32_key *key)
{
char abuf[256];
if (show_raw)
goto raw;
switch (key->off) {
case 0:
switch (ntohl(key->mask)) {
case 0x0f000000:
fprintf(f, "\n ihl %u", ntohl(key->val) >> 24);
fprintf(f, "\n match IP ihl %u", ntohl(key->val) >> 24);
return;
case 0x00ff0000:
fprintf(f, "\n dsfield %#x", ntohl(key->val) >> 16);
fprintf(f, "\n match IP dsfield %#x", ntohl(key->val) >> 16);
return;
}
break;
case 8:
if (ntohl(key->mask) == 0x00ff0000) {
fprintf(f, "\n protocol %u", ntohl(key->val) >> 16);
fprintf(f, "\n match IP protocol %d", ntohl(key->val) >> 16);
return;
}
break;
@ -818,7 +818,7 @@ static void show_key(FILE *f, const struct tc_u32_key *key)
int bits = mask2bits(key->mask);
if (bits >= 0) {
fprintf(f, "\n %s %s/%d",
key->off == 12 ? "src" : "dst",
key->off == 12 ? "match IP src" : "match IP dst",
inet_ntop(AF_INET, &key->val,
abuf, sizeof(abuf)),
bits);
@ -830,31 +830,62 @@ static void show_key(FILE *f, const struct tc_u32_key *key)
case 20:
switch (ntohl(key->mask)) {
case 0x0000ffff:
fprintf(f, "\n sport %u",
fprintf(f, "\n match sport %u",
ntohl(key->val) & 0xffff);
return;
case 0xffff0000:
fprintf(f, "\n dport %u",
fprintf(f, "\n match dport %u",
ntohl(key->val) >> 16);
return;
case 0xffffffff:
fprintf(f, "\n sport %u, dport %u",
fprintf(f, "\n match sport %u, match dport %u",
ntohl(key->val) & 0xffff,
ntohl(key->val) >> 16);
return;
}
/* XXX: Default print_raw */
}
}
raw:
fprintf(f, "\n match %08x/%08x at %s%d",
static void print_raw(FILE *f, const struct tc_u32_key *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);
}
static int u32_parse_opt(struct filter_util *qu, char *handle,
static const struct {
__u16 proto;
__u16 pad;
void (*pprinter)(FILE *f, const struct tc_u32_key *key);
} u32_pprinters[] = {
{0, 0, print_raw},
{ETH_P_IP, 0, print_ipv4},
};
static void show_keys(FILE *f, const struct tc_u32_key *key)
{
int i = 0;
if (!show_pretty)
goto show_k;
for (i = 0; i < sizeof(u32_pprinters) / sizeof(u32_pprinters[0]); i++) {
if (u32_pprinters[i].proto == ntohs(f_proto)) {
show_k:
u32_pprinters[i].pprinter(f, key);
return;
}
}
i = 0;
goto show_k;
}
static int u32_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{
struct {
@ -1129,7 +1160,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
if (sel->nkeys) {
int i;
for (i=0; i<sel->nkeys; i++) {
show_key(f, sel->keys + i);
show_keys(f, sel->keys + i);
if (show_stats && NULL != pf)
fprintf(f, " (success %llu ) ",
(unsigned long long) pf->kcnts[i]);

View File

@ -491,3 +491,80 @@ int print_ematch(FILE *fd, const struct rtattr *rta)
return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
}
struct bstr * bstr_alloc(const char *text)
{
struct bstr *b = calloc(1, sizeof(*b));
if (b == NULL)
return NULL;
b->data = strdup(text);
if (b->data == NULL) {
free(b);
return NULL;
}
b->len = strlen(text);
return b;
}
unsigned long bstrtoul(const struct bstr *b)
{
char *inv = NULL;
unsigned long l;
char buf[b->len+1];
memcpy(buf, b->data, b->len);
buf[b->len] = '\0';
l = strtoul(buf, &inv, 0);
if (l == ULONG_MAX || inv == buf)
return ULONG_MAX;
return l;
}
void bstr_print(FILE *fd, const struct bstr *b, int ascii)
{
int i;
char *s = b->data;
if (ascii)
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
else {
for (i = 0; i < b->len; i++)
fprintf(fd, "%02x", s[i]);
fprintf(fd, "\"");
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
fprintf(fd, "\"");
}
}
void print_ematch_tree(const struct ematch *tree)
{
const struct ematch *t;
for (t = tree; t; t = t->next) {
if (t->inverted)
printf("NOT ");
if (t->child) {
printf("(");
print_ematch_tree(t->child);
printf(")");
} else {
struct bstr *b;
for (b = t->args; b; b = b->next)
printf("%s%s", b->data, b->next ? " " : "");
}
if (t->relation == TCF_EM_REL_AND)
printf(" AND ");
else if (t->relation == TCF_EM_REL_OR)
printf(" OR ");
}
}

View File

@ -18,23 +18,7 @@ struct bstr
struct bstr *next;
};
static inline struct bstr * bstr_alloc(const char *text)
{
struct bstr *b = calloc(1, sizeof(*b));
if (b == NULL)
return NULL;
b->data = strdup(text);
if (b->data == NULL) {
free(b);
return NULL;
}
b->len = strlen(text);
return b;
}
extern struct bstr * bstr_alloc(const char *text);
static inline struct bstr * bstr_new(char *data, unsigned int len)
{
@ -60,45 +44,15 @@ static inline int bstrcmp(struct bstr *b, const char *text)
return d;
}
static inline unsigned long bstrtoul(struct bstr *b)
{
char *inv = NULL;
unsigned long l;
char buf[b->len+1];
memcpy(buf, b->data, b->len);
buf[b->len] = '\0';
l = strtol(buf, &inv, 0);
if (l == ULONG_MAX || inv == buf)
return LONG_MAX;
return l;
}
static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
{
int i;
char *s = b->data;
if (ascii)
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
else {
for (i = 0; i < b->len; i++)
fprintf(fd, "%02x", s[i]);
fprintf(fd, "\"");
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
fprintf(fd, "\"");
}
}
static inline struct bstr *bstr_next(struct bstr *b)
{
return b->next;
}
extern unsigned long bstrtoul(const struct bstr *b);
extern void bstr_print(FILE *fd, const struct bstr *b, int ascii);
struct ematch
{
struct bstr *args;
@ -123,30 +77,8 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted)
return e;
}
static inline void print_ematch_tree(struct ematch *tree)
{
struct ematch *t;
extern void print_ematch_tree(const struct ematch *tree);
for (t = tree; t; t = t->next) {
if (t->inverted)
printf("NOT ");
if (t->child) {
printf("(");
print_ematch_tree(t->child);
printf(")");
} else {
struct bstr *b;
for (b = t->args; b; b = b->next)
printf("%s%s", b->data, b->next ? " " : "");
}
if (t->relation == TCF_EM_REL_AND)
printf(" AND ");
else if (t->relation == TCF_EM_REL_OR)
printf(" OR ");
}
}
struct ematch_util
{

View File

@ -33,6 +33,8 @@
int show_stats = 0;
int show_details = 0;
int show_raw = 0;
int show_pretty = 0;
int resolve_hosts = 0;
int use_iec = 0;
int force = 0;
@ -182,7 +184,7 @@ static void usage(void)
fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
" tc [-force] -batch file\n"
"where OBJECT := { qdisc | class | filter | action | monitor }\n"
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] [file] }\n");
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [file] }\n");
}
static int do_cmd(int argc, char **argv)
@ -273,6 +275,8 @@ int main(int argc, char **argv)
++show_details;
} else if (matches(argv[1], "-raw") == 0) {
++show_raw;
} else if (matches(argv[1], "-pretty") == 0) {
++show_pretty;
} else if (matches(argv[1], "-Version") == 0) {
printf("tc utility, iproute2-ss%s\n", SNAPSHOT);
return 0;

View File

@ -54,7 +54,7 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)
} req;
struct filter_util *q = NULL;
__u32 prio = 0;
__u32 protocol = ETH_P_ALL;
__u32 protocol = 0;
int protocol_set = 0;
char *fhandle = NULL;
char d[16];
@ -72,6 +72,9 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)
req.n.nlmsg_type = cmd;
req.t.tcm_family = AF_UNSPEC;
if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE)
protocol = ETH_P_ALL;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
@ -175,6 +178,7 @@ static __u32 filter_parent;
static int filter_ifindex;
static __u32 filter_prio;
static __u32 filter_protocol;
__u16 f_proto = 0;
int print_filter(const struct sockaddr_nl *who,
struct nlmsghdr *n,
@ -221,13 +225,13 @@ int print_filter(const struct sockaddr_nl *who,
}
}
if (t->tcm_info) {
__u32 protocol = TC_H_MIN(t->tcm_info);
f_proto = TC_H_MIN(t->tcm_info);
__u32 prio = TC_H_MAJ(t->tcm_info)>>16;
if (!filter_protocol || filter_protocol != protocol) {
if (protocol) {
if (!filter_protocol || filter_protocol != f_proto) {
if (f_proto) {
SPRINT_BUF(b1);
fprintf(fp, "protocol %s ",
ll_proto_n2a(protocol, b1, sizeof(b1)));
ll_proto_n2a(f_proto, b1, sizeof(b1)));
}
}
if (!filter_prio || filter_prio != prio) {

View File

@ -19,6 +19,7 @@ struct qdisc_util
int (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
};
extern __u16 f_proto;
struct filter_util
{
struct filter_util *next;