Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
iproute2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
iproute2
Commits
a37c7472
Commit
a37c7472
authored
Feb 10, 2014
by
Stephen Hemminger
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'net-next-for-3.13'
parents
514cdfb4
8c452755
Changes
22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1102 additions
and
67 deletions
+1102
-67
include/linux/if_addr.h
include/linux/if_addr.h
+6
-0
include/linux/if_arp.h
include/linux/if_arp.h
+1
-0
include/linux/if_link.h
include/linux/if_link.h
+45
-0
include/linux/netconf.h
include/linux/netconf.h
+1
-0
include/linux/netfilter.h
include/linux/netfilter.h
+1
-0
include/linux/pkt_sched.h
include/linux/pkt_sched.h
+53
-0
include/linux/tc_act/tc_ipt.h
include/linux/tc_act/tc_ipt.h
+1
-0
include/linux/tcp_metrics.h
include/linux/tcp_metrics.h
+2
-0
ip/ipaddress.c
ip/ipaddress.c
+49
-15
ip/iplink_bond.c
ip/iplink_bond.c
+451
-7
ip/ipnetconf.c
ip/ipnetconf.c
+4
-0
man/man8/Makefile
man/man8/Makefile
+1
-1
man/man8/tc-pie.8
man/man8/tc-pie.8
+131
-0
tc/Makefile
tc/Makefile
+1
-0
tc/q_htb.c
tc/q_htb.c
+42
-14
tc/q_netem.c
tc/q_netem.c
+24
-5
tc/q_pie.c
tc/q_pie.c
+218
-0
tc/q_tbf.c
tc/q_tbf.c
+40
-20
tc/tc_core.c
tc/tc_core.c
+3
-3
tc/tc_core.h
tc/tc_core.h
+2
-2
tc/tc_util.c
tc/tc_util.c
+25
-0
tc/tc_util.h
tc/tc_util.h
+1
-0
No files found.
include/linux/if_addr.h
View file @
a37c7472
...
...
@@ -18,6 +18,9 @@ struct ifaddrmsg {
* It makes no difference for normally configured broadcast interfaces,
* but for point-to-point IFA_ADDRESS is DESTINATION address,
* local address is supplied in IFA_LOCAL attribute.
*
* IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
* If present, the value from struct ifaddrmsg will be ignored.
*/
enum
{
IFA_UNSPEC
,
...
...
@@ -28,6 +31,7 @@ enum {
IFA_ANYCAST
,
IFA_CACHEINFO
,
IFA_MULTICAST
,
IFA_FLAGS
,
__IFA_MAX
,
};
...
...
@@ -44,6 +48,8 @@ enum {
#define IFA_F_DEPRECATED 0x20
#define IFA_F_TENTATIVE 0x40
#define IFA_F_PERMANENT 0x80
#define IFA_F_MANAGETEMPADDR 0x100
#define IFA_F_NOPREFIXROUTE 0x200
struct
ifa_cacheinfo
{
__u32
ifa_prefered
;
...
...
include/linux/if_arp.h
View file @
a37c7472
...
...
@@ -94,6 +94,7 @@
#define ARPHRD_CAIF 822
/* CAIF media type */
#define ARPHRD_IP6GRE 823
/* GRE over IPv6 */
#define ARPHRD_NETLINK 824
/* Netlink header */
#define ARPHRD_6LOWPAN 825
/* IPv6 over LoWPAN */
#define ARPHRD_VOID 0xFFFF
/* Void type, nothing is known */
#define ARPHRD_NONE 0xFFFE
/* zero header length */
...
...
include/linux/if_link.h
View file @
a37c7472
...
...
@@ -144,6 +144,7 @@ enum {
IFLA_NUM_RX_QUEUES
,
IFLA_CARRIER
,
IFLA_PHYS_PORT_ID
,
IFLA_SLAVE
,
__IFLA_MAX
};
...
...
@@ -329,11 +330,55 @@ enum {
IFLA_BOND_UNSPEC
,
IFLA_BOND_MODE
,
IFLA_BOND_ACTIVE_SLAVE
,
IFLA_BOND_MIIMON
,
IFLA_BOND_UPDELAY
,
IFLA_BOND_DOWNDELAY
,
IFLA_BOND_USE_CARRIER
,
IFLA_BOND_ARP_INTERVAL
,
IFLA_BOND_ARP_IP_TARGET
,
IFLA_BOND_ARP_VALIDATE
,
IFLA_BOND_ARP_ALL_TARGETS
,
IFLA_BOND_PRIMARY
,
IFLA_BOND_PRIMARY_RESELECT
,
IFLA_BOND_FAIL_OVER_MAC
,
IFLA_BOND_XMIT_HASH_POLICY
,
IFLA_BOND_RESEND_IGMP
,
IFLA_BOND_NUM_PEER_NOTIF
,
IFLA_BOND_ALL_SLAVES_ACTIVE
,
IFLA_BOND_MIN_LINKS
,
IFLA_BOND_LP_INTERVAL
,
IFLA_BOND_PACKETS_PER_SLAVE
,
IFLA_BOND_AD_LACP_RATE
,
IFLA_BOND_AD_SELECT
,
IFLA_BOND_AD_INFO
,
__IFLA_BOND_MAX
,
};
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
enum
{
IFLA_BOND_AD_INFO_AGGREGATOR
,
IFLA_BOND_AD_INFO_NUM_PORTS
,
IFLA_BOND_AD_INFO_ACTOR_KEY
,
IFLA_BOND_AD_INFO_PARTNER_KEY
,
IFLA_BOND_AD_INFO_PARTNER_MAC
,
__IFLA_BOND_AD_INFO_MAX
,
};
#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1)
enum
{
IFLA_SLAVE_STATE
,
IFLA_SLAVE_MII_STATUS
,
IFLA_SLAVE_LINK_FAILURE_COUNT
,
IFLA_SLAVE_PERM_HWADDR
,
IFLA_SLAVE_QUEUE_ID
,
IFLA_SLAVE_AD_AGGREGATOR_ID
,
__IFLA_SLAVE_MAX
,
};
#define IFLA_SLAVE_MAX (__IFLA_SLAVE_MAX - 1)
/* SR-IOV virtual function management section */
enum
{
...
...
include/linux/netconf.h
View file @
a37c7472
...
...
@@ -14,6 +14,7 @@ enum {
NETCONFA_FORWARDING
,
NETCONFA_RP_FILTER
,
NETCONFA_MC_FORWARDING
,
NETCONFA_PROXY_NEIGH
,
__NETCONFA_MAX
};
#define NETCONFA_MAX (__NETCONFA_MAX - 1)
...
...
include/linux/netfilter.h
View file @
a37c7472
...
...
@@ -51,6 +51,7 @@ enum nf_inet_hooks {
enum
{
NFPROTO_UNSPEC
=
0
,
NFPROTO_INET
=
1
,
NFPROTO_IPV4
=
2
,
NFPROTO_ARP
=
3
,
NFPROTO_BRIDGE
=
7
,
...
...
include/linux/pkt_sched.h
View file @
a37c7472
...
...
@@ -173,6 +173,8 @@ enum {
TCA_TBF_PTAB
,
TCA_TBF_RATE64
,
TCA_TBF_PRATE64
,
TCA_TBF_BURST
,
TCA_TBF_PBURST
,
__TCA_TBF_MAX
,
};
...
...
@@ -523,6 +525,7 @@ enum {
TCA_NETEM_LOSS
,
TCA_NETEM_RATE
,
TCA_NETEM_ECN
,
TCA_NETEM_RATE64
,
__TCA_NETEM_MAX
,
};
...
...
@@ -790,4 +793,54 @@ struct tc_fq_qd_stats {
__u32
throttled_flows
;
__u32
pad
;
};
/* Heavy-Hitter Filter */
enum
{
TCA_HHF_UNSPEC
,
TCA_HHF_BACKLOG_LIMIT
,
TCA_HHF_QUANTUM
,
TCA_HHF_HH_FLOWS_LIMIT
,
TCA_HHF_RESET_TIMEOUT
,
TCA_HHF_ADMIT_BYTES
,
TCA_HHF_EVICT_TIMEOUT
,
TCA_HHF_NON_HH_WEIGHT
,
__TCA_HHF_MAX
};
#define TCA_HHF_MAX (__TCA_HHF_MAX - 1)
struct
tc_hhf_xstats
{
__u32
drop_overlimit
;
/* number of times max qdisc packet limit
* was hit
*/
__u32
hh_overlimit
;
/* number of times max heavy-hitters was hit */
__u32
hh_tot_count
;
/* number of captured heavy-hitters so far */
__u32
hh_cur_count
;
/* number of current heavy-hitters */
};
/* PIE */
enum
{
TCA_PIE_UNSPEC
,
TCA_PIE_TARGET
,
TCA_PIE_LIMIT
,
TCA_PIE_TUPDATE
,
TCA_PIE_ALPHA
,
TCA_PIE_BETA
,
TCA_PIE_ECN
,
TCA_PIE_BYTEMODE
,
__TCA_PIE_MAX
};
#define TCA_PIE_MAX (__TCA_PIE_MAX - 1)
struct
tc_pie_xstats
{
__u32
prob
;
/* current probability */
__u32
delay
;
/* current delay in ms */
__u32
avg_dq_rate
;
/* current average dq_rate in bits/pie_time */
__u32
packets_in
;
/* total number of packets enqueued */
__u32
dropped
;
/* packets dropped due to pie_action */
__u32
overlimit
;
/* dropped due to lack of space in queue */
__u32
maxq
;
/* maximum queue size */
__u32
ecn_mark
;
/* packets marked with ecn*/
};
#endif
include/linux/tc_act/tc_ipt.h
View file @
a37c7472
...
...
@@ -4,6 +4,7 @@
#include <linux/pkt_cls.h>
#define TCA_ACT_IPT 6
#define TCA_ACT_XT 10
enum
{
TCA_IPT_UNSPEC
,
...
...
include/linux/tcp_metrics.h
View file @
a37c7472
...
...
@@ -35,6 +35,8 @@ enum {
TCP_METRICS_ATTR_FOPEN_SYN_DROPS
,
/* u16, count of drops */
TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS
,
/* msecs age */
TCP_METRICS_ATTR_FOPEN_COOKIE
,
/* binary */
TCP_METRICS_ATTR_SADDR_IPV4
,
/* u32 */
TCP_METRICS_ATTR_SADDR_IPV6
,
/* binary */
__TCP_METRICS_ATTR_MAX
,
};
...
...
ip/ipaddress.c
View file @
a37c7472
...
...
@@ -82,7 +82,7 @@ static void usage(void)
fprintf
(
stderr
,
" tentative | deprecated | dadfailed | temporary |
\n
"
);
fprintf
(
stderr
,
" CONFFLAG-LIST ]
\n
"
);
fprintf
(
stderr
,
"CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG
\n
"
);
fprintf
(
stderr
,
"CONFFLAG := [ home | nodad ]
\n
"
);
fprintf
(
stderr
,
"CONFFLAG := [ home | nodad
| mngtmpaddr | noprefixroute
]
\n
"
);
fprintf
(
stderr
,
"LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]
\n
"
);
fprintf
(
stderr
,
"LFT := forever | SECONDS
\n
"
);
...
...
@@ -541,6 +541,13 @@ static int set_lifetime(unsigned int *lifetime, char *argv)
return
0
;
}
static
unsigned
int
get_ifa_flags
(
struct
ifaddrmsg
*
ifa
,
struct
rtattr
*
ifa_flags_attr
)
{
return
ifa_flags_attr
?
rta_getattr_u32
(
ifa_flags_attr
)
:
ifa
->
ifa_flags
;
}
int
print_addrinfo
(
const
struct
sockaddr_nl
*
who
,
struct
nlmsghdr
*
n
,
void
*
arg
)
{
...
...
@@ -567,6 +574,8 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
parse_rtattr
(
rta_tb
,
IFA_MAX
,
IFA_RTA
(
ifa
),
n
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
ifa
)));
ifa_flags
=
get_ifa_flags
(
ifa
,
rta_tb
[
IFA_FLAGS
]);
if
(
!
rta_tb
[
IFA_LOCAL
])
rta_tb
[
IFA_LOCAL
]
=
rta_tb
[
IFA_ADDRESS
];
if
(
!
rta_tb
[
IFA_ADDRESS
])
...
...
@@ -576,7 +585,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
return
0
;
if
((
filter
.
scope
^
ifa
->
ifa_scope
)
&
filter
.
scopemask
)
return
0
;
if
((
filter
.
flags
^
ifa
->
ifa_flags
)
&
filter
.
flagmask
)
if
((
filter
.
flags
^
ifa_flags
)
&
filter
.
flagmask
)
return
0
;
if
(
filter
.
label
)
{
SPRINT_BUF
(
b1
);
...
...
@@ -670,36 +679,43 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
abuf
,
sizeof
(
abuf
)));
}
fprintf
(
fp
,
"scope %s "
,
rtnl_rtscope_n2a
(
ifa
->
ifa_scope
,
b1
,
sizeof
(
b1
)));
ifa_flags
=
ifa
->
ifa_flags
;
if
(
ifa
->
ifa_flags
&
IFA_F_SECONDARY
)
{
if
(
ifa_flags
&
IFA_F_SECONDARY
)
{
ifa_flags
&=
~
IFA_F_SECONDARY
;
if
(
ifa
->
ifa_family
==
AF_INET6
)
fprintf
(
fp
,
"temporary "
);
else
fprintf
(
fp
,
"secondary "
);
}
if
(
ifa
->
ifa_flags
&
IFA_F_TENTATIVE
)
{
if
(
ifa
_flags
&
IFA_F_TENTATIVE
)
{
ifa_flags
&=
~
IFA_F_TENTATIVE
;
fprintf
(
fp
,
"tentative "
);
}
if
(
ifa
->
ifa_flags
&
IFA_F_DEPRECATED
)
{
if
(
ifa
_flags
&
IFA_F_DEPRECATED
)
{
ifa_flags
&=
~
IFA_F_DEPRECATED
;
deprecated
=
1
;
fprintf
(
fp
,
"deprecated "
);
}
if
(
ifa
->
ifa_flags
&
IFA_F_HOMEADDRESS
)
{
if
(
ifa
_flags
&
IFA_F_HOMEADDRESS
)
{
ifa_flags
&=
~
IFA_F_HOMEADDRESS
;
fprintf
(
fp
,
"home "
);
}
if
(
ifa
->
ifa_flags
&
IFA_F_NODAD
)
{
if
(
ifa
_flags
&
IFA_F_NODAD
)
{
ifa_flags
&=
~
IFA_F_NODAD
;
fprintf
(
fp
,
"nodad "
);
}
if
(
!
(
ifa
->
ifa_flags
&
IFA_F_PERMANENT
))
{
if
(
ifa_flags
&
IFA_F_MANAGETEMPADDR
)
{
ifa_flags
&=
~
IFA_F_MANAGETEMPADDR
;
fprintf
(
fp
,
"mngtmpaddr "
);
}
if
(
ifa_flags
&
IFA_F_NOPREFIXROUTE
)
{
ifa_flags
&=
~
IFA_F_NOPREFIXROUTE
;
fprintf
(
fp
,
"noprefixroute "
);
}
if
(
!
(
ifa_flags
&
IFA_F_PERMANENT
))
{
fprintf
(
fp
,
"dynamic "
);
}
else
ifa_flags
&=
~
IFA_F_PERMANENT
;
if
(
ifa
->
ifa_flags
&
IFA_F_DADFAILED
)
{
if
(
ifa
_flags
&
IFA_F_DADFAILED
)
{
ifa_flags
&=
~
IFA_F_DADFAILED
;
fprintf
(
fp
,
"dadfailed "
);
}
...
...
@@ -926,6 +942,8 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
for
(
a
=
ainfo
->
head
;
a
;
a
=
a
->
next
)
{
struct
nlmsghdr
*
n
=
&
a
->
h
;
struct
ifaddrmsg
*
ifa
=
NLMSG_DATA
(
n
);
struct
rtattr
*
tb
[
IFA_MAX
+
1
];
unsigned
int
ifa_flags
;
if
(
ifa
->
ifa_index
!=
ifi
->
ifi_index
)
continue
;
...
...
@@ -934,11 +952,13 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
continue
;
if
((
filter
.
scope
^
ifa
->
ifa_scope
)
&
filter
.
scopemask
)
continue
;
if
((
filter
.
flags
^
ifa
->
ifa_flags
)
&
filter
.
flagmask
)
parse_rtattr
(
tb
,
IFA_MAX
,
IFA_RTA
(
ifa
),
IFA_PAYLOAD
(
n
));
ifa_flags
=
get_ifa_flags
(
ifa
,
tb
[
IFA_FLAGS
]);
if
((
filter
.
flags
^
ifa_flags
)
&
filter
.
flagmask
)
continue
;
if
(
filter
.
pfx
.
family
||
filter
.
label
)
{
struct
rtattr
*
tb
[
IFA_MAX
+
1
];
parse_rtattr
(
tb
,
IFA_MAX
,
IFA_RTA
(
ifa
),
IFA_PAYLOAD
(
n
));
if
(
!
tb
[
IFA_LOCAL
])
tb
[
IFA_LOCAL
]
=
tb
[
IFA_ADDRESS
];
...
...
@@ -1114,6 +1134,12 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
}
else
if
(
strcmp
(
*
argv
,
"nodad"
)
==
0
)
{
filter
.
flags
|=
IFA_F_NODAD
;
filter
.
flagmask
|=
IFA_F_NODAD
;
}
else
if
(
strcmp
(
*
argv
,
"mngtmpaddr"
)
==
0
)
{
filter
.
flags
|=
IFA_F_MANAGETEMPADDR
;
filter
.
flagmask
|=
IFA_F_MANAGETEMPADDR
;
}
else
if
(
strcmp
(
*
argv
,
"noprefixroute"
)
==
0
)
{
filter
.
flags
|=
IFA_F_NOPREFIXROUTE
;
filter
.
flagmask
|=
IFA_F_NOPREFIXROUTE
;
}
else
if
(
strcmp
(
*
argv
,
"dadfailed"
)
==
0
)
{
filter
.
flags
|=
IFA_F_DADFAILED
;
filter
.
flagmask
|=
IFA_F_DADFAILED
;
...
...
@@ -1252,6 +1278,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
__u32
preferred_lft
=
INFINITY_LIFE_TIME
;
__u32
valid_lft
=
INFINITY_LIFE_TIME
;
struct
ifa_cacheinfo
cinfo
;
unsigned
int
ifa_flags
=
0
;
memset
(
&
req
,
0
,
sizeof
(
req
));
...
...
@@ -1329,9 +1356,13 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
if
(
set_lifetime
(
&
preferred_lft
,
*
argv
))
invarg
(
"preferred_lft value"
,
*
argv
);
}
else
if
(
strcmp
(
*
argv
,
"home"
)
==
0
)
{
req
.
ifa
.
ifa_flags
|=
IFA_F_HOMEADDRESS
;
ifa_flags
|=
IFA_F_HOMEADDRESS
;
}
else
if
(
strcmp
(
*
argv
,
"nodad"
)
==
0
)
{
req
.
ifa
.
ifa_flags
|=
IFA_F_NODAD
;
ifa_flags
|=
IFA_F_NODAD
;
}
else
if
(
strcmp
(
*
argv
,
"mngtmpaddr"
)
==
0
)
{
ifa_flags
|=
IFA_F_MANAGETEMPADDR
;
}
else
if
(
strcmp
(
*
argv
,
"noprefixroute"
)
==
0
)
{
ifa_flags
|=
IFA_F_NOPREFIXROUTE
;
}
else
{
if
(
strcmp
(
*
argv
,
"local"
)
==
0
)
{
NEXT_ARG
();
...
...
@@ -1349,6 +1380,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
argc
--
;
argv
++
;
}
req
.
ifa
.
ifa_flags
=
ifa_flags
;
addattr32
(
&
req
.
n
,
sizeof
(
req
),
IFA_FLAGS
,
ifa_flags
);
if
(
d
==
NULL
)
{
fprintf
(
stderr
,
"Not enough information:
\"
dev
\"
argument is required.
\n
"
);
return
-
1
;
...
...
ip/iplink_bond.c
View file @
a37c7472
This diff is collapsed.
Click to expand it.
ip/ipnetconf.c
View file @
a37c7472
...
...
@@ -114,6 +114,10 @@ int print_netconf(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf
(
fp
,
"mc_forwarding %d "
,
*
(
int
*
)
RTA_DATA
(
tb
[
NETCONFA_MC_FORWARDING
]));
if
(
tb
[
NETCONFA_PROXY_NEIGH
])
fprintf
(
fp
,
"proxy_neigh %s "
,
*
(
int
*
)
RTA_DATA
(
tb
[
NETCONFA_PROXY_NEIGH
])
?
"on"
:
"off"
);
fprintf
(
fp
,
"
\n
"
);
fflush
(
fp
);
return
0
;
...
...
man/man8/Makefile
View file @
a37c7472
...
...
@@ -2,7 +2,7 @@ TARGETS = ip-address.8 ip-link.8 ip-route.8
MAN8PAGES
=
$(TARGETS)
ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 ss.8
\
tc.8 tc-bfifo.8 tc-cbq.8 tc-cbq-details.8 tc-choke.8 tc-codel.8
\
tc-drr.8 tc-ematch.8 tc-fq_codel.8 tc-hfsc.8 tc-htb.8
\
tc-drr.8 tc-ematch.8 tc-fq_codel.8 tc-hfsc.8 tc-htb.8
tc-pie.8
\
tc-netem.8 tc-pfifo.8 tc-pfifo_fast.8 tc-prio.8 tc-red.8
\
tc-sfb.8 tc-sfq.8 tc-stab.8 tc-tbf.8
\
bridge.8 rtstat.8 ctstat.8 nstat.8 routef.8
\
...
...
man/man8/tc-pie.8
0 → 100644
View file @
a37c7472
.TH PIE 8 "16 January 2014" "iproute2" "Linux"
.SH NAME
PIE \- Proportional Integral controller-Enhanced AQM algorithm
.SH SYNOPSIS
.B tc qdisc ... pie
[
.B limit
PACKETS ] [
.B target
TIME ] [
.B tupdate
TIME ] [
.B alpha
int ] [
.B beta
int ] [
.B ecn
|
.B noecn
] [
.B bytemode
|
.B nobytemode
]
.SH DESCRIPTION
Proportional Integral controller-Enhanced (PIE) is a control theoretic active
queue management scheme. It is based on the proportional integral controller but
aims to control delay. The main design goals are
o Low latency control
o High link utilization
o Simple implementation
o Guaranteed stability and fast responsiveness
.SH ALGORITHM
PIE is designed to control delay effectively. First, an average dequeue rate is
estimated based on the standing queue. The rate is used to calculate the current
delay. Then, on a periodic basis, the delay is used to calculate the dropping
probabilty. Finally, on arrival, a packet is dropped (or marked) based on this
probability.
PIE makes adjustments to the probability based on the trend of the delay i.e.
whether it is going up or down.The delay converges quickly to the target value
specified.
alpha and beta are statically chosen parameters chosen to control the drop probability
growth and are determined through control theoretic approaches. alpha determines how
the deviation between the current and target latency changes probability. beta exerts
additional adjustments depending on the latency trend.
The drop probabilty is used to mark packets in ecn mode. However, as in RED,
beyond 10% packets are dropped based on this probability. The bytemode is used
to drop packets proportional to the packet size.
Additional details can be found in the paper cited below.
.SH PARAMETERS
.SS limit
limit on the queue size in packets. Incoming packets are dropped when this limit
is reached. Default is 1000 packets.
.SS target
is the expected queue delay. The default target delay is 20ms.
.SS tupdate
is the frequency at which the system drop probability is calculated. The default is 30ms.
.SS alpha
.SS beta
alpha and beta are parameters chosen to control the drop probability. These
should be in the range between 0 and 32.
.SS ecn | noecn
is used to mark packets instead of dropping
.B ecn
to turn on ecn mode,
.B noecn
to turn off ecn mode. By default,
.B ecn
is turned off.
.SS bytemode | nobytemode
is used to scale drop probability proportional to packet size
.B bytemode
to turn on bytemode,
.B nobytemode
to turn off bytemode. By default,
.B bytemode
is turned off.
.SH EXAMPLES
# tc qdisc add dev eth0 root pie
# tc -s qdisc show
qdisc pie 8034: dev eth0 root refcnt 2 limit 200p target 19000us tupdate 29000us alpha 2 beta 20
Sent 7443524 bytes 7204 pkt (dropped 900, overlimits 0 requeues 0)
backlog 38998b 37p requeues 0
prob 0.123384 delay 25000us avg_dq_rate 1464840
pkts_in 7241 overlimit 900 dropped 0 maxq 186 ecn_mark 0
# tc qdisc add dev eth0 root pie limit 100 target 20ms tupdate 30ms ecn
# tc -s qdisc show
qdisc pie 8036: dev eth0 root refcnt 2 limit 200p target 19000 tupdate 29000 alpha 2 beta 20 ecn
Sent 2491922 bytes 2507 pkt (dropped 214, overlimits 0 requeues 0)
backlog 33728b 32p requeues 0
prob 0.102262 delay 24000us avg_dq_rate 1464840
pkts_in 2468 overlimit 214 dropped 0 maxq 192 ecn_mark 71
# tc qdisc add dev eth0 root pie limit 100 target 50ms tupdate 30ms bytemode
# tc -s qdisc show
qdisc pie 8036: dev eth0 root refcnt 2 limit 200p target 19000 tupdate 29000 alpha 2 beta 20 ecn
Sent 2491922 bytes 2507 pkt (dropped 214, overlimits 0 requeues 0)
backlog 33728b 32p requeues 0
prob 0.102262 delay 24000us avg_dq_rate 1464840
pkts_in 2468 overlimit 214 dropped 0 maxq 192 ecn_mark 71
.SH SEE ALSO
.BR tc (8),
.BR tc-codel (8)
.BR tc-red (8)
.SH SOURCES
o IETF draft submission is at http://tools.ietf.org/html/draft-pan-tsvwg-pie-00
o IEEE Conference on High Performance Switching and Routing 2013 : "PIE: A
Lightweight Control Scheme to Address the Bufferbloat Problem"
.SH AUTHORS
PIE was implemented by Vijay Subramanian and Mythili Prabhu, also the authors of
this man page. Please report bugs and corrections to the Linux networking
development mailing list at <netdev@vger.kernel.org>.
tc/Makefile
View file @
a37c7472
...
...
@@ -53,6 +53,7 @@ TCMODULES += q_mqprio.o
TCMODULES
+=
q_codel.o
TCMODULES
+=
q_fq_codel.o
TCMODULES
+=
q_fq.o
TCMODULES
+=
q_pie.o
ifeq
($(TC_CONFIG_IPSET), y)
ifeq
($(TC_CONFIG_XT), y)
...
...
tc/q_htb.c
View file @
a37c7472
...
...
@@ -113,6 +113,7 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
unsigned
int
direct_qlen
=
~
0U
;
unsigned
int
linklayer
=
LINKLAYER_ETHERNET
;
/* Assume ethernet */
struct
rtattr
*
tail
;
__u64
ceil64
=
0
,
rate64
=
0
;
memset
(
&
opt
,
0
,
sizeof
(
opt
));
mtu
=
1600
;
/* eth packet len */
...
...
@@ -173,22 +174,22 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
ok
++
;
}
else
if
(
strcmp
(
*
argv
,
"ceil"
)
==
0
)
{
NEXT_ARG
();
if
(
opt
.
ceil
.
rate
)
{
if
(
ceil64
)
{
fprintf
(
stderr
,
"Double
\"
ceil
\"
spec
\n
"
);
return
-
1
;
}
if
(
get_rate
(
&
opt
.
ceil
.
rate
,
*
argv
))
{
if
(
get_rate
64
(
&
ceil64
,
*
argv
))
{
explain1
(
"ceil"
);
return
-
1
;
}
ok
++
;
}
else
if
(
strcmp
(
*
argv
,
"rate"
)
==
0
)
{
NEXT_ARG
();
if
(
opt
.
rate
.
rate
)
{
if
(
rate64
)
{
fprintf
(
stderr
,
"Double
\"
rate
\"
spec
\n
"
);
return
-
1
;
}
if
(
get_rate
(
&
opt
.
rate
.
rate
,
*
argv
))
{
if
(
get_rate
64
(
&
rate64
,
*
argv
))
{
explain1
(
"rate"
);
return
-
1
;
}
...
...
@@ -207,17 +208,23 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
/* if (!ok)
return 0;*/
if
(
opt
.
rate
.
rate
==
0
)
{
if
(
!
rate64
)
{
fprintf
(
stderr
,
"
\"
rate
\"
is required.
\n
"
);
return
-
1
;
}
/* if ceil params are missing, use the same as rate */
if
(
!
opt
.
ceil
.
rate
)
opt
.
ceil
=
opt
.
rate
;
if
(
!
ceil64
)
ceil64
=
rate64
;
opt
.
rate
.
rate
=
(
rate64
>=
(
1ULL
<<
32
))
?
~
0U
:
rate64
;
opt
.
ceil
.
rate
=
(
ceil64
>=
(
1ULL
<<
32
))
?
~
0U
:
ceil64
;
/* compute minimal allowed burst from rate; mtu is added here to make
sute that buffer is larger than mtu and to have some safeguard space */
if
(
!
buffer
)
buffer
=
opt
.
rate
.
rate
/
get_hz
()
+
mtu
;
if
(
!
cbuffer
)
cbuffer
=
opt
.
ceil
.
rate
/
get_hz
()
+
mtu
;
if
(
!
buffer
)
buffer
=
rate64
/
get_hz
()
+
mtu
;
if
(
!
cbuffer
)
cbuffer
=
ceil64
/
get_hz
()
+
mtu
;
opt
.
ceil
.
overhead
=
overhead
;
opt
.
rate
.
overhead
=
overhead
;
...
...
@@ -229,19 +236,26 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
fprintf
(
stderr
,
"htb: failed to calculate rate table.
\n
"
);
return
-
1
;
}
opt
.
buffer
=
tc_calc_xmittime
(
opt
.
rate
.
rate
,
buffer
);
opt
.
buffer
=
tc_calc_xmittime
(
rate64
,
buffer
);
if
(
tc_calc_rtable
(
&
opt
.
ceil
,
ctab
,
ccell_log
,
mtu
,
linklayer
)
<
0
)
{
fprintf
(
stderr
,
"htb: failed to calculate ceil rate table.
\n
"
);
return
-
1
;
}
opt
.
cbuffer
=
tc_calc_xmittime
(
opt
.
ceil
.
rate
,
cbuffer
);
opt
.
cbuffer
=
tc_calc_xmittime
(
ceil64
,
cbuffer
);
tail
=
NLMSG_TAIL
(
n
);
if
(
direct_qlen
!=
~
0U
)
addattr_l
(
n
,
1024
,
TCA_HTB_DIRECT_QLEN
,
&
direct_qlen
,
sizeof
(
direct_qlen
));
addattr_l
(
n
,
1024
,
TCA_OPTIONS
,
NULL
,
0
);
if
(
rate64
>=
(
1ULL
<<
32
))
addattr_l
(
n
,
1124
,
TCA_HTB_RATE64
,
&
rate64
,
sizeof
(
rate64
));
if
(
ceil64
>=
(
1ULL
<<
32
))
addattr_l
(
n
,
1224
,
TCA_HTB_CEIL64
,
&
ceil64
,
sizeof
(
ceil64
));
addattr_l
(
n
,
2024
,
TCA_HTB_PARMS
,
&
opt
,
sizeof
(
opt
));
addattr_l
(
n
,
3024
,
TCA_HTB_RTAB
,
rtab
,
1024
);
addattr_l
(
n
,
4024
,
TCA_HTB_CTAB
,
ctab
,
1024
);
...
...
@@ -256,6 +270,7 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
struct
tc_htb_glob
*
gopt
;
double
buffer
,
cbuffer
;
unsigned
int
linklayer
;
__u64
rate64
,
ceil64
;
SPRINT_BUF
(
b1
);
SPRINT_BUF
(
b2
);
SPRINT_BUF
(
b3
);
...
...
@@ -275,12 +290,25 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if
(
show_details
)
fprintf
(
f
,
"quantum %d "
,
(
int
)
hopt
->
quantum
);
}
fprintf
(
f
,
"rate %s "
,
sprint_rate
(
hopt
->
rate
.
rate
,
b1
));
rate64
=
hopt
->
rate
.
rate
;
if
(
tb
[
TCA_HTB_RATE64
]
&&
RTA_PAYLOAD
(
tb
[
TCA_HTB_RATE64
])
>=
sizeof
(
rate64
))
{
rate64
=
rta_getattr_u64
(
tb
[
TCA_HTB_RATE64
]);
}
ceil64
=
hopt
->
ceil
.
rate
;
if
(
tb
[
TCA_HTB_CEIL64
]
&&
RTA_PAYLOAD
(
tb
[
TCA_HTB_CEIL64
])
>=
sizeof
(
ceil64
))
ceil64
=
rta_getattr_u64
(
tb
[
TCA_HTB_CEIL64
]);
fprintf
(
f
,
"rate %s "
,
sprint_rate
(
rate64
,
b1
));
if
(
hopt
->
rate
.
overhead
)
fprintf
(
f
,
"overhead %u "
,
hopt
->
rate
.
overhead
);
buffer
=
tc_calc_xmitsize
(
hopt
->
rate
.
rate
,
hopt
->
buffer
);
fprintf
(
f
,
"ceil %s "
,
sprint_rate
(
hopt
->
ceil
.
rate
,
b1
));
cbuffer
=
tc_calc_xmitsize
(
hopt
->
ceil
.
rate
,
hopt
->
cbuffer
);
buffer
=
tc_calc_xmitsize
(
rate64
,
hopt
->
buffer
);
fprintf
(
f
,
"ceil %s "
,
sprint_rate
(
ceil64
,
b1
));
cbuffer
=
tc_calc_xmitsize
(
ceil64
,
hopt
->
cbuffer
);
linklayer
=
(
hopt
->
rate
.
linklayer
&
TC_LINKLAYER_MASK
);
if
(
linklayer
>
TC_LINKLAYER_ETHERNET
||
show_details
)
fprintf
(
f
,
"linklayer %s "
,
sprint_linklayer
(
linklayer
,
b4
));
...
...
tc/q_netem.c
View file @
a37c7472
...
...
@@ -183,6 +183,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
__s16
*
dist_data
=
NULL
;
__u16
loss_type
=
NETEM_LOSS_UNSPEC
;
int
present
[
__TCA_NETEM_MAX
];
__u64
rate64
=
0
;
memset
(
&
cor
,
0
,
sizeof
(
cor
));
memset
(
&
reorder
,
0
,
sizeof
(
reorder
));
...
...
@@ -391,7 +392,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
}
else
if
(
matches
(
*
argv
,
"rate"
)
==
0
)
{
++
present
[
TCA_NETEM_RATE
];
NEXT_ARG
();
if
(
get_rate
(
&
rate
.
rate
,
*
argv
))
{
if
(
get_rate
64
(
&
rate64
,
*
argv
))
{
explain1
(
"rate"
);
return
-
1
;
}
...
...
@@ -496,9 +497,18 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
addattr_nest_end
(
n
,
start
);
}
if
(
present
[
TCA_NETEM_RATE
]
&&
addattr_l
(
n
,
1024
,
TCA_NETEM_RATE
,
&
rate
,
sizeof
(
rate
))
<
0
)
return
-
1
;
if
(
present
[
TCA_NETEM_RATE
])
{
if
(
rate64
>=
(
1ULL
<<
32
))
{
if
(
addattr_l
(
n
,
1024
,
TCA_NETEM_RATE64
,
&
rate64
,
sizeof
(
rate64
))
<
0
)
return
-
1
;
rate
.
rate
=
~
0U
;
}
else
{
rate
.
rate
=
rate64
;
}
if
(
addattr_l
(
n
,
1024
,
TCA_NETEM_RATE
,
&
rate
,
sizeof
(
rate
))
<
0
)
return
-
1
;
}
if
(
dist_data
)
{
if
(
addattr_l
(
n
,
MAX_DIST
*
sizeof
(
dist_data
[
0
]),
...
...
@@ -522,6 +532,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
struct
tc_netem_qopt
qopt
;
const
struct
tc_netem_rate
*
rate
=
NULL
;
int
len
=
RTA_PAYLOAD
(
opt
)
-
sizeof
(
qopt
);
__u64
rate64
=
0
;
SPRINT_BUF
(
b1
);
if
(
opt
==
NULL
)
...
...
@@ -572,6 +583,11 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
return
-
1
;
ecn
=
RTA_DATA
(
tb
[
TCA_NETEM_ECN
]);
}
if
(
tb
[
TCA_NETEM_RATE64
])
{
if
(
RTA_PAYLOAD
(
tb
[
TCA_NETEM_RATE64
])
<
sizeof
(
rate64
))
return
-
1
;
rate64
=
rta_getattr_u64
(
tb
[
TCA_NETEM_RATE64
]);
}
}
fprintf
(
f
,
"limit %d"
,
qopt
.
limit
);
...
...
@@ -632,7 +648,10 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
}
if
(
rate
&&
rate
->
rate
)
{
fprintf
(
f
,
" rate %s"
,
sprint_rate
(
rate
->
rate
,
b1
));
if
(
rate64
)
fprintf
(
f
,
" rate %s"
,
sprint_rate
(
rate64
,
b1
));
else
fprintf
(
f
,
" rate %s"
,
sprint_rate
(
rate
->
rate
,
b1
));
if
(
rate
->
packet_overhead
)
fprintf
(
f
,
" packetoverhead %d"
,
rate
->
packet_overhead
);
if
(
rate
->
cell_size
)
...
...
tc/q_pie.c
0 → 100644
View file @
a37c7472
/* Copyright (C) 2013 Cisco Systems, Inc, 2013.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Author: Vijay Subramanian <vijaynsu@cisco.com>
* Author: Mythili Prabhu <mysuryan@cisco.com>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <math.h>
#include "utils.h"
#include "tc_util.h"
static
void
explain
(
void
)
{
fprintf
(
stderr
,
"Usage: ... pie [ limit PACKETS ][ target TIME us]
\n
"
);
fprintf
(
stderr
,
" [ tupdate TIME us][ alpha ALPHA ]"
);
fprintf
(
stderr
,
"[beta BETA ][bytemode | nobytemode][ecn | noecn ]
\n
"
);
}
#define ALPHA_MAX 32
#define ALPHA_MIN 0
#define BETA_MAX 32
#define BETA_MIN 0
static
int
pie_parse_opt
(
struct
qdisc_util
*
qu
,
int
argc
,
char
**
argv
,
struct
nlmsghdr
*
n
)
{
unsigned
int
limit
=
0
;
unsigned
int
target
=
0
;
unsigned
int
tupdate
=
0
;
unsigned
int
alpha
=
0
;
unsigned
int
beta
=
0
;
int
ecn
=
-
1
;
int
bytemode
=
-
1
;
struct
rtattr
*
tail
;
while
(
argc
>
0
)
{
if
(
strcmp
(
*
argv
,
"limit"
)
==
0
)
{
NEXT_ARG
();
if
(
get_unsigned
(
&
limit
,
*
argv
,
0
))
{
fprintf
(
stderr
,
"Illegal
\"
limit
\"\n
"
);
return
-
1
;
}
}
else
if
(
strcmp
(
*
argv
,
"target"
)
==
0
)
{
NEXT_ARG
();
if
(
get_time
(
&
target
,
*
argv
))
{
fprintf
(
stderr
,
"Illegal
\"
target
\"\n
"
);
return
-
1
;
}
}
else
if
(
strcmp
(
*
argv
,
"tupdate"
)
==
0
)
{
NEXT_ARG
();
if
(
get_time
(
&
tupdate
,
*
argv
))
{
fprintf
(
stderr
,
"Illegal
\"
tupdate
\"\n
"
);
return
-
1
;
}
}
else
if
(
strcmp
(
*
argv
,
"alpha"
)
==
0
)
{
NEXT_ARG
();
if
(
get_unsigned
(
&
alpha
,
*
argv
,
0
)
||
(
alpha
>
ALPHA_MAX
)
||
(
alpha
<
ALPHA_MIN
))
{
fprintf
(
stderr
,
"Illegal
\"
alpha
\"\n
"
);
return
-
1
;
}
}
else
if
(
strcmp
(
*
argv
,
"beta"
)
==
0
)
{
NEXT_ARG
();
if
(
get_unsigned
(
&
beta
,
*
argv
,
0
)
||
(
beta
>
BETA_MAX
)
||
(
beta
<
BETA_MIN
))
{
fprintf
(
stderr
,
"Illegal
\"
beta
\"\n
"
);
return
-
1
;
}
}
else
if
(
strcmp
(
*
argv
,
"ecn"
)
==
0
)
{
ecn
=
1
;
}
else
if
(
strcmp
(
*
argv
,
"noecn"
)
==
0
)
{
ecn
=
0
;
}
else
if
(
strcmp
(
*
argv
,
"bytemode"
)
==
0
)
{
bytemode
=
1
;
}
else
if
(
strcmp
(
*
argv
,
"nobytemode"
)
==
0
)
{
bytemode
=
0
;
}
else
if
(
strcmp
(
*
argv
,
"help"
)
==
0
)
{
explain
();
return
-
1
;
}
else
{
fprintf
(
stderr
,
"What is
\"
%s
\"
?
\n
"
,
*
argv
);
explain
();
return
-
1
;
}
argc
--
;
argv
++
;
}
tail
=
NLMSG_TAIL
(
n
);
addattr_l
(
n
,
1024
,
TCA_OPTIONS
,
NULL
,
0
);
if
(
limit
)
addattr_l
(
n
,
1024
,
TCA_PIE_LIMIT
,
&
limit
,
sizeof
(
limit
));
if
(
tupdate
)
addattr_l
(
n
,
1024
,
TCA_PIE_TUPDATE
,
&
tupdate
,
sizeof
(
tupdate
));
if
(
target
)
addattr_l
(
n
,
1024
,
TCA_PIE_TARGET
,
&
target
,
sizeof
(
target
));
if
(
alpha
)
addattr_l
(
n
,
1024
,
TCA_PIE_ALPHA
,
&
alpha
,
sizeof
(
alpha
));
if
(
beta
)
addattr_l
(
n
,
1024
,
TCA_PIE_BETA
,
&
beta
,
sizeof
(
beta
));
if
(
ecn
!=
-
1
)
addattr_l
(
n
,
1024
,
TCA_PIE_ECN
,
&
ecn
,
sizeof
(
ecn
));
if
(
bytemode
!=
-
1
)
addattr_l
(
n
,
1024
,
TCA_PIE_BYTEMODE
,
&
bytemode
,
sizeof
(
bytemode
));
tail
->
rta_len
=
(
void
*
)
NLMSG_TAIL
(
n
)
-
(
void
*
)
tail
;
return
0
;
}
static
int
pie_print_opt
(
struct
qdisc_util
*
qu
,
FILE
*
f
,
struct
rtattr
*
opt
)
{
struct
rtattr
*
tb
[
TCA_PIE_MAX
+
1
];
unsigned
int
limit
;
unsigned
int
tupdate
;
unsigned
int
target
;
unsigned
int
alpha
;
unsigned
int
beta
;
unsigned
ecn
;
unsigned
bytemode
;
SPRINT_BUF
(
b1
);
if
(
opt
==
NULL
)
return
0
;
parse_rtattr_nested
(
tb
,
TCA_PIE_MAX
,
opt
);
if
(
tb
[
TCA_PIE_LIMIT
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_LIMIT
])
>=
sizeof
(
__u32
))
{
limit
=
rta_getattr_u32
(
tb
[
TCA_PIE_LIMIT
]);
fprintf
(
f
,
"limit %up "
,
limit
);
}
if
(
tb
[
TCA_PIE_TARGET
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_TARGET
])
>=
sizeof
(
__u32
))
{
target
=
rta_getattr_u32
(
tb
[
TCA_PIE_TARGET
]);
fprintf
(
f
,
"target %s "
,
sprint_time
(
target
,
b1
));
}
if
(
tb
[
TCA_PIE_TUPDATE
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_TUPDATE
])
>=
sizeof
(
__u32
))
{
tupdate
=
rta_getattr_u32
(
tb
[
TCA_PIE_TUPDATE
]);
fprintf
(
f
,
"tupdate %s "
,
sprint_time
(
tupdate
,
b1
));
}
if
(
tb
[
TCA_PIE_ALPHA
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_ALPHA
])
>=
sizeof
(
__u32
))
{
alpha
=
rta_getattr_u32
(
tb
[
TCA_PIE_ALPHA
]);
fprintf
(
f
,
"alpha %u "
,
alpha
);
}
if
(
tb
[
TCA_PIE_BETA
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_BETA
])
>=
sizeof
(
__u32
))
{
beta
=
rta_getattr_u32
(
tb
[
TCA_PIE_BETA
]);
fprintf
(
f
,
"beta %u "
,
beta
);
}
if
(
tb
[
TCA_PIE_ECN
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_ECN
])
>=
sizeof
(
__u32
))
{
ecn
=
rta_getattr_u32
(
tb
[
TCA_PIE_ECN
]);
if
(
ecn
)
fprintf
(
f
,
"ecn "
);
}
if
(
tb
[
TCA_PIE_BYTEMODE
]
&&
RTA_PAYLOAD
(
tb
[
TCA_PIE_BYTEMODE
])
>=
sizeof
(
__u32
))
{
bytemode
=
rta_getattr_u32
(
tb
[
TCA_PIE_BYTEMODE
]);
if
(
bytemode
)
fprintf
(
f
,
"bytemode "
);
}
return
0
;
}
static
int
pie_print_xstats
(
struct
qdisc_util
*
qu
,
FILE
*
f
,
struct
rtattr
*
xstats
)
{
struct
tc_pie_xstats
*
st
;
if
(
xstats
==
NULL
)
return
0
;
if
(
RTA_PAYLOAD
(
xstats
)
<
sizeof
(
*
st
))
return
-
1
;
st
=
RTA_DATA
(
xstats
);
/*prob is returned as a fracion of maximum integer value */
fprintf
(
f
,
"prob %f delay %uus avg_dq_rate %u
\n
"
,
(
double
)
st
->
prob
/
(
double
)
0xffffffff
,
st
->
delay
,
st
->
avg_dq_rate
);
fprintf
(
f
,
"pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u
\n
"
,
st
->
packets_in
,
st
->
overlimit
,
st
->
dropped
,
st
->
maxq
,
st
->
ecn_mark
);
return
0
;
}
struct
qdisc_util
pie_qdisc_util
=
{
.
id
=
"pie"
,
.
parse_qopt
=
pie_parse_opt
,
.
print_qopt
=
pie_print_opt
,
.
print_xstats
=
pie_print_xstats
,
};
tc/q_tbf.c
View file @
a37c7472
...
...
@@ -47,6 +47,7 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
unsigned
short
overhead
=
0
;
unsigned
int
linklayer
=
LINKLAYER_ETHERNET
;
/* Assume ethernet */
struct
rtattr
*
tail
;
__u64
rate64
=
0
,
prate64
=
0
;
memset
(
&
opt
,
0
,
sizeof
(
opt
));
...
...
@@ -121,22 +122,22 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
ok
++
;
}
else
if
(
strcmp
(
*
argv
,
"rate"
)
==
0
)
{
NEXT_ARG
();
if
(
opt
.
rate
.
rate
)
{
if
(
rate64
)
{
fprintf
(
stderr
,
"tbf: duplicate
\"
rate
\"
specification
\n
"
);
return
-
1
;
}
if
(
get_rate
(
&
opt
.
rate
.
rate
,
*
argv
))
{
if
(
get_rate
64
(
&
rate64
,
*
argv
))
{
explain1
(
"rate"
,
*
argv
);
return
-
1
;
}
ok
++
;
}
else
if
(
matches
(
*
argv
,
"peakrate"
)
==
0
)
{
NEXT_ARG
();
if
(
opt
.
peakrate
.
rate
)
{
if
(
prate64
)
{
fprintf
(
stderr
,
"tbf: duplicate
\"
peakrate
\"
specification
\n
"
);
return
-
1
;
}
if
(
get_rate
(
&
opt
.
peakrate
.
rate
,
*
argv
))
{
if
(
get_rate
64
(
&
prate64
,
*
argv
))
{
explain1
(
"peakrate"
,
*
argv
);
return
-
1
;
}
...
...
@@ -172,7 +173,7 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
* one go rather than reveal one more problem when a
* previous one has been fixed.
*/
if
(
opt
.
rate
.
rate
==
0
)
{
if
(
rate64
==
0
)
{
fprintf
(
stderr
,
"tbf: the
\"
rate
\"
parameter is mandatory.
\n
"
);
verdict
=
-
1
;
}
...
...
@@ -180,7 +181,7 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
fprintf
(
stderr
,
"tbf: the
\"
burst
\"
parameter is mandatory.
\n
"
);
verdict
=
-
1
;
}
if
(
opt
.
peakrate
.
rate
)
{
if
(
prate64
)
{
if
(
!
mtu
)
{
fprintf
(
stderr
,
"tbf: when
\"
peakrate
\"
is specified,
\"
mtu
\"
must also be specified.
\n
"
);
verdict
=
-
1
;
...
...
@@ -197,10 +198,13 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
return
verdict
;
}
opt
.
rate
.
rate
=
(
rate64
>=
(
1ULL
<<
32
))
?
~
0U
:
rate64
;
opt
.
peakrate
.
rate
=
(
prate64
>=
(
1ULL
<<
32
))
?
~
0U
:
prate64
;
if
(
opt
.
limit
==
0
)
{
double
lim
=
opt
.
rate
.
rate
*
(
double
)
latency
/
TIME_UNITS_PER_SEC
+
buffer
;
if
(
opt
.
peakrate
.
rate
)
{
double
lim2
=
opt
.
peakrate
.
rate
*
(
double
)
latency
/
TIME_UNITS_PER_SEC
+
mtu
;
double
lim
=
rate64
*
(
double
)
latency
/
TIME_UNITS_PER_SEC
+
buffer
;
if
(
prate64
)
{
double
lim2
=
prate64
*
(
double
)
latency
/
TIME_UNITS_PER_SEC
+
mtu
;
if
(
lim2
<
lim
)
lim
=
lim2
;
}
...
...
@@ -228,20 +232,28 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
tail
=
NLMSG_TAIL
(
n
);
addattr_l
(
n
,
1024
,
TCA_OPTIONS
,
NULL
,
0
);
addattr_l
(
n
,
2024
,
TCA_TBF_PARMS
,
&
opt
,
sizeof
(
opt
));
addattr_l
(
n
,
2124
,
TCA_TBF_BURST
,
&
buffer
,
sizeof
(
buffer
));
if
(
rate64
>=
(
1ULL
<<
32
))
addattr_l
(
n
,
2124
,
TCA_TBF_RATE64
,
&
rate64
,
sizeof
(
rate64
));
addattr_l
(
n
,
3024
,
TCA_TBF_RTAB
,
rtab
,
1024
);
if
(
opt
.
peakrate
.
rate
)
if
(
opt
.
peakrate
.
rate
)
{
if
(
prate64
>=
(
1ULL
<<
32
))
addattr_l
(
n
,
3124
,
TCA_TBF_PRATE64
,
&
prate64
,
sizeof
(
prate64
));
addattr_l
(
n
,
3224
,
TCA_TBF_PBURST
,
&
mtu
,
sizeof
(
mtu
));
addattr_l
(
n
,
4096
,
TCA_TBF_PTAB
,
ptab
,
1024
);
}
tail
->
rta_len
=
(
void
*
)
NLMSG_TAIL
(
n
)
-
(
void
*
)
tail
;
return
0
;
}
static
int
tbf_print_opt
(
struct
qdisc_util
*
qu
,
FILE
*
f
,
struct
rtattr
*
opt
)
{
struct
rtattr
*
tb
[
TCA_TBF_
PTAB
+
1
];
struct
rtattr
*
tb
[
TCA_TBF_
MAX
+
1
];
struct
tc_tbf_qopt
*
qopt
;
unsigned
int
linklayer
;
double
buffer
,
mtu
;
double
latency
;
__u64
rate64
=
0
,
prate64
=
0
;
SPRINT_BUF
(
b1
);
SPRINT_BUF
(
b2
);
SPRINT_BUF
(
b3
);
...
...
@@ -249,7 +261,7 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if
(
opt
==
NULL
)
return
0
;
parse_rtattr_nested
(
tb
,
TCA_TBF_
PTAB
,
opt
);
parse_rtattr_nested
(
tb
,
TCA_TBF_
MAX
,
opt
);
if
(
tb
[
TCA_TBF_PARMS
]
==
NULL
)
return
-
1
;
...
...
@@ -257,8 +269,12 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
qopt
=
RTA_DATA
(
tb
[
TCA_TBF_PARMS
]);
if
(
RTA_PAYLOAD
(
tb
[
TCA_TBF_PARMS
])
<
sizeof
(
*
qopt
))
return
-
1
;
fprintf
(
f
,
"rate %s "
,
sprint_rate
(
qopt
->
rate
.
rate
,
b1
));
buffer
=
tc_calc_xmitsize
(
qopt
->
rate
.
rate
,
qopt
->
buffer
);
rate64
=
qopt
->
rate
.
rate
;
if
(
tb
[
TCA_TBF_RATE64
]
&&
RTA_PAYLOAD
(
tb
[
TCA_TBF_RATE64
])
>=
sizeof
(
rate64
))
rate64
=
rta_getattr_u64
(
tb
[
TCA_TBF_RATE64
]);
fprintf
(
f
,
"rate %s "
,
sprint_rate
(
rate64
,
b1
));
buffer
=
tc_calc_xmitsize
(
rate64
,
qopt
->
buffer
);
if
(
show_details
)
{
fprintf
(
f
,
"burst %s/%u mpu %s "
,
sprint_size
(
buffer
,
b1
),
1
<<
qopt
->
rate
.
cell_log
,
sprint_size
(
qopt
->
rate
.
mpu
,
b2
));
...
...
@@ -267,10 +283,14 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
}
if
(
show_raw
)
fprintf
(
f
,
"[%08x] "
,
qopt
->
buffer
);
if
(
qopt
->
peakrate
.
rate
)
{
fprintf
(
f
,
"peakrate %s "
,
sprint_rate
(
qopt
->
peakrate
.
rate
,
b1
));
prate64
=
qopt
->
peakrate
.
rate
;
if
(
tb
[
TCA_TBF_PRATE64
]
&&
RTA_PAYLOAD
(
tb
[
TCA_TBF_PRATE64
])
>=
sizeof
(
prate64
))
prate64
=
rta_getattr_u64
(
tb
[
TCA_TBF_PRATE64
]);
if
(
prate64
)
{
fprintf
(
f
,
"peakrate %s "
,
sprint_rate
(
prate64
,
b1
));
if
(
qopt
->
mtu
||
qopt
->
peakrate
.
mpu
)
{
mtu
=
tc_calc_xmitsize
(
qopt
->
peakrate
.
rate
,
qopt
->
mtu
);
mtu
=
tc_calc_xmitsize
(
prate64
,
qopt
->
mtu
);
if
(
show_details
)
{
fprintf
(
f
,
"mtu %s/%u mpu %s "
,
sprint_size
(
mtu
,
b1
),
1
<<
qopt
->
peakrate
.
cell_log
,
sprint_size
(
qopt
->
peakrate
.
mpu
,
b2
));
...
...
@@ -285,9 +305,9 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if
(
show_raw
)
fprintf
(
f
,
"limit %s "
,
sprint_size
(
qopt
->
limit
,
b1
));
latency
=
TIME_UNITS_PER_SEC
*
(
qopt
->
limit
/
(
double
)
qopt
->
rate
.
rate
)
-
tc_core_tick2time
(
qopt
->
buffer
);
if
(
qopt
->
peakrate
.
rate
)
{
double
lat2
=
TIME_UNITS_PER_SEC
*
(
qopt
->
limit
/
(
double
)
qopt
->
peakrate
.
rate
)
-
tc_core_tick2time
(
qopt
->
mtu
);
latency
=
TIME_UNITS_PER_SEC
*
(
qopt
->
limit
/
(
double
)
rate64
)
-
tc_core_tick2time
(
qopt
->
buffer
);
if
(
prate64
)
{
double
lat2
=
TIME_UNITS_PER_SEC
*
(
qopt
->
limit
/
(
double
)
prate64
)
-
tc_core_tick2time
(
qopt
->
mtu
);
if
(
lat2
>
latency
)
latency
=
lat2
;
}
...
...
tc/tc_core.c
View file @
a37c7472
...
...
@@ -56,12 +56,12 @@ unsigned tc_core_ktime2time(unsigned ktime)
return
ktime
/
clock_factor
;
}
unsigned
tc_calc_xmittime
(
unsigned
rate
,
unsigned
size
)
unsigned
tc_calc_xmittime
(
__u64
rate
,
unsigned
size
)
{
return
tc_core_time2tick
(
TIME_UNITS_PER_SEC
*
((
double
)
size
/
rate
));
return
tc_core_time2tick
(
TIME_UNITS_PER_SEC
*
((
double
)
size
/
(
double
)
rate
));
}
unsigned
tc_calc_xmitsize
(
unsigned
rate
,
unsigned
ticks
)
unsigned
tc_calc_xmitsize
(
__u64
rate
,
unsigned
ticks
)
{
return
((
double
)
rate
*
tc_core_tick2time
(
ticks
))
/
TIME_UNITS_PER_SEC
;
}
...
...
tc/tc_core.h
View file @
a37c7472
...
...
@@ -18,8 +18,8 @@ unsigned tc_core_time2tick(unsigned time);
unsigned
tc_core_tick2time
(
unsigned
tick
);
unsigned
tc_core_time2ktime
(
unsigned
time
);
unsigned
tc_core_ktime2time
(
unsigned
ktime
);
unsigned
tc_calc_xmittime
(
unsigned
rate
,
unsigned
size
);
unsigned
tc_calc_xmitsize
(
unsigned
rate
,
unsigned
ticks
);
unsigned
tc_calc_xmittime
(
__u64
rate
,
unsigned
size
);
unsigned
tc_calc_xmitsize
(
__u64
rate
,
unsigned
ticks
);
int
tc_calc_rtable
(
struct
tc_ratespec
*
r
,
__u32
*
rtab
,
int
cell_log
,
unsigned
mtu
,
enum
link_layer
link_layer
);
int
tc_calc_size_table
(
struct
tc_sizespec
*
s
,
__u16
**
stab
);
...
...
tc/tc_util.c
View file @
a37c7472
...
...
@@ -171,6 +171,31 @@ int get_rate(unsigned *rate, const char *str)
return
0
;
}
int
get_rate64
(
__u64
*
rate
,
const
char
*
str
)
{
char
*
p
;
double
bps
=
strtod
(
str
,
&
p
);
const
struct
rate_suffix
*
s
;
if
(
p
==
str
)
return
-
1
;
for
(
s
=
suffixes
;
s
->
name
;
++
s
)
{
if
(
strcasecmp
(
s
->
name
,
p
)
==
0
)
{
bps
*=
s
->
scale
;
p
+=
strlen
(
p
);
break
;
}
}
if
(
*
p
)
return
-
1
;
/* unknown suffix */
bps
/=
8
;
/* -> bytes per second */
*
rate
=
bps
;
return
0
;
}
void
print_rate
(
char
*
buf
,
int
len
,
__u64
rate
)
{
extern
int
use_iec
;
...
...
tc/tc_util.h
View file @
a37c7472
...
...
@@ -58,6 +58,7 @@ extern struct filter_util *get_filter_kind(const char *str);
extern
int
get_qdisc_handle
(
__u32
*
h
,
const
char
*
str
);
extern
int
get_rate
(
unsigned
*
rate
,
const
char
*
str
);
extern
int
get_rate64
(
__u64
*
rate
,
const
char
*
str
);
extern
int
get_size
(
unsigned
*
size
,
const
char
*
str
);
extern
int
get_size_and_cell
(
unsigned
*
size
,
int
*
cell_log
,
char
*
str
);
extern
int
get_time
(
unsigned
*
time
,
const
char
*
str
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment