Merge branch 'master' into net-next
This commit is contained in:
commit
86c392f958
|
|
@ -263,4 +263,3 @@ int do_ipaddrlabel(int argc, char **argv)
|
||||||
fprintf(stderr, "Command \"%s\" is unknown, try \"ip addrlabel help\".\n", *argv);
|
fprintf(stderr, "Command \"%s\" is unknown, try \"ip addrlabel help\".\n", *argv);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,4 +156,3 @@ int do_ipfou(int argc, char **argv)
|
||||||
fprintf(stderr, "Command \"%s\" is unknown, try \"ip fou help\".\n", *argv);
|
fprintf(stderr, "Command \"%s\" is unknown, try \"ip fou help\".\n", *argv);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,4 +113,3 @@ struct link_util bond_slave_link_util = {
|
||||||
.parse_opt = bond_slave_parse_opt,
|
.parse_opt = bond_slave_parse_opt,
|
||||||
.slave = true,
|
.slave = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,4 +107,3 @@ int print_prefix(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1842,4 +1842,3 @@ int do_iproute(int argc, char **argv)
|
||||||
fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv);
|
fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -508,4 +508,3 @@ int do_tcp_metrics(int argc, char **argv)
|
||||||
"try \"ip tcp_metrics help\".\n", *argv);
|
"try \"ip tcp_metrics help\".\n", *argv);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 rtpr.8 ss.
|
||||||
ip-netns.8 ip-ntable.8 ip-rule.8 ip-tunnel.8 ip-xfrm.8 \
|
ip-netns.8 ip-ntable.8 ip-rule.8 ip-tunnel.8 ip-xfrm.8 \
|
||||||
ip-tcp_metrics.8 ip-netconf.8 ip-token.8 \
|
ip-tcp_metrics.8 ip-netconf.8 ip-token.8 \
|
||||||
tipc.8 tipc-bearer.8 tipc-link.8 tipc-media.8 tipc-nametable.8 \
|
tipc.8 tipc-bearer.8 tipc-link.8 tipc-media.8 tipc-nametable.8 \
|
||||||
tipc-node.8 tipc-socket.8
|
tipc-node.8 tipc-socket.8 \
|
||||||
|
tc-basic.8 tc-cgroup.8 tc-flow.8 tc-flower.8 tc-fw.8 tc-route.8 \
|
||||||
|
tc-tcindex.8 tc-u32.8
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
.TH "Basic classifier in tc" 8 "21 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
basic \- basic traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " basic " [ " match
|
||||||
|
.IR EMATCH_TREE " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ] [ "
|
||||||
|
.B classid
|
||||||
|
.IR CLASSID " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B basic
|
||||||
|
filter allows to classify packets using the extended match infrastructure.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Push matching packets into the class identified by
|
||||||
|
.IR CLASSID .
|
||||||
|
.TP
|
||||||
|
.BI match " EMATCH_TREE"
|
||||||
|
Match packets using the extended match infrastructure. See
|
||||||
|
.BR tc-ematch (8)
|
||||||
|
for a detailed description of the allowed syntax in
|
||||||
|
.IR EMATCH_TREE .
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR tc-ematch (8)
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
.TH "Cgroup classifier in tc" 8 " 21 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
cgroup \- control group based traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " cgroup " [ " match
|
||||||
|
.IR EMATCH_TREE " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This filter serves as a hint to
|
||||||
|
.B tc
|
||||||
|
that the assigned class ID of the net_cls control group the process the packet
|
||||||
|
originates from belongs to should be used for classification. Obviously, it is
|
||||||
|
useful for locally generated packets only.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI match " EMATCH_TREE"
|
||||||
|
Match packets using the extended match infrastructure. See
|
||||||
|
.BR tc-ematch (8)
|
||||||
|
for a detailed description of the allowed syntax in
|
||||||
|
.IR EMATCH_TREE .
|
||||||
|
.SH EXAMPLES
|
||||||
|
In order to use this filter, a net_cls control group has to be created first and
|
||||||
|
class as well as process ID(s) assigned to it. The following creates a net_cls
|
||||||
|
cgroup named "foobar":
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
modprobe cls_cgroup
|
||||||
|
mkdir /sys/fs/cgroup/net_cls
|
||||||
|
mount -t cgroup -onet_cls net_cls /sys/fs/cgroup/net_cls
|
||||||
|
mkdir /sys/fs/cgroup/net_cls/foobar
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
To assign a class ID to the created cgroup, a file named
|
||||||
|
.I net_cls.classid
|
||||||
|
has to be created which contains the class ID to be assigned as a hexadecimal,
|
||||||
|
64bit wide number. The upper 32bits are reserved for the major handle, the
|
||||||
|
remaining hold the minor. So a class ID of e.g.
|
||||||
|
.B ff:be
|
||||||
|
has to be written like so:
|
||||||
|
.B 0xff00be
|
||||||
|
(leading zeroes may be omitted). To continue the above example, the following
|
||||||
|
assigns class ID 1:2 to foobar cgroup:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
echo 0x10002 > /sys/fs/cgroup/net_cls/foobar/net_cls.classid
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
Finally some PIDs can be assigned to the given cgroup:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
echo 1234 > /sys/fs/cgroup/net_cls/foobar/tasks
|
||||||
|
echo 5678 > /sys/fs/cgroup/net_cls/foobar/tasks
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
Now by simply attaching a
|
||||||
|
.B cgroup
|
||||||
|
filter to a
|
||||||
|
.B qdisc
|
||||||
|
makes packets from PIDs 1234 and 5678 be pushed into class 1:2.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR tc-ematch (8),
|
||||||
|
.br
|
||||||
|
the file
|
||||||
|
.I Documentation/cgroups/net_cls.txt
|
||||||
|
of the Linux kernel tree
|
||||||
|
|
@ -0,0 +1,265 @@
|
||||||
|
.TH "Flow filter in tc" 8 "20 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
flow \- flow based traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.TP
|
||||||
|
Mapping mode:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " "flow map key "
|
||||||
|
.IR KEY " [ " OPS " ] [ " OPTIONS " ] "
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
Hashing mode:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " "flow hash keys "
|
||||||
|
.IR KEY_LIST " [ "
|
||||||
|
.B perturb
|
||||||
|
.IR secs " ] [ " OPTIONS " ] "
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.IR OPS " := [ " OPS " ] " OP
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR OPTIONS " := [ "
|
||||||
|
.B divisor
|
||||||
|
.IR NUM " ] [ "
|
||||||
|
.B baseclass
|
||||||
|
.IR ID " ] [ "
|
||||||
|
.B match
|
||||||
|
.IR EMATCH_TREE " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR KEY_LIST " := [ " KEY_LIST " ] " KEY
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR OP " := { "
|
||||||
|
.BR or " | " and " | " xor " | " rshift " | " addend " } "
|
||||||
|
.I NUM
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR ID " := " X : Y
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR KEY " := { "
|
||||||
|
.BR src " | " dst " | " proto " | " proto-src " | " proto-dst " | " iif " | "
|
||||||
|
.BR priority " | " mark " | " nfct " | " nfct-src " | " nfct-dst " | "
|
||||||
|
.BR nfct-proto-src " | " nfct-proto-dst " | " rt-classid " | " sk-uid " | "
|
||||||
|
.BR sk-gid " | " vlan-tag " | " rxhash " }"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B flow
|
||||||
|
classifier is meant to extend the
|
||||||
|
.B SFQ
|
||||||
|
hashing capabilities without hard-coding new hash functions. It also allows
|
||||||
|
deterministic mappings of keys to classes.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI baseclass " ID"
|
||||||
|
An offset for the resulting class ID.
|
||||||
|
.I ID
|
||||||
|
may be
|
||||||
|
.BR root ", " none
|
||||||
|
or a hexadecimal class ID in the form [\fIX\fB:\fR]\fIY\fR. If \fIX\fR is
|
||||||
|
omitted, it is assumed to be zero.
|
||||||
|
.TP
|
||||||
|
.BI divisor " NUM"
|
||||||
|
Number of buckets to use for sorting into. Keys are calculated modulo
|
||||||
|
.IR NUM .
|
||||||
|
.TP
|
||||||
|
.BI "hash keys " KEY-LIST
|
||||||
|
Perform a
|
||||||
|
.B jhash2
|
||||||
|
operation over the keys in
|
||||||
|
.IR KEY-LIST ,
|
||||||
|
the result (modulo the
|
||||||
|
.B divisor
|
||||||
|
if given) is taken as class ID, optionally offset by the value of
|
||||||
|
.BR baseclass .
|
||||||
|
It is possible to specify an interval (in seconds) after which
|
||||||
|
.BR jhash2 's
|
||||||
|
entropy source is recreated using the
|
||||||
|
.B perturb
|
||||||
|
parameter.
|
||||||
|
.TP
|
||||||
|
.BI "map key " KEY
|
||||||
|
Packet data identified by
|
||||||
|
.I KEY
|
||||||
|
is translated into class IDs to push the packet into. The value may be mangled by
|
||||||
|
.I OPS
|
||||||
|
before using it for the mapping. They are applied in the order listed here:
|
||||||
|
.RS
|
||||||
|
.TP 4
|
||||||
|
.BI and " NUM"
|
||||||
|
Perform bitwise
|
||||||
|
.B AND
|
||||||
|
operation with numeric value
|
||||||
|
.IR NUM .
|
||||||
|
.TP
|
||||||
|
.BI or " NUM"
|
||||||
|
Perform bitwise
|
||||||
|
.B OR
|
||||||
|
operation with numeric value
|
||||||
|
.IR NUM .
|
||||||
|
.TP
|
||||||
|
.BI xor " NUM"
|
||||||
|
Perform bitwise
|
||||||
|
.B XOR
|
||||||
|
operation with numeric value
|
||||||
|
.IR NUM .
|
||||||
|
.TP
|
||||||
|
.BI rshift " NUM"
|
||||||
|
Shift the value of
|
||||||
|
.I KEY
|
||||||
|
to the right by
|
||||||
|
.I NUM
|
||||||
|
bits.
|
||||||
|
.TP
|
||||||
|
.BI addend " NUM"
|
||||||
|
Add
|
||||||
|
.I NUM
|
||||||
|
to the value of
|
||||||
|
.IR KEY .
|
||||||
|
|
||||||
|
.RE
|
||||||
|
.RS
|
||||||
|
For the
|
||||||
|
.BR or ", " and ", " xor " and " rshift
|
||||||
|
operations,
|
||||||
|
.I NUM
|
||||||
|
is assumed to be an unsigned, 32bit integer value. For the
|
||||||
|
.B addend
|
||||||
|
operation,
|
||||||
|
.I NUM
|
||||||
|
may be much more complex: It may be prefixed by a minus ('-') sign to cause
|
||||||
|
subtraction instead of addition and for keys of
|
||||||
|
.BR src ", " dst ", " nfct-src " and " nfct-dst
|
||||||
|
it may be given in IP address notation. See below for an illustrating example.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI match " EMATCH_TREE"
|
||||||
|
Match packets using the extended match infrastructure. See
|
||||||
|
.BR tc-ematch (8)
|
||||||
|
for a detailed description of the allowed syntax in
|
||||||
|
.IR EMATCH_TREE .
|
||||||
|
.SH KEYS
|
||||||
|
In mapping mode, a single key is used (after optional permutation) to build a
|
||||||
|
class ID. The resulting ID is deducible in most cases. In hashing more, a number
|
||||||
|
of keys may be specified which are then hashed and the output used as class ID.
|
||||||
|
This ID is not deducible in beforehand, and may even change over time for a
|
||||||
|
given flow if a
|
||||||
|
.B perturb
|
||||||
|
interval has been given.
|
||||||
|
|
||||||
|
The range of class IDs can be limited by the
|
||||||
|
.B divisor
|
||||||
|
option, which is used for a modulus.
|
||||||
|
.TP
|
||||||
|
.BR src ", " dst
|
||||||
|
Use source or destination address as key. In case of IPv4 and TIPC, this is the
|
||||||
|
actual address value. For IPv6, the 128bit address is folded into a 32bit value
|
||||||
|
by XOR'ing the four 32bit words. In all other cases, the kernel-internal socket
|
||||||
|
address is used (after folding into 32bits on 64bit systems).
|
||||||
|
.TP
|
||||||
|
.B proto
|
||||||
|
Use the layer four protocol number as key.
|
||||||
|
.TP
|
||||||
|
.B proto-src
|
||||||
|
Use the layer four source port as key. If not available, the kernel-internal
|
||||||
|
socket address is used instead.
|
||||||
|
.TP
|
||||||
|
.B proto-dst
|
||||||
|
Use the layer four destination port as key. If not available, the associated
|
||||||
|
kernel-internal dst_entry address is used after XOR'ing with the packet's
|
||||||
|
layer three protocol number.
|
||||||
|
.TP
|
||||||
|
.B iif
|
||||||
|
Use the incoming interface index as key.
|
||||||
|
.TP
|
||||||
|
.B priority
|
||||||
|
Use the packet's priority as key. Usually this is the IP header's DSCP/ECN
|
||||||
|
value.
|
||||||
|
.TP
|
||||||
|
.B mark
|
||||||
|
Use the netfilter
|
||||||
|
.B fwmark
|
||||||
|
as key.
|
||||||
|
.TP
|
||||||
|
.B nfct
|
||||||
|
Use the associated conntrack entry address as key.
|
||||||
|
.TP
|
||||||
|
.BR nfct-src ", " nfct-dst ", " nfct-proto-src ", " nfct-proto-dst
|
||||||
|
These are conntrack-aware variants of
|
||||||
|
.BR src ", " dst ", " proto-src " and " proto-dst .
|
||||||
|
In case of NAT, these are basically the packet header's values before NAT was
|
||||||
|
applied.
|
||||||
|
.TP
|
||||||
|
.B rt-classid
|
||||||
|
Use the packet's destination routing table entry's realm as key.
|
||||||
|
.TP
|
||||||
|
.B sk-uid
|
||||||
|
.TQ
|
||||||
|
.B sk-gid
|
||||||
|
For locally generated packets, use the user or group ID the originating socket
|
||||||
|
belongs to as key.
|
||||||
|
.TP
|
||||||
|
.B vlan-tag
|
||||||
|
Use the packet's vlan ID as key.
|
||||||
|
.TP
|
||||||
|
.B rxhash
|
||||||
|
Use the flow hash as key.
|
||||||
|
|
||||||
|
.SH EXAMPLES
|
||||||
|
.TP
|
||||||
|
Classic SFQ hash:
|
||||||
|
|
||||||
|
.EX
|
||||||
|
tc filter add ... flow hash \\
|
||||||
|
keys src,dst,proto,proto-src,proto-dst divisor 1024
|
||||||
|
.EE
|
||||||
|
.TP
|
||||||
|
Classic SFQ hash, but using information from conntrack to work properly in combination with NAT:
|
||||||
|
|
||||||
|
.EX
|
||||||
|
tc filter add ... flow hash \\
|
||||||
|
keys nfct-src,nfct-dst,proto,nfct-proto-src,nfct-proto-dst \\
|
||||||
|
divisor 1024
|
||||||
|
.EE
|
||||||
|
.TP
|
||||||
|
Map destination IPs of 192.168.0.0/24 to classids 1-257:
|
||||||
|
|
||||||
|
.EX
|
||||||
|
tc filter add ... flow map \\
|
||||||
|
key dst addend -192.168.0.0 divisor 256
|
||||||
|
.EE
|
||||||
|
.TP
|
||||||
|
Alternative to the above:
|
||||||
|
|
||||||
|
.EX
|
||||||
|
tc filter add ... flow map \\
|
||||||
|
key dst and 0xff
|
||||||
|
.EE
|
||||||
|
.TP
|
||||||
|
The same, but in reverse order:
|
||||||
|
|
||||||
|
.EX
|
||||||
|
tc filter add ... flow map \\
|
||||||
|
key dst and 0xff xor 0xff
|
||||||
|
.EE
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR tc-ematch (8),
|
||||||
|
.BR tc-sfq (8)
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
.TH "Flower filter in tc" 8 "22 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
flower \- flow based traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " flower " [ "
|
||||||
|
.IR MATCH_LIST " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ] [ "
|
||||||
|
.B classid
|
||||||
|
.IR CLASSID " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR MATCH_LIST " := [ " MATCH_LIST " ] " MATCH
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR MATCH " := { "
|
||||||
|
.B indev
|
||||||
|
.IR ifname " | { "
|
||||||
|
.BR dst_mac " | " src_mac " } "
|
||||||
|
.IR mac_address " | "
|
||||||
|
.BR eth_type " { " ipv4 " | " ipv6 " | "
|
||||||
|
.IR ETH_TYPE " } | "
|
||||||
|
.BR ip_proto " { " tcp " | " udp " | "
|
||||||
|
.IR IP_PROTO " } | { "
|
||||||
|
.BR dst_ip " | " src_ip " } { "
|
||||||
|
.IR ipv4_address " | " ipv6_address " } | { "
|
||||||
|
.BR dst_port " | " src_port " } "
|
||||||
|
.IR port_number " }"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B flower
|
||||||
|
filter matches flows to the set of keys specified and assigns an arbitrarily
|
||||||
|
chosen class ID to packets belonging to them. Additionally (or alternatively) an
|
||||||
|
action from the generic action framework may be called.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Specify a class to pass matching packets on to.
|
||||||
|
.I CLASSID
|
||||||
|
is in the form
|
||||||
|
.BR X : Y ", while " X " and " Y
|
||||||
|
are interpreted as numbers in hexadecimal format.
|
||||||
|
.TP
|
||||||
|
.BI indev " ifname"
|
||||||
|
Match on incoming interface name. Obviously this makes sense only for forwarded
|
||||||
|
flows.
|
||||||
|
.I ifname
|
||||||
|
is the name of an interface which must exist at the time of
|
||||||
|
.B tc
|
||||||
|
invocation.
|
||||||
|
.TP
|
||||||
|
.BI dst_mac " mac_address"
|
||||||
|
.TQ
|
||||||
|
.BI src_mac " mac_address"
|
||||||
|
Match on source or destination MAC address.
|
||||||
|
.TP
|
||||||
|
.BI eth_type " ETH_TYPE"
|
||||||
|
Match on layer three protocol.
|
||||||
|
.I ETH_TYPE
|
||||||
|
may be either
|
||||||
|
.BR ipv4 , ipv6
|
||||||
|
or an unsigned 16bit value in hexadecimal format.
|
||||||
|
.TP
|
||||||
|
.BI ip_proto " IP_PROTO"
|
||||||
|
Match on layer four protocol.
|
||||||
|
.I IP_PROTO
|
||||||
|
may be either
|
||||||
|
.BR tcp , udp
|
||||||
|
or an unsigned 8bit value in hexadecimal format.
|
||||||
|
.TP
|
||||||
|
.BI dst_ip " ADDRESS"
|
||||||
|
.TQ
|
||||||
|
.BI src_ip " ADDRESS"
|
||||||
|
Match on source or destination IP address.
|
||||||
|
.I ADDRESS
|
||||||
|
must be a valid IPv4 or IPv6 address, depending on
|
||||||
|
.BR ether_type ,
|
||||||
|
which has to be specified in beforehand.
|
||||||
|
.TP
|
||||||
|
.BI dst_port " NUMBER"
|
||||||
|
.TQ
|
||||||
|
.BI src_port " NUMBER"
|
||||||
|
Match on layer 4 protocol source or destination port number. Only available for
|
||||||
|
.BR ip_proto " values " udp " and " tcp ,
|
||||||
|
which has to be specified in beforehand.
|
||||||
|
.SH NOTES
|
||||||
|
As stated above where applicable, matches of a certain layer implicitly depend
|
||||||
|
on the matches of the next lower layer. Precisely, layer one and two matches (
|
||||||
|
.BR indev , dst_mac , src_mac " and " eth_type )
|
||||||
|
have no dependency, layer three matches (
|
||||||
|
.BR ip_proto , dst_ip " and " src_ip )
|
||||||
|
require
|
||||||
|
.B eth_type
|
||||||
|
being set to either
|
||||||
|
.BR ipv4 " or " ipv6 ,
|
||||||
|
and finally layer four matches (
|
||||||
|
.BR dst_port " and " src_port )
|
||||||
|
depend on
|
||||||
|
.B ip_proto
|
||||||
|
being set to either
|
||||||
|
.BR tcp " or " udp .
|
||||||
|
.P
|
||||||
|
There can be only used one mask per one prio. If user needs to specify different
|
||||||
|
mask, he has to use different prio.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR tc-flow (8)
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
.TH "Firewall mark classifier in tc" 8 "21 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
fw \- fwmark traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " fw " [ " classid
|
||||||
|
.IR CLASSID " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
the
|
||||||
|
.B fw
|
||||||
|
filter allows to classify packets based on a previously set
|
||||||
|
.BR fwmark " by " iptables .
|
||||||
|
If it is identical to the filter's
|
||||||
|
.BR handle ,
|
||||||
|
the filter matches.
|
||||||
|
.B iptables
|
||||||
|
allows to mark single packets with the
|
||||||
|
.B MARK
|
||||||
|
target, or whole connections using
|
||||||
|
.BR CONNMARK .
|
||||||
|
The benefit of using this filter instead of doing the
|
||||||
|
heavy-lifting with
|
||||||
|
.B tc
|
||||||
|
itself is that on one hand it might be convenient to keep packet filtering and
|
||||||
|
classification in one place, possibly having to match a packet just once, and on
|
||||||
|
the other users familiar with
|
||||||
|
.BR iptables " but not " tc
|
||||||
|
will have a less hard time adding QoS to their setups.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Push matching packets to the class identified by
|
||||||
|
.IR CLASSID .
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.SH EXAMPLES
|
||||||
|
Take e.g. the following tc filter statement:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add ... handle 6 fw classid 1:1
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
will match if the packet's
|
||||||
|
.B fwmark
|
||||||
|
value is
|
||||||
|
.BR 6 .
|
||||||
|
This is a sample
|
||||||
|
.B iptables
|
||||||
|
statement marking packets coming in on eth0:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
iptables -t mangle -A PREROUTING -i eth0 -j MARK --set-mark 6
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR iptables (8),
|
||||||
|
.BR iptables-extensions (8)
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
.TH "Route classifier in tc" 8 "21 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
route \- route traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " route " [ " from
|
||||||
|
.IR REALM " | "
|
||||||
|
.B fromif
|
||||||
|
.IR TAG " ] [ "
|
||||||
|
.B to
|
||||||
|
.IR REALM " ] [ "
|
||||||
|
.B classid
|
||||||
|
.IR CLASSID " ] [ "
|
||||||
|
.B action
|
||||||
|
.IR ACTION_SPEC " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Match packets based on routing table entries. This filter centers around the
|
||||||
|
possibility to assign a
|
||||||
|
.B realm
|
||||||
|
to routing table entries. For any packet to be classified by this filter, a
|
||||||
|
routing table lookup is performed and the returned
|
||||||
|
.B realm
|
||||||
|
is used to decide on whether the packet is a match or not.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Push matching packets into the class identified by
|
||||||
|
.IR CLASSID .
|
||||||
|
.TP
|
||||||
|
.BI from " REALM"
|
||||||
|
.TQ
|
||||||
|
.BI fromif " TAG"
|
||||||
|
Perform source route lookups.
|
||||||
|
.I TAG
|
||||||
|
is the name of an interface which must be present on the system at the time of
|
||||||
|
.B tc
|
||||||
|
invocation.
|
||||||
|
.TP
|
||||||
|
.BI to " REALM"
|
||||||
|
Match if normal (i.e., destination) routing returns the given
|
||||||
|
.IR REALM .
|
||||||
|
.SH EXAMPLES
|
||||||
|
Consider the subnet 192.168.2.0/24 being attached to eth0:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
ip route add 192.168.2.0/24 dev eth0 realm 2
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
The following
|
||||||
|
.B route
|
||||||
|
filter will then match packets from that subnet:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add ... route from 2 classid 1:2
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
and pass packets on to class 1:2.
|
||||||
|
.SH NOTES
|
||||||
|
Due to implementation details,
|
||||||
|
.B realm
|
||||||
|
values must be in a range from 0 to 255, inclusive. Alternatively, a verbose
|
||||||
|
name defined in /etc/iproute2/rt_realms may be given instead.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.BR ip-route (8)
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
.TH "Traffic control index filter" 8 "21 Oct 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
tcindex \- traffic control index filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... " tcindex " [ " hash
|
||||||
|
.IR SIZE " ] [ "
|
||||||
|
.B mask
|
||||||
|
.IR MASK " ] [ "
|
||||||
|
.B shift
|
||||||
|
.IR SHIFT " ] [ "
|
||||||
|
.BR pas_on " | " fall_through " ] [ " classid
|
||||||
|
.IR CLASSID " ] [ "
|
||||||
|
.B action
|
||||||
|
.BR ACTION_SPEC " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This filter allows to match packets based on their
|
||||||
|
.B tcindex
|
||||||
|
field value, i.e. the combination of the DSCP and ECN fields as present in IPv4
|
||||||
|
and IPv6 headers.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI action " ACTION_SPEC"
|
||||||
|
Apply an action from the generic actions framework on matching packets.
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Push matching packets into the class identified by
|
||||||
|
.IR CLASSID .
|
||||||
|
.TP
|
||||||
|
.BI hash " SIZE"
|
||||||
|
Hash table size in entries to use. Defaults to 64.
|
||||||
|
.TP
|
||||||
|
.BI mask " MASK"
|
||||||
|
An optional bitmask to binary
|
||||||
|
.BR AND " to the packet's " tcindex
|
||||||
|
field before use.
|
||||||
|
.TP
|
||||||
|
.BI shift " SHIFT"
|
||||||
|
The number of bits to right-shift a packet's
|
||||||
|
.B tcindex
|
||||||
|
value before use. If a
|
||||||
|
.B mask
|
||||||
|
has been set, masking is done before shifting.
|
||||||
|
.TP
|
||||||
|
.B pass_on
|
||||||
|
If this flag is set, failure to find a class for the resulting ID will make the
|
||||||
|
filter fail and lead to the next filter being consulted.
|
||||||
|
.TP
|
||||||
|
.B fall_through
|
||||||
|
This is the opposite of
|
||||||
|
.B pass_on
|
||||||
|
and the default. The filter will classify the packet even if there is no class
|
||||||
|
present for the resulting class ID.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8)
|
||||||
|
|
@ -0,0 +1,663 @@
|
||||||
|
.TH "Universal 32bit classifier in tc" 8 "25 Sep 2015" "iproute2" "Linux"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
u32 \- universal 32bit traffic control filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.in +8
|
||||||
|
.ti -8
|
||||||
|
.BR tc " " filter " ... [ " handle
|
||||||
|
.IR HANDLE " ] "
|
||||||
|
.B u32
|
||||||
|
.IR OPTION_LIST " [ "
|
||||||
|
.B offset
|
||||||
|
.IR OFFSET " ] [ "
|
||||||
|
.B hashkey
|
||||||
|
.IR HASHKEY " ] [ "
|
||||||
|
.B classid
|
||||||
|
.IR CLASSID " ] [ "
|
||||||
|
.B divisor
|
||||||
|
.IR uint_value " ] [ "
|
||||||
|
.B order
|
||||||
|
.IR u32_value " ] [ "
|
||||||
|
.B ht
|
||||||
|
.IR HANDLE " ] [ "
|
||||||
|
.B sample
|
||||||
|
.IR SELECTOR " [ "
|
||||||
|
.B divisor
|
||||||
|
.IR uint_value " ] ] [ "
|
||||||
|
.B link
|
||||||
|
.IR HANDLE " ] [ "
|
||||||
|
.B indev
|
||||||
|
.IR ifname " ] [ "
|
||||||
|
.BR help " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR HANDLE " := { "
|
||||||
|
\fIu12_hex_htid\fB:\fR[\fIu8_hex_hash\fB:\fR[\fIu12_hex_nodeid\fR] | \fB0x\fIu32_hex_value\fR }
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR OPTION_LIST " := [ " OPTION_LIST " ] " OPTION
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR HASHKEY " := [ "
|
||||||
|
.B mask
|
||||||
|
.IR u32_hex_value " ] [ "
|
||||||
|
.B at
|
||||||
|
.IR 4*int_value " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR CLASSID " := { "
|
||||||
|
.BR root " | "
|
||||||
|
.BR none " | "
|
||||||
|
[\fIu16_major\fR]\fB:\fIu16_minor\fR | \fIu32_hex_value\fR }
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR OFFSET " := [ "
|
||||||
|
.B plus
|
||||||
|
.IR int_value " ] [ "
|
||||||
|
.B at
|
||||||
|
.IR 2*int_value " ] [ "
|
||||||
|
.B mask
|
||||||
|
.IR u16_hex_value " ] [ "
|
||||||
|
.B shift
|
||||||
|
.IR int_value " ] [ "
|
||||||
|
.BR eat " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR OPTION " := { "
|
||||||
|
.B match
|
||||||
|
.IR SELECTOR " | "
|
||||||
|
.B action
|
||||||
|
.IR ACTION " } "
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR SELECTOR " := { "
|
||||||
|
.B u32
|
||||||
|
.IR VAL_MASK_32 " | "
|
||||||
|
.B u16
|
||||||
|
.IR VAL_MASK_16 " | "
|
||||||
|
.B u8
|
||||||
|
.IR VAL_MASK_8 " | "
|
||||||
|
.B ip
|
||||||
|
.IR IP " | "
|
||||||
|
.B ip6
|
||||||
|
.IR IP6 " | { "
|
||||||
|
.BR tcp " | " udp " } "
|
||||||
|
.IR TCPUDP " | "
|
||||||
|
.B icmp
|
||||||
|
.IR ICMP " | "
|
||||||
|
.B mark
|
||||||
|
.IR VAL_MASK_32 " | "
|
||||||
|
.B ether
|
||||||
|
.IR ETHER " }"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR IP " := { { "
|
||||||
|
.BR src " | " dst " } { " default " | " any " | " all " | "
|
||||||
|
.IR ip_address " [ "
|
||||||
|
.BR / " { "
|
||||||
|
.IR prefixlen " | " netmask " } ] } " AT " | { "
|
||||||
|
.BR dsfield " | " ihl " | " protocol " | " precedence " | "
|
||||||
|
.BR icmp_type " | " icmp_code " } "
|
||||||
|
.IR VAL_MASK_8 " | { "
|
||||||
|
.BR sport " | " dport " } "
|
||||||
|
.IR VAL_MASK_16 " | "
|
||||||
|
.BR nofrag " | " firstfrag " | " df " | " mf " }"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR IP6 " := { { "
|
||||||
|
.BR src " | " dst " } { " default " | " any " | " all " | "
|
||||||
|
.IR ip6_address " [/" prefixlen " ] } " AT " | "
|
||||||
|
.B priority
|
||||||
|
.IR VAL_MASK_8 " | { "
|
||||||
|
.BR protocol " | " icmp_type " | " icmp_code " } "
|
||||||
|
.IR VAL_MASK_8 " | "
|
||||||
|
.B flowlabel
|
||||||
|
.IR VAL_MASK_32 " | { "
|
||||||
|
.BR sport " | " dport " } "
|
||||||
|
.IR VAL_MASK_16 " }"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR TCPUDP " := { "
|
||||||
|
.BR src " | " dst " } "
|
||||||
|
.I VAL_MASK_16
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR ICMP " := { "
|
||||||
|
.B type
|
||||||
|
.IR VAL_MASK_8 " | "
|
||||||
|
.B code
|
||||||
|
.IR VAL_MASK_8 " }"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR ETHER " := { "
|
||||||
|
.BR src " | " dst " } "
|
||||||
|
.IR ether_address " " AT
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR VAL_MASK_32 " := " u32_value " " u32_hex_mask " [ " AT " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR VAL_MASK_16 " := " u16_value " " u16_hex_mask " [ " AT " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR VAL_MASK_8 " := " u8_value " " u8_hex_mask " [ " AT " ]"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR AT " := [ "
|
||||||
|
.BR at " [ " nexthdr+ " ] "
|
||||||
|
.IR int_value " ]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The Universal/Ugly 32bit filter allows to match arbitrary bitfields in the
|
||||||
|
packet. Due to breaking everything down to values, masks and offsets, It is
|
||||||
|
equally powerful and hard to use. Luckily many abstracting directives are
|
||||||
|
present which allow defining rules on a higher level and therefore free the
|
||||||
|
user from having to fiddle with bits and masks in many cases.
|
||||||
|
|
||||||
|
There are two general modes of invocation: The first mode creates a new filter
|
||||||
|
to delegate packets to different destinations. Apart from the obvious ones,
|
||||||
|
namely classifying the packet by specifying a
|
||||||
|
.I CLASSID
|
||||||
|
or calling an
|
||||||
|
.BR action ,
|
||||||
|
one may
|
||||||
|
.B link
|
||||||
|
one filter to another one (or even a list of them), effectively organizing
|
||||||
|
filters into a tree-like hierarchy.
|
||||||
|
|
||||||
|
Typically filter delegation is done by means of a hash table, which leads to the
|
||||||
|
second mode of invocation: it merely serves to set up these hash tables. Filters
|
||||||
|
can select a hash table and provide a key selector from which a hash is to be
|
||||||
|
computed and used as key to lookup the table's bucket which contains filters for
|
||||||
|
further processing. This is useful if a high number of filters is in use, as the
|
||||||
|
overhead of performing the hash operation and table lookup becomes negligible in
|
||||||
|
that case. Using hashtables with
|
||||||
|
.B u32
|
||||||
|
basically involves the following pattern:
|
||||||
|
.IP (1) 4
|
||||||
|
Creating a new hash table, specifying it's size using the
|
||||||
|
.B divisor
|
||||||
|
parameter and ideally a handle by which the table can be identified. If the
|
||||||
|
latter is not given, the kernel chooses one on it's own, which has to be
|
||||||
|
guessed later.
|
||||||
|
.IP (2) 4
|
||||||
|
Creating filters which link to the created table in
|
||||||
|
.I (1)
|
||||||
|
using the
|
||||||
|
.B link
|
||||||
|
parameter and defining the packet data which the kernel will use to calculate
|
||||||
|
the
|
||||||
|
.BR hashkey .
|
||||||
|
.IP (3) 4
|
||||||
|
Adding filters to buckets in the hash table from
|
||||||
|
.IR (1) .
|
||||||
|
In order to avoid having to know how exactly the kernel creates the hash key,
|
||||||
|
there is the
|
||||||
|
.B sample
|
||||||
|
parameter, which gives sample data to hash and thereby define the table bucket
|
||||||
|
the filter should be added to.
|
||||||
|
|
||||||
|
.RE
|
||||||
|
In fact, even if not explicitly requested
|
||||||
|
.B u32
|
||||||
|
creates a hash table for every
|
||||||
|
.B priority
|
||||||
|
a filter is being added with. The table's size is 1 though, so it is in fact
|
||||||
|
merely a linked list.
|
||||||
|
.SH VALUES
|
||||||
|
Options and selectors require values to be specified in a specific format, which
|
||||||
|
is often non-intuitive. Therefore the terminals in
|
||||||
|
.I SYNOPSIS
|
||||||
|
have been given descriptive names to indicate the required format and/or maximum
|
||||||
|
allowed numeric value: Prefixes
|
||||||
|
.IR u32 ", " u16 " and " u8
|
||||||
|
indicate four, two and single byte unsigned values. E.g.
|
||||||
|
.I u16
|
||||||
|
indicates a two byte-sized value in range between 0 and 65535 (0xFFFF)
|
||||||
|
inclusive. A prefix of
|
||||||
|
.I int
|
||||||
|
indicates a four byte signed value. A middle part of
|
||||||
|
.I _hex_
|
||||||
|
indicates that the value is parsed in hexadecimal format. Otherwise, the
|
||||||
|
value's base is automatically detected, i.e. values prefixed with
|
||||||
|
.I 0x
|
||||||
|
are considered hexadecimal, a leading
|
||||||
|
.I 0
|
||||||
|
indicates octal format and decimal format otherwise. There are some values with
|
||||||
|
special formatting as well:
|
||||||
|
.IR ip_address " and " netmask
|
||||||
|
are in dotted-quad formatting as usual for IPv4 addresses. An
|
||||||
|
.I ip6_address
|
||||||
|
is specified in common, colon-separated hexadecimal format. Finally,
|
||||||
|
.I prefixlen
|
||||||
|
is an unsigned, decimal integer value in range from 0 to the address width in
|
||||||
|
bits (32 for IPv4 and 128 for IPv6).
|
||||||
|
|
||||||
|
Sometimes values need to be dividable by a certain number. In that case a name
|
||||||
|
of the form
|
||||||
|
.I N*val
|
||||||
|
was chosen, indicating that
|
||||||
|
.I val
|
||||||
|
must be dividable by
|
||||||
|
.IR N .
|
||||||
|
Or the other way around: the resulting value must be a multiple of
|
||||||
|
.IR N .
|
||||||
|
.SH OPTIONS
|
||||||
|
.B U32
|
||||||
|
recognizes the following options:
|
||||||
|
.TP
|
||||||
|
.BI handle " HANDLE"
|
||||||
|
The handle is used to reference a filter and therefore must be unique. It
|
||||||
|
consists of a hash table identifier
|
||||||
|
.B htid
|
||||||
|
and optional
|
||||||
|
.B hash
|
||||||
|
(which identifies the hash table's bucket) and
|
||||||
|
.BR nodeid .
|
||||||
|
All these values are parsed as unsigned, hexadecimal numbers with length 12bits
|
||||||
|
(
|
||||||
|
.BR htid " and " nodeid )
|
||||||
|
or 8bits (
|
||||||
|
.BR hash ).
|
||||||
|
Alternatively one may specify a single, 32bit long hex number which contains
|
||||||
|
the three fields bits in concatenated form. Other than the fields themselves, it
|
||||||
|
has to be prefixed by
|
||||||
|
.BR 0x .
|
||||||
|
.TP
|
||||||
|
.BI offset " OFFSET"
|
||||||
|
Set an offset which defines where matches of subsequent filters are applied to.
|
||||||
|
Therefore this option is useful only when combined with
|
||||||
|
.BR link " or a combination of " ht " and " sample .
|
||||||
|
The offset may be given explicitly by using the
|
||||||
|
.B plus
|
||||||
|
keyword, or extracted from the packet data with
|
||||||
|
.BR at .
|
||||||
|
It is possible to mangle the latter using
|
||||||
|
.BR mask " and/or " shift
|
||||||
|
keywords. By default, this offset is recorded but not implicitly applied. It is
|
||||||
|
used only to substitute the
|
||||||
|
.B nexthdr+
|
||||||
|
statement. Using the keyword
|
||||||
|
.B eat
|
||||||
|
though inverses this behaviour: the offset is applied always, and
|
||||||
|
.B nexthdr+
|
||||||
|
will fall back to zero.
|
||||||
|
.TP
|
||||||
|
.BI hashkey " HASHKEY"
|
||||||
|
Spefify what packet data to use to calculate a hash key for bucket lookup. The
|
||||||
|
kernel adjusts the value according to the hash table's size. For this to work,
|
||||||
|
the option
|
||||||
|
.B link
|
||||||
|
must be given.
|
||||||
|
.TP
|
||||||
|
.BI classid " CLASSID"
|
||||||
|
Classify matching packets into the given
|
||||||
|
.IR CLASSID ,
|
||||||
|
which consists of either 16bit
|
||||||
|
.BR major " and " minor
|
||||||
|
numbers or a single 32bit value combining both.
|
||||||
|
.TP
|
||||||
|
.BI divisor " u32_value"
|
||||||
|
Specify a modulo value. Used when creating hash tables to define their size or
|
||||||
|
for declaring a
|
||||||
|
.B sample
|
||||||
|
to calculate hash table keys from. Must be a power of two with exponent not
|
||||||
|
exceeding eight.
|
||||||
|
.TP
|
||||||
|
.BI order " u32_value"
|
||||||
|
A value to order filters by, ascending. Conflicts with
|
||||||
|
.B handle
|
||||||
|
which serves the same purpose.
|
||||||
|
.TP
|
||||||
|
.BI sample " SELECTOR"
|
||||||
|
Used together with
|
||||||
|
.B ht
|
||||||
|
to specify which bucket to add this filter to. This allows one to avoid having
|
||||||
|
to know how exactly the kernel calculates hashes. The additional
|
||||||
|
.B divisor
|
||||||
|
defaults to 256, so must be given for hash tables of different size.
|
||||||
|
.TP
|
||||||
|
.BI link " HANDLE"
|
||||||
|
Delegate matching packets to filters in a hash table.
|
||||||
|
.I HANDLE
|
||||||
|
is used to only specify the hash table, so only
|
||||||
|
.BR htid " may be given, " hash " and " nodeid
|
||||||
|
have to be omitted. By default, bucket number 0 will be used and can be
|
||||||
|
overridden by the
|
||||||
|
.B hashkey
|
||||||
|
option.
|
||||||
|
.TP
|
||||||
|
.BI indev " ifname"
|
||||||
|
Filter on the incoming interface of the packet. Obviously works only for
|
||||||
|
forwarded traffic.
|
||||||
|
.TP
|
||||||
|
.BI help
|
||||||
|
Print a brief help text about possible options.
|
||||||
|
.SH SELECTORS
|
||||||
|
Basically the only real selector is
|
||||||
|
.B u32 .
|
||||||
|
All others merely provide a higher level syntax and are internally translated
|
||||||
|
into
|
||||||
|
.B u32 .
|
||||||
|
.TP
|
||||||
|
.BI u32 " VAL_MASK_32"
|
||||||
|
.TQ
|
||||||
|
.BI u16 " VAL_MASK_16"
|
||||||
|
.TQ
|
||||||
|
.BI u8 " VAL_MASK_8"
|
||||||
|
Match packet data to a given value. The selector name defines the sample length
|
||||||
|
to extract (32bits for
|
||||||
|
.BR u32 ,
|
||||||
|
16bits for
|
||||||
|
.B u16
|
||||||
|
and 8bits for
|
||||||
|
.BR u8 ).
|
||||||
|
Before comparing, the sample is binary AND'ed with the given mask. This way
|
||||||
|
uninteresting bits can be cleared before comparison. The position of the sample
|
||||||
|
is defined by the offset specified in
|
||||||
|
.IR AT .
|
||||||
|
.TP
|
||||||
|
.BI ip " IP"
|
||||||
|
.TQ
|
||||||
|
.BI ip6 " IP6"
|
||||||
|
Assume packet starts with an IPv4 (
|
||||||
|
.BR ip )
|
||||||
|
or IPv6 (
|
||||||
|
.BR ip6 )
|
||||||
|
header.
|
||||||
|
.IR IP / IP6
|
||||||
|
then allows to match various header fields:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
.BI src " ADDR"
|
||||||
|
.BI dst " ADDR"
|
||||||
|
Compare Source or Destination Address fields against the value of
|
||||||
|
.IR ADDR .
|
||||||
|
The reserved words
|
||||||
|
.BR default ", " any " and " all
|
||||||
|
effectively match any address. Otherwise an IP address of the particular
|
||||||
|
protocol is expected, optionally suffixed by a prefix length to match whole
|
||||||
|
subnets. In case of IPv4 a netmask may also be given.
|
||||||
|
.TP
|
||||||
|
.BI dsfield " VAL_MASK_8"
|
||||||
|
IPv4 only. Match the packet header's DSCP/ECN field. Synonyms to this are
|
||||||
|
.BR tos " and " precedence .
|
||||||
|
.TP
|
||||||
|
.BI ihl " VAL_MASK_8"
|
||||||
|
IPv4 only. Match the Internet Header Length field. Note that the value's unit is
|
||||||
|
32bits, so to match a packet with 24byte header length
|
||||||
|
.I u8_value
|
||||||
|
has to be 6.
|
||||||
|
.TP
|
||||||
|
.BI protocol " VAL_MASK_8"
|
||||||
|
Match the Protocol (IPv4) or Next Header (IPv6) field value, e.g. 6 for TCP.
|
||||||
|
.TP
|
||||||
|
.BI icmp_type " VAL_MASK_8"
|
||||||
|
.TQ
|
||||||
|
.BI icmp_code " VAL_MASK_8"
|
||||||
|
Assume a next-header protocol of icmp or ipv6-icmp and match Type or Code
|
||||||
|
field values. This is dangerous, as the code assumes minimal header size for
|
||||||
|
IPv4 and lack of extension headers for IPv6.
|
||||||
|
.TP
|
||||||
|
.BI sport " VAL_MASK_16"
|
||||||
|
.TQ
|
||||||
|
.BI dport " VAL_MASK_16"
|
||||||
|
Match layer four source or destination ports. This is dangerous as well, as it
|
||||||
|
assumes a suitable layer four protocol is present (which has Source and
|
||||||
|
Destination Port fields right at the start of the header and 16bit in size).
|
||||||
|
Also minimal header size for IPv4 and lack of IPv6 extension headers is assumed.
|
||||||
|
.TP
|
||||||
|
.B nofrag
|
||||||
|
.TQ
|
||||||
|
.B firstfrag
|
||||||
|
.TQ
|
||||||
|
.B df
|
||||||
|
.TQ
|
||||||
|
.B mf
|
||||||
|
IPv4 only, check certain flags and fragment offset values. Match if the packet
|
||||||
|
is not a fragment
|
||||||
|
.RB ( nofrag ),
|
||||||
|
the first fragment
|
||||||
|
.RB ( firstfrag ),
|
||||||
|
if Don't Fragment
|
||||||
|
.RB ( df )
|
||||||
|
or More Fragments
|
||||||
|
.RB ( mf )
|
||||||
|
bits are set.
|
||||||
|
.TP
|
||||||
|
.BI priority " VAL_MASK_8"
|
||||||
|
IPv6 only. Match the header's Traffic Class field, which has the same purpose
|
||||||
|
and semantics of IPv4's ToS field since RFC 3168: upper six bits are DSCP, the
|
||||||
|
lower two ECN.
|
||||||
|
.TP
|
||||||
|
.BI flowlabel " VAL_MASK_32"
|
||||||
|
IPv6 only. Match the Flow Label field's value. Note that Flow Label itself is
|
||||||
|
only 20bytes long, which are the least significant ones here. The remaining
|
||||||
|
upper 12bytes match Version and Traffic Class fields.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI tcp " TCPUDP"
|
||||||
|
.TQ
|
||||||
|
.BI udp " TCPUDP"
|
||||||
|
Match fields of next header of protocol TCP or UDP. The possible values for
|
||||||
|
.I TCPDUP
|
||||||
|
are:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
.BI src " VAL_MASK_16"
|
||||||
|
Match on Source Port field value.
|
||||||
|
.TP
|
||||||
|
.BI dst " VALMASK_16"
|
||||||
|
Match on Destination Port field value.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI icmp " ICMP"
|
||||||
|
Match fields of next header of protocol ICMP. The possible values for
|
||||||
|
.I ICMP
|
||||||
|
are:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
.BI type " VAL_MASK_8"
|
||||||
|
Match on ICMP Type field.
|
||||||
|
.TP
|
||||||
|
.BI code " VAL_MASK_8"
|
||||||
|
Match on ICMP Code field.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI mark " VAL_MASK_32"
|
||||||
|
Match on netfilter fwmark value.
|
||||||
|
.TP
|
||||||
|
.BI ether " ETHER"
|
||||||
|
Match on ethernet header fields. Possible values for
|
||||||
|
.I ETHER
|
||||||
|
are:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
.BI src " ether_address" " " AT
|
||||||
|
.TQ
|
||||||
|
.BI dst " ether_address" " " AT
|
||||||
|
Match on source or destination ethernet address. This is dangerous: It assumes
|
||||||
|
an ethernet header is present at the start of the packet. This will probably
|
||||||
|
lead to unexpected things if used with layer three interfaces like e.g. tun or
|
||||||
|
ppp.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add dev eth0 parent 999:0 prio 99 protocol ip u32 \\
|
||||||
|
match ip src 192.168.8.0/24 classid 1:1
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
This attaches a filter to the qdisc identified by
|
||||||
|
.BR 999:0.
|
||||||
|
It's priority is
|
||||||
|
.BR 99 ,
|
||||||
|
which affects in which order multiple filters attached to the same
|
||||||
|
.B parent
|
||||||
|
are consulted (the lower the earlier). The filter handles packets of
|
||||||
|
.B protocol
|
||||||
|
type
|
||||||
|
.BR ip ,
|
||||||
|
and
|
||||||
|
.BR match es
|
||||||
|
if the IP header's source address is within the
|
||||||
|
.B 192.168.8.0/24
|
||||||
|
subnet. Matching packets are classified into class
|
||||||
|
.BR 1.1 .
|
||||||
|
The effect of this command might be surprising at first glance:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
filter parent 1: protocol ip pref 99 u32
|
||||||
|
filter parent 1: protocol ip pref 99 u32 \\
|
||||||
|
fh 800: ht divisor 1
|
||||||
|
filter parent 1: protocol ip pref 99 u32 \\
|
||||||
|
fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 \\
|
||||||
|
match c0a80800/ffffff00 at 12
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
So parent
|
||||||
|
.B 1:
|
||||||
|
is assigned a new
|
||||||
|
.B u32
|
||||||
|
filter, which contains a hash table of size 1 (as the
|
||||||
|
.B divisor
|
||||||
|
indicates). The table ID is
|
||||||
|
.BR 800 .
|
||||||
|
The third line then shows the actual filter which was added above: it sits in
|
||||||
|
table
|
||||||
|
.B 800
|
||||||
|
and bucket
|
||||||
|
.BR 0 ,
|
||||||
|
classifies packets into class ID
|
||||||
|
.B 1:1
|
||||||
|
and matches the upper three bytes of the four byte value at offset
|
||||||
|
.B 12
|
||||||
|
to be
|
||||||
|
.BR 0xc0a808 ,
|
||||||
|
which is 192, 168 and 8.
|
||||||
|
|
||||||
|
Now for something more complicated, namely creating a custom hash table:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add dev eth0 prio 99 handle 1: u32 divisor 256
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
This creates a table of size 256 with handle
|
||||||
|
.B 1:
|
||||||
|
in priority
|
||||||
|
.BR 99 .
|
||||||
|
The effect is as follows:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
filter parent 1: protocol all pref 99 u32
|
||||||
|
filter parent 1: protocol all pref 99 u32 fh 1: ht divisor 256
|
||||||
|
filter parent 1: protocol all pref 99 u32 fh 800: ht divisor 1
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
So along with the requested hash table (handle
|
||||||
|
.BR 1: ),
|
||||||
|
the kernel has created his own table of size 1 to hold other filters of the same
|
||||||
|
priority.
|
||||||
|
|
||||||
|
The next step is to create a filter which links to the created hash table:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add dev eth0 parent 1: prio 1 u32 \\
|
||||||
|
link 1: hashkey mask 0x0000ff00 at 12 \\
|
||||||
|
match ip src 192.168.0.0/16
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
The filter is given a lower priority than the hash table itself so
|
||||||
|
.B u32
|
||||||
|
consults it before manually traversing the hash table. The options
|
||||||
|
.BR link " and " hashkey
|
||||||
|
determine which table and bucket to redirect to. In this case the hash key
|
||||||
|
should be constructed out of the second byte at offset 12, which corresponds to
|
||||||
|
an IP packet's third byte of the source address field. Along with the
|
||||||
|
.B match
|
||||||
|
statement, this effectively maps all class C networks below 192.168.0.0/16 to
|
||||||
|
different buckets of the hash table.
|
||||||
|
|
||||||
|
Filters for certain subnets can be created like so:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add dev eth0 parent 1: prio 99 u32 \\
|
||||||
|
ht 1: sample u32 0x00000800 0x0000ff00 at 12 \\
|
||||||
|
match ip src 192.168.8.0/24 classid 1:1
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
The bucket is defined using the
|
||||||
|
.B sample
|
||||||
|
option: In this case, the second byte at offset 12 must be 0x08, exactly. In
|
||||||
|
this case, the resulting bucket ID is obviously 8, but as soon as
|
||||||
|
.B sample
|
||||||
|
selects an amount of data which could exceed the
|
||||||
|
.BR divisor ,
|
||||||
|
one would have to know the kernel-internal algorithm to deduce the destination
|
||||||
|
bucket. This filter's
|
||||||
|
.B match
|
||||||
|
statement is redundant in this case, as the entropy for the hash key does not
|
||||||
|
exceed the table size and therefore no collisions can occur. Otherwise it's
|
||||||
|
necessary to prevent matching unwanted packets.
|
||||||
|
|
||||||
|
Matching upper layer fields is problematic since IPv4 header length is variable
|
||||||
|
and IPv6 supports extension headers which affect upper layer header offset. To
|
||||||
|
overcome this, there is the possibility to specify
|
||||||
|
.B nexthdr+
|
||||||
|
when giving an offset, and to make things easier there are the
|
||||||
|
.BR tcp " and " udp
|
||||||
|
matches which use
|
||||||
|
.B nexthdr+
|
||||||
|
implicitly. This offset has to be calculated in beforehand though, and the only
|
||||||
|
way to achieve that is by doing it in a separate filter which then links to the
|
||||||
|
filter which wants to use it. Here is an example of doing so:
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.EX
|
||||||
|
tc filter add dev eth0 parent 1:0 protocol ip handle 1: \\
|
||||||
|
u32 divisor 1
|
||||||
|
tc filter add dev eth0 parent 1:0 protocol ip \\
|
||||||
|
u32 ht 1: \\
|
||||||
|
match tcp src 22 FFFF \\
|
||||||
|
classid 1:2
|
||||||
|
tc filter add dev eth0 parent 1:0 protocol ip \\
|
||||||
|
u32 ht 800: \\
|
||||||
|
match ip protocol 6 FF \\
|
||||||
|
match ip firstfrag \\
|
||||||
|
offset at 0 mask 0f00 shift 6 \\
|
||||||
|
link 1:
|
||||||
|
.EE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
This is what is being done: In the first call, a single element sized hash table
|
||||||
|
is created so there is a place to hold the linked to filter and a known handle
|
||||||
|
.RB ( 1: )
|
||||||
|
to reference to it. The second call then adds the actual filter, which pushes
|
||||||
|
packets with TCP source port 22 into class
|
||||||
|
.BR 1:2 .
|
||||||
|
Using
|
||||||
|
.BR ht ,
|
||||||
|
it is moved into the hash table created by the first call. The third call then
|
||||||
|
does the actual magic: It matches IPv4 packets with next layer protocol 6 (TCP),
|
||||||
|
only if it's the first fragment (usually TCP sets DF bit, but if it doesn't and
|
||||||
|
the packet is fragmented, only the first one contains the TCP header), and then
|
||||||
|
sets the offset based on the IP header's IHL field (right-shifting by 6
|
||||||
|
eliminates the offset of the field and at the same time converts the value into
|
||||||
|
byte unit). Finally, using
|
||||||
|
.BR link ,
|
||||||
|
the hash table from first call is referenced which holds the filter from second
|
||||||
|
call.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR tc (8),
|
||||||
|
.br
|
||||||
|
.BR cls_u32.txt " at " http://linux-tc-notes.sourceforge.net/
|
||||||
|
|
@ -144,6 +144,50 @@ It is important to notice that filters reside
|
||||||
.B within
|
.B within
|
||||||
qdiscs - they are not masters of what happens.
|
qdiscs - they are not masters of what happens.
|
||||||
|
|
||||||
|
The available filters are:
|
||||||
|
.TP
|
||||||
|
basic
|
||||||
|
Filter packets based on an ematch expression. See
|
||||||
|
.BR tc-ematch (8)
|
||||||
|
for details.
|
||||||
|
.TP
|
||||||
|
bpf
|
||||||
|
Filter packets using (e)BPF, see
|
||||||
|
.BR tc-bpf (8)
|
||||||
|
for details.
|
||||||
|
.TP
|
||||||
|
cgroup
|
||||||
|
Filter packets based on the control group of their process. See
|
||||||
|
. BR tc-cgroup (8)
|
||||||
|
for details.
|
||||||
|
.TP
|
||||||
|
flow, flower
|
||||||
|
Flow-based classifiers, filtering packets based on their flow (identified by selectable keys). See
|
||||||
|
.BR tc-flow "(8) and"
|
||||||
|
.BR tc-flower (8)
|
||||||
|
for details.
|
||||||
|
.TP
|
||||||
|
fw
|
||||||
|
Filter based on fwmark. Directly maps fwmark value to traffic class. See
|
||||||
|
.BR tc-fw (8).
|
||||||
|
.TP
|
||||||
|
route
|
||||||
|
Filter packets based on routing table. See
|
||||||
|
.BR tc-route (8)
|
||||||
|
for details.
|
||||||
|
.TP
|
||||||
|
rsvp
|
||||||
|
Match Resource Reservation Protocol (RSVP) packets.
|
||||||
|
.TP
|
||||||
|
tcindex
|
||||||
|
Filter packets based on traffic control index. See
|
||||||
|
.BR tc-index (8).
|
||||||
|
.TP
|
||||||
|
u32
|
||||||
|
Generic filtering on arbitrary packet data, assisted by syntax to abstract common operations. See
|
||||||
|
.BR tc-u32 (8)
|
||||||
|
for details.
|
||||||
|
|
||||||
.SH CLASSLESS QDISCS
|
.SH CLASSLESS QDISCS
|
||||||
The classless qdiscs are:
|
The classless qdiscs are:
|
||||||
.TP
|
.TP
|
||||||
|
|
@ -655,15 +699,20 @@ Shows classes as ASCII graph with stats info under each class.
|
||||||
.B tc
|
.B tc
|
||||||
was written by Alexey N. Kuznetsov and added in Linux 2.2.
|
was written by Alexey N. Kuznetsov and added in Linux 2.2.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
.BR tc-basic (8),
|
||||||
.BR tc-bfifo (8),
|
.BR tc-bfifo (8),
|
||||||
.BR tc-bpf (8),
|
.BR tc-bpf (8),
|
||||||
.BR tc-cbq (8),
|
.BR tc-cbq (8),
|
||||||
|
.BR tc-cgroup (8),
|
||||||
.BR tc-choke (8),
|
.BR tc-choke (8),
|
||||||
.BR tc-codel (8),
|
.BR tc-codel (8),
|
||||||
.BR tc-drr (8),
|
.BR tc-drr (8),
|
||||||
.BR tc-ematch (8),
|
.BR tc-ematch (8),
|
||||||
|
.BR tc-flow (8),
|
||||||
|
.BR tc-flower (8),
|
||||||
.BR tc-fq (8),
|
.BR tc-fq (8),
|
||||||
.BR tc-fq_codel (8),
|
.BR tc-fq_codel (8),
|
||||||
|
.BR tc-fw (8),
|
||||||
.BR tc-hfsc (7),
|
.BR tc-hfsc (7),
|
||||||
.BR tc-hfsc (8),
|
.BR tc-hfsc (8),
|
||||||
.BR tc-htb (8),
|
.BR tc-htb (8),
|
||||||
|
|
@ -671,10 +720,13 @@ was written by Alexey N. Kuznetsov and added in Linux 2.2.
|
||||||
.BR tc-pfifo (8),
|
.BR tc-pfifo (8),
|
||||||
.BR tc-pfifo_fast (8),
|
.BR tc-pfifo_fast (8),
|
||||||
.BR tc-red (8),
|
.BR tc-red (8),
|
||||||
|
.BR tc-route (8),
|
||||||
.BR tc-sfb (8),
|
.BR tc-sfb (8),
|
||||||
.BR tc-sfq (8),
|
.BR tc-sfq (8),
|
||||||
.BR tc-stab (8),
|
.BR tc-stab (8),
|
||||||
.BR tc-tbf (8),
|
.BR tc-tbf (8),
|
||||||
|
.BR tc-tcindex (8),
|
||||||
|
.BR tc-u32 (8),
|
||||||
.br
|
.br
|
||||||
.RB "User documentation at " http://lartc.org/ ", but please direct bugreports and patches to: " <netdev@vger.kernel.org>
|
.RB "User documentation at " http://lartc.org/ ", but please direct bugreports and patches to: " <netdev@vger.kernel.org>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ static void dump_raw_db(FILE *fp, int to_hist)
|
||||||
if (jw) {
|
if (jw) {
|
||||||
jsonw_name(jw, n->name);
|
jsonw_name(jw, n->name);
|
||||||
jsonw_start_object(jw);
|
jsonw_start_object(jw);
|
||||||
|
|
||||||
for (i=0; i<MAXS && stats[i]; i++)
|
for (i=0; i<MAXS && stats[i]; i++)
|
||||||
jsonw_uint_field(jw, stats[i], vals[i]);
|
jsonw_uint_field(jw, stats[i], vals[i]);
|
||||||
jsonw_end_object(jw);
|
jsonw_end_object(jw);
|
||||||
|
|
|
||||||
|
|
@ -377,4 +377,3 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,3 @@ It is available only for alpha and pentiums with correct
|
||||||
CPU timestamp. It is the fastest way, use it when it is available,
|
CPU timestamp. It is the fastest way, use it when it is available,
|
||||||
but remember: not all pentiums have this facility, and
|
but remember: not all pentiums have this facility, and
|
||||||
a lot of them have clock, broken by APM etc. etc.
|
a lot of them have clock, broken by APM etc. etc.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,4 +98,3 @@ invert:
|
||||||
{
|
{
|
||||||
ematch_err = strdup(s);
|
ematch_err = strdup(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ static void explain(void)
|
||||||
fprintf(stderr, " [ action ACTION-SPEC ] [ classid CLASSID ]\n");
|
fprintf(stderr, " [ action ACTION-SPEC ] [ classid CLASSID ]\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n");
|
fprintf(stderr, "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n");
|
||||||
fprintf(stderr, " MATCH := [ indev DEV-NAME | \n");
|
fprintf(stderr, " MATCH := { indev DEV-NAME | \n");
|
||||||
fprintf(stderr, " dst_mac MAC-ADDR | \n");
|
fprintf(stderr, " dst_mac MAC-ADDR | \n");
|
||||||
fprintf(stderr, " src_mac MAC-ADDR | \n");
|
fprintf(stderr, " src_mac MAC-ADDR | \n");
|
||||||
fprintf(stderr, " eth_type [ipv4 | ipv6 | ETH-TYPE ] | \n");
|
fprintf(stderr, " eth_type [ipv4 | ipv6 | ETH-TYPE ] | \n");
|
||||||
|
|
@ -36,7 +36,7 @@ static void explain(void)
|
||||||
fprintf(stderr, " dst_ip [ IPV4-ADDR | IPV6-ADDR ] | \n");
|
fprintf(stderr, " dst_ip [ IPV4-ADDR | IPV6-ADDR ] | \n");
|
||||||
fprintf(stderr, " src_ip [ IPV4-ADDR | IPV6-ADDR ] | \n");
|
fprintf(stderr, " src_ip [ IPV4-ADDR | IPV6-ADDR ] | \n");
|
||||||
fprintf(stderr, " dst_port PORT-NUMBER | \n");
|
fprintf(stderr, " dst_port PORT-NUMBER | \n");
|
||||||
fprintf(stderr, " src_port PORT-NUMBER | \n");
|
fprintf(stderr, " src_port PORT-NUMBER }\n");
|
||||||
fprintf(stderr, " FILTERID := X:Y:Z\n");
|
fprintf(stderr, " FILTERID := X:Y:Z\n");
|
||||||
fprintf(stderr, " ACTION-SPEC := ... look at individual actions\n");
|
fprintf(stderr, " ACTION-SPEC := ... look at individual actions\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
static void explain(void)
|
static void explain(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ... route [ from REALM | fromif TAG ] [ to REALM ]\n");
|
fprintf(stderr, "Usage: ... route [ from REALM | fromif TAG ] [ to REALM ]\n");
|
||||||
fprintf(stderr, " [ flowid CLASSID ] [ action ACTION_SPEC ]]\n");
|
fprintf(stderr, " [ classid CLASSID ] [ action ACTION_SPEC ]\n");
|
||||||
fprintf(stderr, " ACTION_SPEC := ... look at individual actions\n");
|
fprintf(stderr, " ACTION_SPEC := ... look at individual actions\n");
|
||||||
fprintf(stderr, " CLASSID := X:Y\n");
|
fprintf(stderr, " CLASSID := X:Y\n");
|
||||||
fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
|
fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
static void explain(void)
|
static void explain(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ... rsvp ipproto PROTOCOL session DST[/PORT | GPI ]\n");
|
fprintf(stderr, "Usage: ... rsvp ipproto PROTOCOL session DST[/PORT | GPI ]\n");
|
||||||
fprintf(stderr, " [ sender SRC[/PORT | GPI ]\n");
|
fprintf(stderr, " [ sender SRC[/PORT | GPI ] ]\n");
|
||||||
fprintf(stderr, " [ classid CLASSID ] [ action ACTION_SPEC ]\n");
|
fprintf(stderr, " [ classid CLASSID ] [ action ACTION_SPEC ]\n");
|
||||||
fprintf(stderr, " [ tunnelid ID ] [ tunnel ID skip NUMBER ]\n");
|
fprintf(stderr, " [ tunnelid ID ] [ tunnel ID skip NUMBER ]\n");
|
||||||
fprintf(stderr, "Where: GPI := { flowlabel NUMBER | spi/ah SPI | spi/esp SPI |\n");
|
fprintf(stderr, "Where: GPI := { flowlabel NUMBER | spi/ah SPI | spi/esp SPI |\n");
|
||||||
|
|
|
||||||
56
tc/f_u32.c
56
tc/f_u32.c
|
|
@ -61,14 +61,14 @@ static int get_u32_handle(__u32 *handle, const char *str)
|
||||||
if (htid>=0x1000)
|
if (htid>=0x1000)
|
||||||
return -1;
|
return -1;
|
||||||
if (*tmp) {
|
if (*tmp) {
|
||||||
str = tmp+1;
|
str = tmp + 1;
|
||||||
hash = strtoul(str, &tmp, 16);
|
hash = strtoul(str, &tmp, 16);
|
||||||
if (tmp == str && *str != ':' && *str != 0)
|
if (tmp == str && *str != ':' && *str != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (hash>=0x100)
|
if (hash>=0x100)
|
||||||
return -1;
|
return -1;
|
||||||
if (*tmp) {
|
if (*tmp) {
|
||||||
str = tmp+1;
|
str = tmp + 1;
|
||||||
nodeid = strtoul(str, &tmp, 16);
|
nodeid = strtoul(str, &tmp, 16);
|
||||||
if (tmp == str && *str != 0)
|
if (tmp == str && *str != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -124,9 +124,9 @@ static int pack_key(struct tc_u32_sel *sel, __u32 key, __u32 mask,
|
||||||
|
|
||||||
for (i=0; i<hwm; i++) {
|
for (i=0; i<hwm; i++) {
|
||||||
if (sel->keys[i].off == off && sel->keys[i].offmask == offmask) {
|
if (sel->keys[i].off == off && sel->keys[i].offmask == offmask) {
|
||||||
__u32 intersect = mask&sel->keys[i].mask;
|
__u32 intersect = mask & sel->keys[i].mask;
|
||||||
|
|
||||||
if ((key^sel->keys[i].val) & intersect)
|
if ((key ^ sel->keys[i].val) & intersect)
|
||||||
return -1;
|
return -1;
|
||||||
sel->keys[i].val |= key;
|
sel->keys[i].val |= key;
|
||||||
sel->keys[i].mask |= mask;
|
sel->keys[i].mask |= mask;
|
||||||
|
|
@ -346,7 +346,7 @@ static int parse_ip_addr(int *argc_p, char ***argv_p, struct tc_u32_sel *sel,
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (addr.bitlen)
|
if (addr.bitlen)
|
||||||
mask = htonl(0xFFFFFFFF<<(32-addr.bitlen));
|
mask = htonl(0xFFFFFFFF << (32 - addr.bitlen));
|
||||||
if (pack_key(sel, addr.data[0], mask, off, offmask) < 0)
|
if (pack_key(sel, addr.data[0], mask, off, offmask) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
@ -381,17 +381,17 @@ static int parse_ip6_addr(int *argc_p, char ***argv_p,
|
||||||
}
|
}
|
||||||
|
|
||||||
plen = addr.bitlen;
|
plen = addr.bitlen;
|
||||||
for (i=0; i<plen; i+=32) {
|
for (i = 0; i < plen; i += 32) {
|
||||||
// if (((i+31)&~0x1F)<=plen) {
|
// if (((i + 31) & ~0x1F) <= plen) {
|
||||||
if (i + 31 <= plen) {
|
if (i + 31 <= plen) {
|
||||||
res = pack_key(sel, addr.data[i/32],
|
res = pack_key(sel, addr.data[i / 32],
|
||||||
0xFFFFFFFF, off+4*(i/32), offmask);
|
0xFFFFFFFF, off + 4 * (i / 32), offmask);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if (i < plen) {
|
} else if (i < plen) {
|
||||||
__u32 mask = htonl(0xFFFFFFFF << (32 - (plen -i )));
|
__u32 mask = htonl(0xFFFFFFFF << (32 - (plen - i)));
|
||||||
res = pack_key(sel, addr.data[i/32],
|
res = pack_key(sel, addr.data[i / 32],
|
||||||
mask, off+4*(i/32), offmask);
|
mask, off + 4 * (i / 32), offmask);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -496,7 +496,8 @@ static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
res = parse_ip_addr(&argc, &argv, sel, 16);
|
res = parse_ip_addr(&argc, &argv, sel, 16);
|
||||||
} else if (strcmp(*argv, "tos") == 0 ||
|
} else if (strcmp(*argv, "tos") == 0 ||
|
||||||
matches(*argv, "dsfield") == 0) {
|
matches(*argv, "dsfield") == 0 ||
|
||||||
|
matches(*argv, "precedence") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
res = parse_u8(&argc, &argv, sel, 1, 0);
|
res = parse_u8(&argc, &argv, sel, 1, 0);
|
||||||
} else if (strcmp(*argv, "ihl") == 0) {
|
} else if (strcmp(*argv, "ihl") == 0) {
|
||||||
|
|
@ -505,9 +506,6 @@ static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
} else if (strcmp(*argv, "protocol") == 0) {
|
} else if (strcmp(*argv, "protocol") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
res = parse_u8(&argc, &argv, sel, 9, 0);
|
res = parse_u8(&argc, &argv, sel, 9, 0);
|
||||||
} else if (matches(*argv, "precedence") == 0) {
|
|
||||||
NEXT_ARG();
|
|
||||||
res = parse_u8(&argc, &argv, sel, 1, 0);
|
|
||||||
} else if (strcmp(*argv, "nofrag") == 0) {
|
} else if (strcmp(*argv, "nofrag") == 0) {
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
res = pack_key16(sel, 0, 0x3FFF, 6, 0);
|
res = pack_key16(sel, 0, 0x3FFF, 6, 0);
|
||||||
|
|
@ -1072,9 +1070,9 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (sample_ok)
|
if (sample_ok)
|
||||||
htid = (htid&0xFF000)|(handle&0xFFF00000);
|
htid = (htid & 0xFF000) | (handle & 0xFFF00000);
|
||||||
else
|
else
|
||||||
htid = (handle&0xFFFFF000);
|
htid = (handle & 0xFFFFF000);
|
||||||
} else if (strcmp(*argv, "sample") == 0) {
|
} else if (strcmp(*argv, "sample") == 0) {
|
||||||
__u32 hash;
|
__u32 hash;
|
||||||
unsigned divisor = 0x100;
|
unsigned divisor = 0x100;
|
||||||
|
|
@ -1103,10 +1101,10 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
|
||||||
}
|
}
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
}
|
}
|
||||||
hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
|
hash = sel2.sel.keys[0].val & sel2.sel.keys[0].mask;
|
||||||
hash ^= hash>>16;
|
hash ^= hash >> 16;
|
||||||
hash ^= hash>>8;
|
hash ^= hash >> 8;
|
||||||
htid = ((hash%divisor)<<12)|(htid&0xFFF00000);
|
htid = ((hash % divisor) << 12) | (htid & 0xFFF00000);
|
||||||
sample_ok = 1;
|
sample_ok = 1;
|
||||||
continue;
|
continue;
|
||||||
} else if (strcmp(*argv, "indev") == 0) {
|
} else if (strcmp(*argv, "indev") == 0) {
|
||||||
|
|
@ -1165,7 +1163,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
|
||||||
addattr_l(n, MAX_MSG, TCA_U32_HASH, &htid, 4);
|
addattr_l(n, MAX_MSG, TCA_U32_HASH, &htid, 4);
|
||||||
if (sel_ok)
|
if (sel_ok)
|
||||||
addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel,
|
addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel,
|
||||||
sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_u32_key));
|
sizeof(sel.sel) + sel.sel.nkeys * sizeof(struct tc_u32_key));
|
||||||
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
|
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1173,7 +1171,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
|
||||||
static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
|
static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
|
||||||
__u32 handle)
|
__u32 handle)
|
||||||
{
|
{
|
||||||
struct rtattr *tb[TCA_U32_MAX+1];
|
struct rtattr *tb[TCA_U32_MAX + 1];
|
||||||
struct tc_u32_sel *sel = NULL;
|
struct tc_u32_sel *sel = NULL;
|
||||||
struct tc_u32_pcnt *pf = NULL;
|
struct tc_u32_pcnt *pf = NULL;
|
||||||
|
|
||||||
|
|
@ -1209,9 +1207,9 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
|
||||||
if (tb[TCA_U32_CLASSID]) {
|
if (tb[TCA_U32_CLASSID]) {
|
||||||
SPRINT_BUF(b1);
|
SPRINT_BUF(b1);
|
||||||
fprintf(f, "%sflowid %s ",
|
fprintf(f, "%sflowid %s ",
|
||||||
!sel || !(sel->flags&TC_U32_TERMINAL) ? "*" : "",
|
!sel || !(sel->flags & TC_U32_TERMINAL) ? "*" : "",
|
||||||
sprint_tc_classid(rta_getattr_u32(tb[TCA_U32_CLASSID]), b1));
|
sprint_tc_classid(rta_getattr_u32(tb[TCA_U32_CLASSID]), b1));
|
||||||
} else if (sel && sel->flags&TC_U32_TERMINAL) {
|
} else if (sel && sel->flags & TC_U32_TERMINAL) {
|
||||||
fprintf(f, "terminal flowid ??? ");
|
fprintf(f, "terminal flowid ??? ");
|
||||||
}
|
}
|
||||||
if (tb[TCA_U32_LINK]) {
|
if (tb[TCA_U32_LINK]) {
|
||||||
|
|
@ -1254,16 +1252,16 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sel->flags&(TC_U32_VAROFFSET|TC_U32_OFFSET)) {
|
if (sel->flags & (TC_U32_VAROFFSET | TC_U32_OFFSET)) {
|
||||||
fprintf(f, "\n offset ");
|
fprintf(f, "\n offset ");
|
||||||
if (sel->flags&TC_U32_VAROFFSET)
|
if (sel->flags & TC_U32_VAROFFSET)
|
||||||
fprintf(f, "%04x>>%d at %d ",
|
fprintf(f, "%04x>>%d at %d ",
|
||||||
ntohs(sel->offmask),
|
ntohs(sel->offmask),
|
||||||
sel->offshift, sel->offoff);
|
sel->offshift, sel->offoff);
|
||||||
if (sel->off)
|
if (sel->off)
|
||||||
fprintf(f, "plus %d ", sel->off);
|
fprintf(f, "plus %d ", sel->off);
|
||||||
}
|
}
|
||||||
if (sel->flags&TC_U32_EAT)
|
if (sel->flags & TC_U32_EAT)
|
||||||
fprintf(f, " eat ");
|
fprintf(f, " eat ");
|
||||||
|
|
||||||
if (sel->hmask) {
|
if (sel->hmask) {
|
||||||
|
|
|
||||||
|
|
@ -648,4 +648,3 @@ int do_action(int argc, char **argv)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -618,4 +618,3 @@ struct action_util ipt_action_util = {
|
||||||
.parse_aopt = parse_ipt,
|
.parse_aopt = parse_ipt,
|
||||||
.print_aopt = print_ipt,
|
.print_aopt = print_ipt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -433,4 +433,3 @@ struct action_util ipt_action_util = {
|
||||||
.parse_aopt = parse_ipt,
|
.parse_aopt = parse_ipt,
|
||||||
.print_aopt = print_ipt,
|
.print_aopt = print_ipt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,3 @@ struct m_pedit_util p_pedit_tcp = {
|
||||||
"tcp",
|
"tcp",
|
||||||
parse_tcp,
|
parse_tcp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,3 @@ struct m_pedit_util p_pedit_udp = {
|
||||||
"udp",
|
"udp",
|
||||||
parse_udp,
|
parse_udp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -582,4 +582,3 @@ struct qdisc_util cbq_qdisc_util = {
|
||||||
.parse_copt = cbq_parse_class_opt,
|
.parse_copt = cbq_parse_class_opt,
|
||||||
.print_copt = cbq_print_opt,
|
.print_copt = cbq_print_opt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -688,4 +688,3 @@ struct qdisc_util netem_qdisc_util = {
|
||||||
.parse_qopt = netem_parse_opt,
|
.parse_qopt = netem_parse_opt,
|
||||||
.print_qopt = netem_print_opt,
|
.print_qopt = netem_print_opt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,4 +122,3 @@ struct qdisc_util prio_qdisc_util = {
|
||||||
.parse_qopt = prio_parse_opt,
|
.parse_qopt = prio_parse_opt,
|
||||||
.print_qopt = prio_print_opt,
|
.print_qopt = prio_print_opt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -328,4 +328,3 @@ struct qdisc_util tbf_qdisc_util = {
|
||||||
.parse_qopt = tbf_parse_opt,
|
.parse_qopt = tbf_parse_opt,
|
||||||
.print_qopt = tbf_print_opt,
|
.print_qopt = tbf_print_opt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -375,4 +375,3 @@ int do_filter(int argc, char **argv)
|
||||||
fprintf(stderr, "Command \"%s\" is unknown, try \"tc filter help\".\n", *argv);
|
fprintf(stderr, "Command \"%s\" is unknown, try \"tc filter help\".\n", *argv);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,4 +148,3 @@ void print_size_table(FILE *fp, const char *prefix, struct rtattr *rta)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -608,4 +608,3 @@ compat_xstats:
|
||||||
if (tb[TCA_XSTATS] && xstats)
|
if (tb[TCA_XSTATS] && xstats)
|
||||||
*xstats = tb[TCA_XSTATS];
|
*xstats = tb[TCA_XSTATS];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue