* [PATCH net-next 0/9] Misc. cleanups for HNS3 ethernet driver
From: Salil Mehta @ 2018-07-19 14:46 UTC (permalink / raw)
To: davem
Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
linux-kernel, linuxarm
This patch-set presents some cleanups for HNS3 Ethernet Driver.
Jian Shen (9):
net: hns3: Remove some redundant assignments
net: hns3: Standardize the handle of return value
net: hns3: Remove extra space and brackets
net: hns3: Correct unreasonable code comments
net: hns3: Use decimal for bit offset macros
net: hns3: Modify inconsistent bit mask macros
net: hns3: Fix misleading parameter name
net: hns3: Remove unused struct member and definition
net: hns3: Add SPDX tags to HNS3 PF driver
drivers/net/ethernet/hisilicon/hns3/hnae3.c | 10 +-
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 10 +-
drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c | 10 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 14 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 10 +-
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 10 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 14 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 103 ++++++--------
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 10 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h | 10 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 150 +++++++--------------
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 42 +++---
.../ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 10 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h | 10 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 10 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 10 +-
16 files changed, 136 insertions(+), 297 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH iproute2-next v11] Add support for CAKE qdisc
From: Toke Høiland-Jørgensen @ 2018-07-19 13:56 UTC (permalink / raw)
To: netdev; +Cc: cake, Toke Høiland-Jørgensen, Dave Taht
sch_cake is intended to squeeze the most bandwidth and latency out of even
the slowest ISP links and routers, while presenting an API simple enough
that even an ISP can configure it.
Example of use on a cable ISP uplink:
tc qdisc add dev eth0 cake bandwidth 20Mbit nat docsis ack-filter
To shape a cable download link (ifb and tc-mirred setup elided)
tc qdisc add dev ifb0 cake bandwidth 200mbit nat docsis ingress wash besteffort
Cake is filled with:
* A hybrid Codel/Blue AQM algorithm, "Cobalt", tied to an FQ_Codel
derived Flow Queuing system, which autoconfigures based on the bandwidth.
* A novel "triple-isolate" mode (the default) which balances per-host
and per-flow FQ even through NAT.
* An deficit based shaper, that can also be used in an unlimited mode.
* 8 way set associative hashing to reduce flow collisions to a minimum.
* A reasonable interpretation of various diffserv latency/loss tradeoffs.
* Support for zeroing diffserv markings for entering and exiting traffic.
* Support for interacting well with Docsis 3.0 shaper framing.
* Support for DSL framing types and shapers.
* Support for ack filtering.
* Extensive statistics for measuring, loss, ecn markings, latency variation.
Various versions baking have been available as an out of tree build for
kernel versions going back to 3.10, as the embedded router world has been
running a few years behind mainline Linux. A stable version has been
generally available on lede-17.01 and later.
sch_cake replaces a combination of iptables, tc filter, htb and fq_codel
in the sqm-scripts, with sane defaults and vastly simpler configuration.
Cake's principal author is Jonathan Morton, with contributions from
Kevin Darbyshire-Bryant, Toke Høiland-Jørgensen, Sebastian Moeller,
Ryan Mounce, Tony Ambardar, Dean Scarff, Nils Andreas Svee, Dave Täht,
and Loganaden Velvindron.
Testing from Pete Heist, Georgios Amanakis, and the many other members of
the cake@lists.bufferbloat.net mailing list.
Signed-off-by: Dave Taht <dave.taht@gmail.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
Changelog:
v11:
- Code style cleanup (checkpatch etc)
v10:
- Rebase on latest iproute2-next
v9:
- Add printing of class stats and instantaneous queue backlog
v8:
- Change rates to 64bit values (apparently, 32 Gbps is not enough for
everyone).
v7:
- Move the target/interval presets to a table and check that only
one is passed.
v6:
- Identical to v5 because apparently I don't git so well... :/
v5:
- Print the SPLIT_GSO flag
- Switch to print_u64() for JSON output
- Fix a format string for mpu option output
v4:
- Switch stats parsing to use nested netlink attributes
- Tweaks to JSON stats output keys
v3:
- Remove accidentally included test flag
v2:
- Updated netlink config ABI
- Remove diffserv-llt mode
- Various tweaks and clean-ups of stats output
man/man8/tc-cake.8 | 632 ++++++++++++++++++++++++++++++++++++
man/man8/tc.8 | 1 +
tc/Makefile | 1 +
tc/q_cake.c | 790 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1424 insertions(+)
create mode 100644 man/man8/tc-cake.8
create mode 100644 tc/q_cake.c
diff --git a/man/man8/tc-cake.8 b/man/man8/tc-cake.8
new file mode 100644
index 00000000..9773fcae
--- /dev/null
+++ b/man/man8/tc-cake.8
@@ -0,0 +1,632 @@
+.TH CAKE 8 "19 July 2018" "iproute2" "Linux"
+.SH NAME
+CAKE \- Common Applications Kept Enhanced (CAKE)
+.SH SYNOPSIS
+.B tc qdisc ... cake
+.br
+[
+.BR bandwidth
+RATE |
+.BR unlimited*
+|
+.BR autorate_ingress
+]
+.br
+[
+.BR rtt
+TIME |
+.BR datacentre
+|
+.BR lan
+|
+.BR metro
+|
+.BR regional
+|
+.BR internet*
+|
+.BR oceanic
+|
+.BR satellite
+|
+.BR interplanetary
+]
+.br
+[
+.BR besteffort
+|
+.BR diffserv8
+|
+.BR diffserv4
+|
+.BR diffserv3*
+]
+.br
+[
+.BR flowblind
+|
+.BR srchost
+|
+.BR dsthost
+|
+.BR hosts
+|
+.BR flows
+|
+.BR dual-srchost
+|
+.BR dual-dsthost
+|
+.BR triple-isolate*
+]
+.br
+[
+.BR nat
+|
+.BR nonat*
+]
+.br
+[
+.BR wash
+|
+.BR nowash*
+]
+.br
+[
+.BR ack-filter
+|
+.BR ack-filter-aggressive
+|
+.BR no-ack-filter*
+]
+.br
+[
+.BR memlimit
+LIMIT ]
+.br
+[
+.BR ptm
+|
+.BR atm
+|
+.BR noatm*
+]
+.br
+[
+.BR overhead
+N |
+.BR conservative
+|
+.BR raw*
+]
+.br
+[
+.BR mpu
+N ]
+.br
+[
+.BR ingress
+|
+.BR egress*
+]
+.br
+(* marks defaults)
+
+
+.SH DESCRIPTION
+CAKE (Common Applications Kept Enhanced) is a shaping-capable queue discipline
+which uses both AQM and FQ. It combines COBALT, which is an AQM algorithm
+combining Codel and BLUE, a shaper which operates in deficit mode, and a variant
+of DRR++ for flow isolation. 8-way set-associative hashing is used to virtually
+eliminate hash collisions. Priority queuing is available through a simplified
+diffserv implementation. Overhead compensation for various encapsulation
+schemes is tightly integrated.
+
+All settings are optional; the default settings are chosen to be sensible in
+most common deployments. Most people will only need to set the
+.B bandwidth
+parameter to get useful results, but reading the
+.B Overhead Compensation
+and
+.B Round Trip Time
+sections is strongly encouraged.
+
+.SH SHAPER PARAMETERS
+CAKE uses a deficit-mode shaper, which does not exhibit the initial burst
+typical of token-bucket shapers. It will automatically burst precisely as much
+as required to maintain the configured throughput. As such, it is very
+straightforward to configure.
+.PP
+.B unlimited
+(default)
+.br
+ No limit on the bandwidth.
+.PP
+.B bandwidth
+RATE
+.br
+ Set the shaper bandwidth. See
+.BR tc(8)
+or examples below for details of the RATE value.
+.PP
+.B autorate_ingress
+.br
+ Automatic capacity estimation based on traffic arriving at this qdisc.
+This is most likely to be useful with cellular links, which tend to change
+quality randomly. A
+.B bandwidth
+parameter can be used in conjunction to specify an initial estimate. The shaper
+will periodically be set to a bandwidth slightly below the estimated rate. This
+estimator cannot estimate the bandwidth of links downstream of itself.
+
+.SH OVERHEAD COMPENSATION PARAMETERS
+The size of each packet on the wire may differ from that seen by Linux. The
+following parameters allow CAKE to compensate for this difference by internally
+considering each packet to be bigger than Linux informs it. To assist users who
+are not expert network engineers, keywords have been provided to represent a
+number of common link technologies.
+
+.SS Manual Overhead Specification
+.B overhead
+BYTES
+.br
+ Adds BYTES to the size of each packet. BYTES may be negative; values
+between -64 and 256 (inclusive) are accepted.
+.PP
+.B mpu
+BYTES
+.br
+ Rounds each packet (including overhead) up to a minimum length
+BYTES. BYTES may not be negative; values between 0 and 256 (inclusive)
+are accepted.
+.PP
+.B atm
+.br
+ Compensates for ATM cell framing, which is normally found on ADSL links.
+This is performed after the
+.B overhead
+parameter above. ATM uses fixed 53-byte cells, each of which can carry 48 bytes
+payload.
+.PP
+.B ptm
+.br
+ Compensates for PTM encoding, which is normally found on VDSL2 links and
+uses a 64b/65b encoding scheme. It is even more efficient to simply
+derate the specified shaper bandwidth by a factor of 64/65 or 0.984. See
+ITU G.992.3 Annex N and IEEE 802.3 Section 61.3 for details.
+.PP
+.B noatm
+.br
+ Disables ATM and PTM compensation.
+
+.SS Failsafe Overhead Keywords
+These two keywords are provided for quick-and-dirty setup. Use them if you
+can't be bothered to read the rest of this section.
+.PP
+.B raw
+(default)
+.br
+ Turns off all overhead compensation in CAKE. The packet size reported
+by Linux will be used directly.
+.PP
+ Other overhead keywords may be added after "raw". The effect of this is
+to make the overhead compensation operate relative to the reported packet size,
+not the underlying IP packet size.
+.PP
+.B conservative
+.br
+ Compensates for more overhead than is likely to occur on any
+widely-deployed link technology.
+.br
+ Equivalent to
+.B overhead 48 atm.
+
+.SS ADSL Overhead Keywords
+Most ADSL modems have a way to check which framing scheme is in use. Often this
+is also specified in the settings document provided by the ISP. The keywords in
+this section are intended to correspond with these sources of information. All
+of them implicitly set the
+.B atm
+flag.
+.PP
+.B pppoa-vcmux
+.br
+ Equivalent to
+.B overhead 10 atm
+.PP
+.B pppoa-llc
+.br
+ Equivalent to
+.B overhead 14 atm
+.PP
+.B pppoe-vcmux
+.br
+ Equivalent to
+.B overhead 32 atm
+.PP
+.B pppoe-llcsnap
+.br
+ Equivalent to
+.B overhead 40 atm
+.PP
+.B bridged-vcmux
+.br
+ Equivalent to
+.B overhead 24 atm
+.PP
+.B bridged-llcsnap
+.br
+ Equivalent to
+.B overhead 32 atm
+.PP
+.B ipoa-vcmux
+.br
+ Equivalent to
+.B overhead 8 atm
+.PP
+.B ipoa-llcsnap
+.br
+ Equivalent to
+.B overhead 16 atm
+.PP
+See also the Ethernet Correction Factors section below.
+
+.SS VDSL2 Overhead Keywords
+ATM was dropped from VDSL2 in favour of PTM, which is a much more
+straightforward framing scheme. Some ISPs retained PPPoE for compatibility with
+their existing back-end systems.
+.PP
+.B pppoe-ptm
+.br
+ Equivalent to
+.B overhead 30 ptm
+
+.br
+ PPPoE: 2B PPP + 6B PPPoE +
+.br
+ ETHERNET: 6B dest MAC + 6B src MAC + 2B ethertype + 4B Frame Check Sequence +
+.br
+ PTM: 1B Start of Frame (S) + 1B End of Frame (Ck) + 2B TC-CRC (PTM-FCS)
+.br
+.PP
+.B bridged-ptm
+.br
+ Equivalent to
+.B overhead 22 ptm
+.br
+ ETHERNET: 6B dest MAC + 6B src MAC + 2B ethertype + 4B Frame Check Sequence +
+.br
+ PTM: 1B Start of Frame (S) + 1B End of Frame (Ck) + 2B TC-CRC (PTM-FCS)
+.br
+.PP
+See also the Ethernet Correction Factors section below.
+
+.SS DOCSIS Cable Overhead Keyword
+DOCSIS is the universal standard for providing Internet service over cable-TV
+infrastructure.
+
+In this case, the actual on-wire overhead is less important than the packet size
+the head-end equipment uses for shaping and metering. This is specified to be
+an Ethernet frame including the CRC (aka FCS).
+.PP
+.B docsis
+.br
+ Equivalent to
+.B overhead 18 mpu 64 noatm
+
+.SS Ethernet Overhead Keywords
+.PP
+.B ethernet
+.br
+ Accounts for Ethernet's preamble, inter-frame gap, and Frame Check
+Sequence. Use this keyword when the bottleneck being shaped for is an
+actual Ethernet cable.
+.br
+ Equivalent to
+.B overhead 38 mpu 84 noatm
+.PP
+.B ether-vlan
+.br
+ Adds 4 bytes to the overhead compensation, accounting for an IEEE 802.1Q
+VLAN header appended to the Ethernet frame header. NB: Some ISPs use one or
+even two of these within PPPoE; this keyword may be repeated as necessary to
+express this.
+
+.SH ROUND TRIP TIME PARAMETERS
+Active Queue Management (AQM) consists of embedding congestion signals in the
+packet flow, which receivers use to instruct senders to slow down when the queue
+is persistently occupied. CAKE uses ECN signalling when available, and packet
+drops otherwise, according to a combination of the Codel and BLUE AQM algorithms
+called COBALT.
+
+Very short latencies require a very rapid AQM response to adequately control
+latency. However, such a rapid response tends to impair throughput when the
+actual RTT is relatively long. CAKE allows specifying the RTT it assumes for
+tuning various parameters. Actual RTTs within an order of magnitude of this
+will generally work well for both throughput and latency management.
+
+At the 'lan' setting and below, the time constants are similar in magnitude to
+the jitter in the Linux kernel itself, so congestion might be signalled
+prematurely. The flows will then become sparse and total throughput reduced,
+leaving little or no back-pressure for the fairness logic to work against. Use
+the "metro" setting for local lans unless you have a custom kernel.
+.PP
+.B rtt
+TIME
+.br
+ Manually specify an RTT.
+.PP
+.B datacentre
+.br
+ For extremely high-performance 10GigE+ networks only. Equivalent to
+.B rtt 100us.
+.PP
+.B lan
+.br
+ For pure Ethernet (not Wi-Fi) networks, at home or in the office. Don't
+use this when shaping for an Internet access link. Equivalent to
+.B rtt 1ms.
+.PP
+.B metro
+.br
+ For traffic mostly within a single city. Equivalent to
+.B rtt 10ms.
+.PP
+.B regional
+.br
+ For traffic mostly within a European-sized country. Equivalent to
+.B rtt 30ms.
+.PP
+.B internet
+(default)
+.br
+ This is suitable for most Internet traffic. Equivalent to
+.B rtt 100ms.
+.PP
+.B oceanic
+.br
+ For Internet traffic with generally above-average latency, such as that
+suffered by Australasian residents. Equivalent to
+.B rtt 300ms.
+.PP
+.B satellite
+.br
+ For traffic via geostationary satellites. Equivalent to
+.B rtt 1000ms.
+.PP
+.B interplanetary
+.br
+ So named because Jupiter is about 1 light-hour from Earth. Use this to
+(almost) completely disable AQM actions. Equivalent to
+.B rtt 3600s.
+
+.SH FLOW ISOLATION PARAMETERS
+With flow isolation enabled, CAKE places packets from different flows into
+different queues, each of which carries its own AQM state. Packets from each
+queue are then delivered fairly, according to a DRR++ algorithm which minimises
+latency for "sparse" flows. CAKE uses a set-associative hashing algorithm to
+minimise flow collisions.
+
+These keywords specify whether fairness based on source address, destination
+address, individual flows, or any combination of those is desired.
+.PP
+.B flowblind
+.br
+ Disables flow isolation; all traffic passes through a single queue for
+each tin.
+.PP
+.B srchost
+.br
+ Flows are defined only by source address. Could be useful on the egress
+path of an ISP backhaul.
+.PP
+.B dsthost
+.br
+ Flows are defined only by destination address. Could be useful on the
+ingress path of an ISP backhaul.
+.PP
+.B hosts
+.br
+ Flows are defined by source-destination host pairs. This is host
+isolation, rather than flow isolation.
+.PP
+.B flows
+.br
+ Flows are defined by the entire 5-tuple of source address, destination
+address, transport protocol, source port and destination port. This is the type
+of flow isolation performed by SFQ and fq_codel.
+.PP
+.B dual-srchost
+.br
+ Flows are defined by the 5-tuple, and fairness is applied first over
+source addresses, then over individual flows. Good for use on egress traffic
+from a LAN to the internet, where it'll prevent any one LAN host from
+monopolising the uplink, regardless of the number of flows they use.
+.PP
+.B dual-dsthost
+.br
+ Flows are defined by the 5-tuple, and fairness is applied first over
+destination addresses, then over individual flows. Good for use on ingress
+traffic to a LAN from the internet, where it'll prevent any one LAN host from
+monopolising the downlink, regardless of the number of flows they use.
+.PP
+.B triple-isolate
+(default)
+.br
+ Flows are defined by the 5-tuple, and fairness is applied over source
+*and* destination addresses intelligently (ie. not merely by host-pairs), and
+also over individual flows. Use this if you're not certain whether to use
+dual-srchost or dual-dsthost; it'll do both jobs at once, preventing any one
+host on *either* side of the link from monopolising it with a large number of
+flows.
+.PP
+.B nat
+.br
+ Instructs Cake to perform a NAT lookup before applying flow-isolation
+rules, to determine the true addresses and port numbers of the packet, to
+improve fairness between hosts "inside" the NAT. This has no practical effect
+in "flowblind" or "flows" modes, or if NAT is performed on a different host.
+.PP
+.B nonat
+(default)
+.br
+ Cake will not perform a NAT lookup. Flow isolation will be performed
+using the addresses and port numbers directly visible to the interface Cake is
+attached to.
+
+.SH PRIORITY QUEUE PARAMETERS
+CAKE can divide traffic into "tins" based on the Diffserv field. Each tin has
+its own independent set of flow-isolation queues, and is serviced based on a WRR
+algorithm. To avoid perverse Diffserv marking incentives, tin weights have a
+"priority sharing" value when bandwidth used by that tin is below a threshold,
+and a lower "bandwidth sharing" value when above. Bandwidth is compared against
+the threshold using the same algorithm as the deficit-mode shaper.
+
+Detailed customisation of tin parameters is not provided. The following presets
+perform all necessary tuning, relative to the current shaper bandwidth and RTT
+settings.
+.PP
+.B besteffort
+.br
+ Disables priority queuing by placing all traffic in one tin.
+.PP
+.B precedence
+.br
+ Enables legacy interpretation of TOS "Precedence" field. Use of this
+preset on the modern Internet is firmly discouraged.
+.PP
+.B diffserv4
+.br
+ Provides a general-purpose Diffserv implementation with four tins:
+.br
+ Bulk (CS1), 6.25% threshold, generally low priority.
+.br
+ Best Effort (general), 100% threshold.
+.br
+ Video (AF4x, AF3x, CS3, AF2x, CS2, TOS4, TOS1), 50% threshold.
+.br
+ Voice (CS7, CS6, EF, VA, CS5, CS4), 25% threshold.
+.PP
+.B diffserv3
+(default)
+.br
+ Provides a simple, general-purpose Diffserv implementation with three tins:
+.br
+ Bulk (CS1), 6.25% threshold, generally low priority.
+.br
+ Best Effort (general), 100% threshold.
+.br
+ Voice (CS7, CS6, EF, VA, TOS4), 25% threshold, reduced Codel interval.
+
+.SH OTHER PARAMETERS
+.B memlimit
+LIMIT
+.br
+ Limit the memory consumed by Cake to LIMIT bytes. Note that this does
+not translate directly to queue size (so do not size this based on bandwidth
+delay product considerations, but rather on worst case acceptable memory
+consumption), as there is some overhead in the data structures containing the
+packets, especially for small packets.
+
+ By default, the limit is calculated based on the bandwidth and RTT
+settings.
+
+.PP
+.B wash
+
+.br
+ Traffic entering your diffserv domain is frequently mis-marked in
+transit from the perspective of your network, and traffic exiting yours may be
+mis-marked from the perspective of the transiting provider.
+
+Apply the wash option to clear all extra diffserv (but not ECN bits), after
+priority queuing has taken place.
+
+If you are shaping inbound, and cannot trust the diffserv markings (as is the
+case for Comcast Cable, among others), it is best to use a single queue
+"besteffort" mode with wash.
+
+.SH EXAMPLES
+# tc qdisc delete root dev eth0
+.br
+# tc qdisc add root dev eth0 cake bandwidth 100Mbit ethernet
+.br
+# tc -s qdisc show dev eth0
+.br
+qdisc cake 1: root refcnt 2 bandwidth 100Mbit diffserv3 triple-isolate rtt 100.0ms noatm overhead 38 mpu 84
+ Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
+ backlog 0b 0p requeues 0
+ memory used: 0b of 5000000b
+ capacity estimate: 100Mbit
+ min/max network layer size: 65535 / 0
+ min/max overhead-adjusted size: 65535 / 0
+ average network hdr offset: 0
+
+ Bulk Best Effort Voice
+ thresh 6250Kbit 100Mbit 25Mbit
+ target 5.0ms 5.0ms 5.0ms
+ interval 100.0ms 100.0ms 100.0ms
+ pk_delay 0us 0us 0us
+ av_delay 0us 0us 0us
+ sp_delay 0us 0us 0us
+ pkts 0 0 0
+ bytes 0 0 0
+ way_inds 0 0 0
+ way_miss 0 0 0
+ way_cols 0 0 0
+ drops 0 0 0
+ marks 0 0 0
+ ack_drop 0 0 0
+ sp_flows 0 0 0
+ bk_flows 0 0 0
+ un_flows 0 0 0
+ max_len 0 0 0
+ quantum 300 1514 762
+
+After some use:
+.br
+# tc -s qdisc show dev eth0
+
+qdisc cake 1: root refcnt 2 bandwidth 100Mbit diffserv3 triple-isolate rtt 100.0ms noatm overhead 38 mpu 84
+ Sent 44709231 bytes 31931 pkt (dropped 45, overlimits 93782 requeues 0)
+ backlog 33308b 22p requeues 0
+ memory used: 292352b of 5000000b
+ capacity estimate: 100Mbit
+ min/max network layer size: 28 / 1500
+ min/max overhead-adjusted size: 84 / 1538
+ average network hdr offset: 14
+
+ Bulk Best Effort Voice
+ thresh 6250Kbit 100Mbit 25Mbit
+ target 5.0ms 5.0ms 5.0ms
+ interval 100.0ms 100.0ms 100.0ms
+ pk_delay 8.7ms 6.9ms 5.0ms
+ av_delay 4.9ms 5.3ms 3.8ms
+ sp_delay 727us 1.4ms 511us
+ pkts 2590 21271 8137
+ bytes 3081804 30302659 11426206
+ way_inds 0 46 0
+ way_miss 3 17 4
+ way_cols 0 0 0
+ drops 20 15 10
+ marks 0 0 0
+ ack_drop 0 0 0
+ sp_flows 2 4 1
+ bk_flows 1 2 1
+ un_flows 0 0 0
+ max_len 1514 1514 1514
+ quantum 300 1514 762
+
+.SH SEE ALSO
+.BR tc (8),
+.BR tc-codel (8),
+.BR tc-fq_codel (8),
+.BR tc-htb (8)
+
+.SH AUTHORS
+Cake's principal author is Jonathan Morton, with contributions from
+Tony Ambardar, Kevin Darbyshire-Bryant, Toke Høiland-Jørgensen,
+Sebastian Moeller, Ryan Mounce, Dean Scarff, Nils Andreas Svee, and Dave Täht.
+
+This manual page was written by Loganaden Velvindron. Please report corrections
+to the Linux Networking mailing list <netdev@vger.kernel.org>.
diff --git a/man/man8/tc.8 b/man/man8/tc.8
index 840880fb..716dfec5 100644
--- a/man/man8/tc.8
+++ b/man/man8/tc.8
@@ -795,6 +795,7 @@ was written by Alexey N. Kuznetsov and added in Linux 2.2.
.BR tc-basic (8),
.BR tc-bfifo (8),
.BR tc-bpf (8),
+.BR tc-cake (8),
.BR tc-cbq (8),
.BR tc-cgroup (8),
.BR tc-choke (8),
diff --git a/tc/Makefile b/tc/Makefile
index 4525c0fb..36cde2f8 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -66,6 +66,7 @@ TCMODULES += q_codel.o
TCMODULES += q_fq_codel.o
TCMODULES += q_fq.o
TCMODULES += q_pie.o
+TCMODULES += q_cake.o
TCMODULES += q_hhf.o
TCMODULES += q_clsact.o
TCMODULES += e_bpf.o
diff --git a/tc/q_cake.c b/tc/q_cake.c
new file mode 100644
index 00000000..b5476584
--- /dev/null
+++ b/tc/q_cake.c
@@ -0,0 +1,790 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+
+/*
+ * Common Applications Kept Enhanced -- CAKE
+ *
+ * Copyright (C) 2014-2018 Jonathan Morton <chromatix99@gmail.com>
+ * Copyright (C) 2017-2018 Toke Høiland-Jørgensen <toke@toke.dk>
+ */
+
+#include <stddef.h>
+#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 <inttypes.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+struct cake_preset {
+ char *name;
+ unsigned int target;
+ unsigned int interval;
+};
+
+static struct cake_preset presets[] = {
+ {"datacentre", 5, 100},
+ {"lan", 50, 1000},
+ {"metro", 500, 10000},
+ {"regional", 1500, 30000},
+ {"internet", 5000, 100000},
+ {"oceanic", 15000, 300000},
+ {"satellite", 50000, 1000000},
+ {"interplanetary", 50000000, 1000000000},
+};
+
+static const char * diffserv_names[CAKE_DIFFSERV_MAX] = {
+ [CAKE_DIFFSERV_DIFFSERV3] = "diffserv3",
+ [CAKE_DIFFSERV_DIFFSERV4] = "diffserv4",
+ [CAKE_DIFFSERV_DIFFSERV8] = "diffserv8",
+ [CAKE_DIFFSERV_BESTEFFORT] = "besteffort",
+ [CAKE_DIFFSERV_PRECEDENCE] = "precedence",
+};
+
+static const char * flowmode_names[CAKE_FLOW_MAX] = {
+ [CAKE_FLOW_NONE] = "flowblind",
+ [CAKE_FLOW_SRC_IP] = "srchost",
+ [CAKE_FLOW_DST_IP] = "dsthost",
+ [CAKE_FLOW_HOSTS] = "hosts",
+ [CAKE_FLOW_FLOWS] = "flows",
+ [CAKE_FLOW_DUAL_SRC] = "dual-srchost",
+ [CAKE_FLOW_DUAL_DST] = "dual-dsthost",
+ [CAKE_FLOW_TRIPLE] = "triple-isolate",
+};
+
+static struct cake_preset *find_preset(char *argv)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(presets); i++)
+ if (!strcmp(argv, presets[i].name))
+ return &presets[i];
+ return NULL;
+}
+
+static void explain(void)
+{
+ fprintf(stderr,
+"Usage: ... cake [ bandwidth RATE | unlimited* | autorate_ingress ]\n"
+" [ rtt TIME | datacentre | lan | metro | regional |\n"
+" internet* | oceanic | satellite | interplanetary ]\n"
+" [ besteffort | diffserv8 | diffserv4 | diffserv3* ]\n"
+" [ flowblind | srchost | dsthost | hosts | flows |\n"
+" dual-srchost | dual-dsthost | triple-isolate* ]\n"
+" [ nat | nonat* ]\n"
+" [ wash | nowash* ]\n"
+" [ ack-filter | ack-filter-aggressive | no-ack-filter* ]\n"
+" [ memlimit LIMIT ]\n"
+" [ ptm | atm | noatm* ] [ overhead N | conservative | raw* ]\n"
+" [ mpu N ] [ ingress | egress* ]\n"
+" (* marks defaults)\n");
+}
+
+static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv,
+ struct nlmsghdr *n, const char *dev)
+{
+ struct cake_preset *preset, *preset_set = NULL;
+ bool overhead_override = false;
+ bool overhead_set = false;
+ unsigned int interval = 0;
+ unsigned int diffserv = 0;
+ unsigned int memlimit = 0;
+ unsigned int target = 0;
+ __u64 bandwidth = 0;
+ int ack_filter = -1;
+ struct rtattr *tail;
+ int unlimited = 0;
+ int flowmode = -1;
+ int autorate = -1;
+ int ingress = -1;
+ int overhead = 0;
+ int wash = -1;
+ int nat = -1;
+ int atm = -1;
+ int mpu = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "bandwidth") == 0) {
+ NEXT_ARG();
+ if (get_rate64(&bandwidth, *argv)) {
+ fprintf(stderr, "Illegal \"bandwidth\"\n");
+ return -1;
+ }
+ unlimited = 0;
+ autorate = 0;
+ } else if (strcmp(*argv, "unlimited") == 0) {
+ bandwidth = 0;
+ unlimited = 1;
+ autorate = 0;
+ } else if (strcmp(*argv, "autorate_ingress") == 0) {
+ autorate = 1;
+ } else if (strcmp(*argv, "rtt") == 0) {
+ NEXT_ARG();
+ if (get_time(&interval, *argv)) {
+ fprintf(stderr, "Illegal \"rtt\"\n");
+ return -1;
+ }
+ target = interval / 20;
+ if (!target)
+ target = 1;
+ } else if ((preset = find_preset(*argv))) {
+ if (preset_set)
+ duparg(*argv, preset_set->name);
+ preset_set = preset;
+ target = preset->target;
+ interval = preset->interval;
+ } else if (strcmp(*argv, "besteffort") == 0) {
+ diffserv = CAKE_DIFFSERV_BESTEFFORT;
+ } else if (strcmp(*argv, "precedence") == 0) {
+ diffserv = CAKE_DIFFSERV_PRECEDENCE;
+ } else if (strcmp(*argv, "diffserv8") == 0) {
+ diffserv = CAKE_DIFFSERV_DIFFSERV8;
+ } else if (strcmp(*argv, "diffserv4") == 0) {
+ diffserv = CAKE_DIFFSERV_DIFFSERV4;
+ } else if (strcmp(*argv, "diffserv") == 0) {
+ diffserv = CAKE_DIFFSERV_DIFFSERV4;
+ } else if (strcmp(*argv, "diffserv3") == 0) {
+ diffserv = CAKE_DIFFSERV_DIFFSERV3;
+ } else if (strcmp(*argv, "nowash") == 0) {
+ wash = 0;
+ } else if (strcmp(*argv, "wash") == 0) {
+ wash = 1;
+ } else if (strcmp(*argv, "flowblind") == 0) {
+ flowmode = CAKE_FLOW_NONE;
+ } else if (strcmp(*argv, "srchost") == 0) {
+ flowmode = CAKE_FLOW_SRC_IP;
+ } else if (strcmp(*argv, "dsthost") == 0) {
+ flowmode = CAKE_FLOW_DST_IP;
+ } else if (strcmp(*argv, "hosts") == 0) {
+ flowmode = CAKE_FLOW_HOSTS;
+ } else if (strcmp(*argv, "flows") == 0) {
+ flowmode = CAKE_FLOW_FLOWS;
+ } else if (strcmp(*argv, "dual-srchost") == 0) {
+ flowmode = CAKE_FLOW_DUAL_SRC;
+ } else if (strcmp(*argv, "dual-dsthost") == 0) {
+ flowmode = CAKE_FLOW_DUAL_DST;
+ } else if (strcmp(*argv, "triple-isolate") == 0) {
+ flowmode = CAKE_FLOW_TRIPLE;
+ } else if (strcmp(*argv, "nat") == 0) {
+ nat = 1;
+ } else if (strcmp(*argv, "nonat") == 0) {
+ nat = 0;
+ } else if (strcmp(*argv, "ptm") == 0) {
+ atm = CAKE_ATM_PTM;
+ } else if (strcmp(*argv, "atm") == 0) {
+ atm = CAKE_ATM_ATM;
+ } else if (strcmp(*argv, "noatm") == 0) {
+ atm = CAKE_ATM_NONE;
+ } else if (strcmp(*argv, "raw") == 0) {
+ atm = CAKE_ATM_NONE;
+ overhead = 0;
+ overhead_set = true;
+ overhead_override = true;
+ } else if (strcmp(*argv, "conservative") == 0) {
+ /*
+ * Deliberately over-estimate overhead:
+ * one whole ATM cell plus ATM framing.
+ * A safe choice if the actual overhead is unknown.
+ */
+ atm = CAKE_ATM_ATM;
+ overhead = 48;
+ overhead_set = true;
+
+ /* Various ADSL framing schemes, all over ATM cells */
+ } else if (strcmp(*argv, "ipoa-vcmux") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 8;
+ overhead_set = true;
+ } else if (strcmp(*argv, "ipoa-llcsnap") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 16;
+ overhead_set = true;
+ } else if (strcmp(*argv, "bridged-vcmux") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 24;
+ overhead_set = true;
+ } else if (strcmp(*argv, "bridged-llcsnap") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 32;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoa-vcmux") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 10;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoa-llc") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 14;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoe-vcmux") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 32;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoe-llcsnap") == 0) {
+ atm = CAKE_ATM_ATM;
+ overhead += 40;
+ overhead_set = true;
+
+ /* Typical VDSL2 framing schemes, both over PTM */
+ /* PTM has 64b/65b coding which absorbs some bandwidth */
+ } else if (strcmp(*argv, "pppoe-ptm") == 0) {
+ /* 2B PPP + 6B PPPoE + 6B dest MAC + 6B src MAC
+ * + 2B ethertype + 4B Frame Check Sequence
+ * + 1B Start of Frame (S) + 1B End of Frame (Ck)
+ * + 2B TC-CRC (PTM-FCS) = 30B
+ */
+ atm = CAKE_ATM_PTM;
+ overhead += 30;
+ overhead_set = true;
+ } else if (strcmp(*argv, "bridged-ptm") == 0) {
+ /* 6B dest MAC + 6B src MAC + 2B ethertype
+ * + 4B Frame Check Sequence
+ * + 1B Start of Frame (S) + 1B End of Frame (Ck)
+ * + 2B TC-CRC (PTM-FCS) = 22B
+ */
+ atm = CAKE_ATM_PTM;
+ overhead += 22;
+ overhead_set = true;
+ } else if (strcmp(*argv, "via-ethernet") == 0) {
+ /*
+ * We used to use this flag to manually compensate for
+ * Linux including the Ethernet header on Ethernet-type
+ * interfaces, but not on IP-type interfaces.
+ *
+ * It is no longer needed, because Cake now adjusts for
+ * that automatically, and is thus ignored.
+ *
+ * It would be deleted entirely, but it appears in the
+ * stats output when the automatic compensation is
+ * active.
+ */
+ } else if (strcmp(*argv, "ethernet") == 0) {
+ /* ethernet pre-amble & interframe gap & FCS
+ * you may need to add vlan tag
+ */
+ overhead += 38;
+ overhead_set = true;
+ mpu = 84;
+
+ /* Additional Ethernet-related overhead used by some ISPs */
+ } else if (strcmp(*argv, "ether-vlan") == 0) {
+ /* 802.1q VLAN tag - may be repeated */
+ overhead += 4;
+ overhead_set = true;
+
+ /*
+ * DOCSIS cable shapers account for Ethernet frame with FCS,
+ * but not interframe gap or preamble.
+ */
+ } else if (strcmp(*argv, "docsis") == 0) {
+ atm = CAKE_ATM_NONE;
+ overhead += 18;
+ overhead_set = true;
+ mpu = 64;
+ } else if (strcmp(*argv, "overhead") == 0) {
+ char *p = NULL;
+
+ NEXT_ARG();
+ overhead = strtol(*argv, &p, 10);
+ if (!p || *p || !*argv ||
+ overhead < -64 || overhead > 256) {
+ fprintf(stderr,
+ "Illegal \"overhead\", valid range is -64 to 256\\n");
+ return -1;
+ }
+ overhead_set = true;
+
+ } else if (strcmp(*argv, "mpu") == 0) {
+ char *p = NULL;
+
+ NEXT_ARG();
+ mpu = strtol(*argv, &p, 10);
+ if (!p || *p || !*argv || mpu < 0 || mpu > 256) {
+ fprintf(stderr,
+ "Illegal \"mpu\", valid range is 0 to 256\\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "ingress") == 0) {
+ ingress = 1;
+ } else if (strcmp(*argv, "egress") == 0) {
+ ingress = 0;
+ } else if (strcmp(*argv, "no-ack-filter") == 0) {
+ ack_filter = CAKE_ACK_NONE;
+ } else if (strcmp(*argv, "ack-filter") == 0) {
+ ack_filter = CAKE_ACK_FILTER;
+ } else if (strcmp(*argv, "ack-filter-aggressive") == 0) {
+ ack_filter = CAKE_ACK_AGGRESSIVE;
+ } else if (strcmp(*argv, "memlimit") == 0) {
+ NEXT_ARG();
+ if (get_size(&memlimit, *argv)) {
+ fprintf(stderr,
+ "Illegal value for \"memlimit\": \"%s\"\n", *argv);
+ return -1;
+ }
+ } 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 (bandwidth || unlimited)
+ addattr_l(n, 1024, TCA_CAKE_BASE_RATE64, &bandwidth,
+ sizeof(bandwidth));
+ if (diffserv)
+ addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv,
+ sizeof(diffserv));
+ if (atm != -1)
+ addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm));
+ if (flowmode != -1)
+ addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode,
+ sizeof(flowmode));
+ if (overhead_set)
+ addattr_l(n, 1024, TCA_CAKE_OVERHEAD, &overhead,
+ sizeof(overhead));
+ if (overhead_override) {
+ unsigned int zero = 0;
+
+ addattr_l(n, 1024, TCA_CAKE_RAW, &zero, sizeof(zero));
+ }
+ if (mpu > 0)
+ addattr_l(n, 1024, TCA_CAKE_MPU, &mpu, sizeof(mpu));
+ if (interval)
+ addattr_l(n, 1024, TCA_CAKE_RTT, &interval, sizeof(interval));
+ if (target)
+ addattr_l(n, 1024, TCA_CAKE_TARGET, &target, sizeof(target));
+ if (autorate != -1)
+ addattr_l(n, 1024, TCA_CAKE_AUTORATE, &autorate,
+ sizeof(autorate));
+ if (memlimit)
+ addattr_l(n, 1024, TCA_CAKE_MEMORY, &memlimit,
+ sizeof(memlimit));
+ if (nat != -1)
+ addattr_l(n, 1024, TCA_CAKE_NAT, &nat, sizeof(nat));
+ if (wash != -1)
+ addattr_l(n, 1024, TCA_CAKE_WASH, &wash, sizeof(wash));
+ if (ingress != -1)
+ addattr_l(n, 1024, TCA_CAKE_INGRESS, &ingress, sizeof(ingress));
+ if (ack_filter != -1)
+ addattr_l(n, 1024, TCA_CAKE_ACK_FILTER, &ack_filter,
+ sizeof(ack_filter));
+
+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
+ return 0;
+}
+
+static void cake_print_mode(unsigned int value, unsigned int max,
+ const char *key, const char **table)
+{
+ if (value < max && table[value]) {
+ print_string(PRINT_ANY, key, "%s ", table[value]);
+ } else {
+ print_string(PRINT_JSON, key, NULL, "unknown");
+ print_string(PRINT_FP, NULL, "(?%s?)", key);
+ }
+}
+
+static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct rtattr *tb[TCA_CAKE_MAX + 1];
+ unsigned int interval = 0;
+ unsigned int memlimit = 0;
+ __u64 bandwidth = 0;
+ int ack_filter = 0;
+ int split_gso = 0;
+ int overhead = 0;
+ int autorate = 0;
+ int ingress = 0;
+ int wash = 0;
+ int raw = 0;
+ int mpu = 0;
+ int atm = 0;
+ int nat = 0;
+
+ SPRINT_BUF(b1);
+ SPRINT_BUF(b2);
+
+ if (opt == NULL)
+ return 0;
+
+ parse_rtattr_nested(tb, TCA_CAKE_MAX, opt);
+
+ if (tb[TCA_CAKE_BASE_RATE64] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) {
+ bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]);
+ if (bandwidth) {
+ print_uint(PRINT_JSON, "bandwidth", NULL, bandwidth);
+ print_string(PRINT_FP, NULL, "bandwidth %s ",
+ sprint_rate(bandwidth, b1));
+ } else
+ print_string(PRINT_ANY, "bandwidth", "bandwidth %s ",
+ "unlimited");
+ }
+ if (tb[TCA_CAKE_AUTORATE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_AUTORATE]) >= sizeof(__u32)) {
+ autorate = rta_getattr_u32(tb[TCA_CAKE_AUTORATE]);
+ if (autorate == 1)
+ print_string(PRINT_ANY, "autorate", "autorate_%s ",
+ "ingress");
+ else if (autorate)
+ print_string(PRINT_ANY, "autorate", "(?autorate?) ",
+ "unknown");
+ }
+ if (tb[TCA_CAKE_DIFFSERV_MODE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) {
+ cake_print_mode(rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]),
+ CAKE_DIFFSERV_MAX, "diffserv", diffserv_names);
+ }
+ if (tb[TCA_CAKE_FLOW_MODE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) {
+ cake_print_mode(rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]),
+ CAKE_FLOW_MAX, "flowmode", flowmode_names);
+ }
+
+ if (tb[TCA_CAKE_NAT] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_NAT]) >= sizeof(__u32)) {
+ nat = rta_getattr_u32(tb[TCA_CAKE_NAT]);
+ }
+
+ if (nat)
+ print_string(PRINT_FP, NULL, "nat ", NULL);
+ print_bool(PRINT_JSON, "nat", NULL, nat);
+
+ if (tb[TCA_CAKE_WASH] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_WASH]) >= sizeof(__u32)) {
+ wash = rta_getattr_u32(tb[TCA_CAKE_WASH]);
+ }
+ if (tb[TCA_CAKE_ATM] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) {
+ atm = rta_getattr_u32(tb[TCA_CAKE_ATM]);
+ }
+ if (tb[TCA_CAKE_OVERHEAD] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_OVERHEAD]) >= sizeof(__s32)) {
+ overhead = *(__s32 *) RTA_DATA(tb[TCA_CAKE_OVERHEAD]);
+ }
+ if (tb[TCA_CAKE_MPU] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_MPU]) >= sizeof(__u32)) {
+ mpu = rta_getattr_u32(tb[TCA_CAKE_MPU]);
+ }
+ if (tb[TCA_CAKE_INGRESS] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_INGRESS]) >= sizeof(__u32)) {
+ ingress = rta_getattr_u32(tb[TCA_CAKE_INGRESS]);
+ }
+ if (tb[TCA_CAKE_ACK_FILTER] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_ACK_FILTER]) >= sizeof(__u32)) {
+ ack_filter = rta_getattr_u32(tb[TCA_CAKE_ACK_FILTER]);
+ }
+ if (tb[TCA_CAKE_SPLIT_GSO] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_SPLIT_GSO]) >= sizeof(__u32)) {
+ split_gso = rta_getattr_u32(tb[TCA_CAKE_SPLIT_GSO]);
+ }
+ if (tb[TCA_CAKE_RAW]) {
+ raw = 1;
+ }
+ if (tb[TCA_CAKE_RTT] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_RTT]) >= sizeof(__u32)) {
+ interval = rta_getattr_u32(tb[TCA_CAKE_RTT]);
+ }
+
+ if (wash)
+ print_string(PRINT_FP, NULL, "wash ", NULL);
+ print_bool(PRINT_JSON, "wash", NULL, wash);
+
+ if (ingress)
+ print_string(PRINT_FP, NULL, "ingress ", NULL);
+ print_bool(PRINT_JSON, "ingress", NULL, ingress);
+
+ if (ack_filter == CAKE_ACK_AGGRESSIVE)
+ print_string(PRINT_ANY, "ack-filter", "ack-filter-%s ",
+ "aggressive");
+ else if (ack_filter == CAKE_ACK_FILTER)
+ print_string(PRINT_ANY, "ack-filter", "ack-filter ", "enabled");
+ else
+ print_string(PRINT_JSON, "ack-filter", NULL, "disabled");
+
+ if (split_gso)
+ print_string(PRINT_FP, NULL, "split-gso ", NULL);
+ print_bool(PRINT_JSON, "split_gso", NULL, split_gso);
+
+ if (interval)
+ print_string(PRINT_FP, NULL, "rtt %s ",
+ sprint_time(interval, b2));
+ print_uint(PRINT_JSON, "rtt", NULL, interval);
+
+ if (raw)
+ print_string(PRINT_FP, NULL, "raw ", NULL);
+ print_bool(PRINT_JSON, "raw", NULL, raw);
+
+ if (atm == CAKE_ATM_ATM)
+ print_string(PRINT_ANY, "atm", "%s ", "atm");
+ else if (atm == CAKE_ATM_PTM)
+ print_string(PRINT_ANY, "atm", "%s ", "ptm");
+ else if (!raw)
+ print_string(PRINT_ANY, "atm", "%s ", "noatm");
+
+ print_int(PRINT_ANY, "overhead", "overhead %d ", overhead);
+
+ if (mpu)
+ print_uint(PRINT_ANY, "mpu", "mpu %u ", mpu);
+
+ if (memlimit) {
+ print_uint(PRINT_JSON, "memlimit", NULL, memlimit);
+ print_string(PRINT_FP, NULL, "memlimit %s",
+ sprint_size(memlimit, b1));
+ }
+
+ return 0;
+}
+
+static void cake_print_json_tin(struct rtattr **tstat)
+{
+#define PRINT_TSTAT_JSON(type, name, attr) if (tstat[TCA_CAKE_TIN_STATS_ ## attr]) \
+ print_u64(PRINT_JSON, name, NULL, \
+ rta_getattr_ ## type((struct rtattr *) \
+ tstat[TCA_CAKE_TIN_STATS_ ## attr]))
+
+ open_json_object(NULL);
+ PRINT_TSTAT_JSON(u64, "threshold_rate", THRESHOLD_RATE64);
+ PRINT_TSTAT_JSON(u64, "sent_bytes", SENT_BYTES64);
+ PRINT_TSTAT_JSON(u32, "backlog_bytes", BACKLOG_BYTES);
+ PRINT_TSTAT_JSON(u32, "target_us", TARGET_US);
+ PRINT_TSTAT_JSON(u32, "interval_us", INTERVAL_US);
+ PRINT_TSTAT_JSON(u32, "peak_delay_us", PEAK_DELAY_US);
+ PRINT_TSTAT_JSON(u32, "avg_delay_us", AVG_DELAY_US);
+ PRINT_TSTAT_JSON(u32, "base_delay_us", BASE_DELAY_US);
+ PRINT_TSTAT_JSON(u32, "sent_packets", SENT_PACKETS);
+ PRINT_TSTAT_JSON(u32, "way_indirect_hits", WAY_INDIRECT_HITS);
+ PRINT_TSTAT_JSON(u32, "way_misses", WAY_MISSES);
+ PRINT_TSTAT_JSON(u32, "way_collisions", WAY_COLLISIONS);
+ PRINT_TSTAT_JSON(u32, "drops", DROPPED_PACKETS);
+ PRINT_TSTAT_JSON(u32, "ecn_mark", ECN_MARKED_PACKETS);
+ PRINT_TSTAT_JSON(u32, "ack_drops", ACKS_DROPPED_PACKETS);
+ PRINT_TSTAT_JSON(u32, "sparse_flows", SPARSE_FLOWS);
+ PRINT_TSTAT_JSON(u32, "bulk_flows", BULK_FLOWS);
+ PRINT_TSTAT_JSON(u32, "unresponsive_flows", UNRESPONSIVE_FLOWS);
+ PRINT_TSTAT_JSON(u32, "max_pkt_len", MAX_SKBLEN);
+ PRINT_TSTAT_JSON(u32, "flow_quantum", FLOW_QUANTUM);
+ close_json_object();
+
+#undef PRINT_TSTAT_JSON
+}
+
+static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
+ struct rtattr *xstats)
+{
+ struct rtattr *st[TCA_CAKE_STATS_MAX + 1];
+ SPRINT_BUF(b1);
+ int i;
+
+ if (xstats == NULL)
+ return 0;
+
+#define GET_STAT_U32(attr) rta_getattr_u32(st[TCA_CAKE_STATS_ ## attr])
+#define GET_STAT_S32(attr) (*(__s32 *)RTA_DATA(st[TCA_CAKE_STATS_ ## attr]))
+#define GET_STAT_U64(attr) rta_getattr_u64(st[TCA_CAKE_STATS_ ## attr])
+
+ parse_rtattr_nested(st, TCA_CAKE_STATS_MAX, xstats);
+
+ if (st[TCA_CAKE_STATS_MEMORY_USED] &&
+ st[TCA_CAKE_STATS_MEMORY_LIMIT]) {
+ print_string(PRINT_FP, NULL, " memory used: %s",
+ sprint_size(GET_STAT_U32(MEMORY_USED), b1));
+
+ print_string(PRINT_FP, NULL, " of %s\n",
+ sprint_size(GET_STAT_U32(MEMORY_LIMIT), b1));
+
+ print_uint(PRINT_JSON, "memory_used", NULL,
+ GET_STAT_U32(MEMORY_USED));
+ print_uint(PRINT_JSON, "memory_limit", NULL,
+ GET_STAT_U32(MEMORY_LIMIT));
+ }
+
+ if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) {
+ print_string(PRINT_FP, NULL, " capacity estimate: %s\n",
+ sprint_rate(GET_STAT_U64(CAPACITY_ESTIMATE64), b1));
+ print_uint(PRINT_JSON, "capacity_estimate", NULL,
+ GET_STAT_U64(CAPACITY_ESTIMATE64));
+ }
+
+ if (st[TCA_CAKE_STATS_MIN_NETLEN] &&
+ st[TCA_CAKE_STATS_MAX_NETLEN]) {
+ print_uint(PRINT_ANY, "min_network_size",
+ " min/max network layer size: %12u",
+ GET_STAT_U32(MIN_NETLEN));
+ print_uint(PRINT_ANY, "max_network_size",
+ " /%8u\n", GET_STAT_U32(MAX_NETLEN));
+ }
+
+ if (st[TCA_CAKE_STATS_MIN_ADJLEN] &&
+ st[TCA_CAKE_STATS_MAX_ADJLEN]) {
+ print_uint(PRINT_ANY, "min_adj_size",
+ " min/max overhead-adjusted size: %8u",
+ GET_STAT_U32(MIN_ADJLEN));
+ print_uint(PRINT_ANY, "max_adj_size",
+ " /%8u\n", GET_STAT_U32(MAX_ADJLEN));
+ }
+
+ if (st[TCA_CAKE_STATS_AVG_NETOFF])
+ print_uint(PRINT_ANY, "avg_hdr_offset",
+ " average network hdr offset: %12u\n\n",
+ GET_STAT_U32(AVG_NETOFF));
+
+ /* class stats */
+ if (st[TCA_CAKE_STATS_DEFICIT])
+ print_int(PRINT_ANY, "deficit", " deficit %u",
+ GET_STAT_S32(DEFICIT));
+ if (st[TCA_CAKE_STATS_COBALT_COUNT])
+ print_uint(PRINT_ANY, "count", " count %u",
+ GET_STAT_U32(COBALT_COUNT));
+
+ if (st[TCA_CAKE_STATS_DROPPING] && GET_STAT_U32(DROPPING)) {
+ print_bool(PRINT_ANY, "dropping", " dropping", true);
+ if (st[TCA_CAKE_STATS_DROP_NEXT_US]) {
+ int drop_next = GET_STAT_S32(DROP_NEXT_US);
+
+ if (drop_next < 0) {
+ print_string(PRINT_FP, NULL, " drop_next -%s",
+ sprint_time(drop_next, b1));
+ } else {
+ print_uint(PRINT_JSON, "drop_next", NULL,
+ drop_next);
+ print_string(PRINT_FP, NULL, " drop_next %s",
+ sprint_time(drop_next, b1));
+ }
+ }
+ }
+
+ if (st[TCA_CAKE_STATS_P_DROP]) {
+ print_uint(PRINT_ANY, "blue_prob", " blue_prob %u",
+ GET_STAT_U32(P_DROP));
+ if (st[TCA_CAKE_STATS_BLUE_TIMER_US]) {
+ int blue_timer = GET_STAT_S32(BLUE_TIMER_US);
+
+ if (blue_timer < 0) {
+ print_string(PRINT_FP, NULL, " blue_timer -%s",
+ sprint_time(blue_timer, b1));
+ } else {
+ print_uint(PRINT_JSON, "blue_timer", NULL,
+ blue_timer);
+ print_string(PRINT_FP, NULL, " blue_timer %s",
+ sprint_time(blue_timer, b1));
+ }
+ }
+ }
+
+#undef GET_STAT_U32
+#undef GET_STAT_S32
+#undef GET_STAT_U64
+
+ if (st[TCA_CAKE_STATS_TIN_STATS]) {
+ struct rtattr *tstat[TC_CAKE_MAX_TINS][TCA_CAKE_TIN_STATS_MAX + 1];
+ struct rtattr *tins[TC_CAKE_MAX_TINS + 1];
+ int num_tins = 0;
+
+ parse_rtattr_nested(tins, TC_CAKE_MAX_TINS,
+ st[TCA_CAKE_STATS_TIN_STATS]);
+
+ for (i = 1; i <= TC_CAKE_MAX_TINS && tins[i]; i++) {
+ parse_rtattr_nested(tstat[i-1], TCA_CAKE_TIN_STATS_MAX,
+ tins[i]);
+ num_tins++;
+ }
+
+ if (!num_tins)
+ return 0;
+
+ if (is_json_context()) {
+ open_json_array(PRINT_JSON, "tins");
+ for (i = 0; i < num_tins; i++)
+ cake_print_json_tin(tstat[i]);
+ close_json_array(PRINT_JSON, NULL);
+
+ return 0;
+ }
+
+
+ switch (num_tins) {
+ case 3:
+ fprintf(f, " Bulk Best Effort Voice\n");
+ break;
+
+ case 4:
+ fprintf(f, " Bulk Best Effort Video Voice\n");
+ break;
+
+ default:
+ fprintf(f, " ");
+ for (i = 0; i < num_tins; i++)
+ fprintf(f, " Tin %u", i);
+ fprintf(f, "\n");
+ };
+
+#define GET_TSTAT(i, attr) (tstat[i][TCA_CAKE_TIN_STATS_ ## attr])
+#define PRINT_TSTAT(name, attr, fmts, val) do { \
+ if (GET_TSTAT(0, attr)) { \
+ fprintf(f, name); \
+ for (i = 0; i < num_tins; i++) \
+ fprintf(f, " %12" fmts, val); \
+ fprintf(f, "\n"); \
+ } \
+ } while (0)
+
+#define SPRINT_TSTAT(pfunc, type, name, attr) PRINT_TSTAT( \
+ name, attr, "s", sprint_ ## pfunc( \
+ rta_getattr_ ## type(GET_TSTAT(i, attr)), b1))
+
+#define PRINT_TSTAT_U32(name, attr) PRINT_TSTAT( \
+ name, attr, "u", rta_getattr_u32(GET_TSTAT(i, attr)))
+
+#define PRINT_TSTAT_U64(name, attr) PRINT_TSTAT( \
+ name, attr, "llu", rta_getattr_u64(GET_TSTAT(i, attr)))
+
+ SPRINT_TSTAT(rate, u64, " thresh ", THRESHOLD_RATE64);
+ SPRINT_TSTAT(time, u32, " target ", TARGET_US);
+ SPRINT_TSTAT(time, u32, " interval", INTERVAL_US);
+ SPRINT_TSTAT(time, u32, " pk_delay", PEAK_DELAY_US);
+ SPRINT_TSTAT(time, u32, " av_delay", AVG_DELAY_US);
+ SPRINT_TSTAT(time, u32, " sp_delay", BASE_DELAY_US);
+ SPRINT_TSTAT(size, u32, " backlog ", BACKLOG_BYTES);
+
+ PRINT_TSTAT_U32(" pkts ", SENT_PACKETS);
+ PRINT_TSTAT_U64(" bytes ", SENT_BYTES64);
+
+ PRINT_TSTAT_U32(" way_inds", WAY_INDIRECT_HITS);
+ PRINT_TSTAT_U32(" way_miss", WAY_MISSES);
+ PRINT_TSTAT_U32(" way_cols", WAY_COLLISIONS);
+ PRINT_TSTAT_U32(" drops ", DROPPED_PACKETS);
+ PRINT_TSTAT_U32(" marks ", ECN_MARKED_PACKETS);
+ PRINT_TSTAT_U32(" ack_drop", ACKS_DROPPED_PACKETS);
+ PRINT_TSTAT_U32(" sp_flows", SPARSE_FLOWS);
+ PRINT_TSTAT_U32(" bk_flows", BULK_FLOWS);
+ PRINT_TSTAT_U32(" un_flows", UNRESPONSIVE_FLOWS);
+ PRINT_TSTAT_U32(" max_len ", MAX_SKBLEN);
+ PRINT_TSTAT_U32(" quantum ", FLOW_QUANTUM);
+
+#undef GET_STAT
+#undef PRINT_TSTAT
+#undef SPRINT_TSTAT
+#undef PRINT_TSTAT_U32
+#undef PRINT_TSTAT_U64
+ }
+ return 0;
+}
+
+struct qdisc_util cake_qdisc_util = {
+ .id = "cake",
+ .parse_qopt = cake_parse_opt,
+ .print_qopt = cake_print_opt,
+ .print_xstats = cake_print_xstats,
+};
--
2.18.0
^ permalink raw reply related
* Re: [PATCH net-next v2 6/7] net: Create reusable function for getting ownership info of sysfs inodes
From: Christian Brauner @ 2018-07-19 14:36 UTC (permalink / raw)
To: Tyler Hicks
Cc: Greg Kroah-Hartman, Tejun Heo, David S. Miller, Stephen Hemminger,
Dmitry Torokhov, netdev, Linux Containers, bridge, linux-kernel,
Eric W. Biederman
In-Reply-To: <1531497949-1766-7-git-send-email-tyhicks@canonical.com>
[-- Attachment #1: Type: text/plain, Size: 4091 bytes --]
On Fri, Jul 13, 2018 at 04:05:48PM +0000, Tyler Hicks wrote:
> Make net_ns_get_ownership() reusable by networking code outside of core.
> This is useful, for example, to allow bridge related sysfs files to be
> owned by container root.
>
> Add a function comment since this is a potentially dangerous function to
> use given the way that kobject_get_ownership() works by initializing uid
> and gid before calling .get_ownership().
>
> Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
> ---
> include/net/net_namespace.h | 7 +++++++
> net/core/net-sysfs.c | 15 ---------------
> net/core/net_namespace.c | 25 +++++++++++++++++++++++++
> 3 files changed, 32 insertions(+), 15 deletions(-)
>
> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> index a71264d75d7f..a257710527ce 100644
> --- a/include/net/net_namespace.h
> +++ b/include/net/net_namespace.h
> @@ -170,6 +170,8 @@ extern struct net init_net;
> struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns,
> struct net *old_net);
>
> +void net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid);
> +
> void net_ns_barrier(void);
> #else /* CONFIG_NET_NS */
> #include <linux/sched.h>
> @@ -182,6 +184,11 @@ static inline struct net *copy_net_ns(unsigned long flags,
> return old_net;
> }
>
> +static inline void net_ns_get_ownership(const struct net *net,
> + kuid_t *uid, kgid_t *gid)
> +{
> +}
> +
> static inline void net_ns_barrier(void) {}
> #endif /* CONFIG_NET_NS */
>
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 41d84c40fe51..a3ad8108d296 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -656,21 +656,6 @@ static const struct attribute_group wireless_group = {
> #define net_class_groups NULL
> #endif /* CONFIG_SYSFS */
>
> -static void net_ns_get_ownership(const struct net *net,
> - kuid_t *uid, kgid_t *gid)
> -{
> - if (net) {
> - kuid_t ns_root_uid = make_kuid(net->user_ns, 0);
> - kgid_t ns_root_gid = make_kgid(net->user_ns, 0);
> -
> - if (uid_valid(ns_root_uid))
> - *uid = ns_root_uid;
> -
> - if (gid_valid(ns_root_gid))
> - *gid = ns_root_gid;
> - }
> -}
> -
> #ifdef CONFIG_SYSFS
> #define to_rx_queue_attr(_attr) \
> container_of(_attr, struct rx_queue_attribute, attr)
> diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> index a11e03f920d3..5257875fa84d 100644
> --- a/net/core/net_namespace.c
> +++ b/net/core/net_namespace.c
> @@ -448,6 +448,31 @@ struct net *copy_net_ns(unsigned long flags,
> return net;
> }
>
> +/**
> + * net_ns_get_ownership - get sysfs ownership data for @net
> + * @net: network namespace in question (can be NULL)
> + * @uid: kernel user ID for sysfs objects (must be GLOBAL_ROOT_UID)
> + * @gid: kernel group ID for sysfs objects (must be GLOBAL_ROOT_GID)
> + *
> + * Returns the uid/gid pair of root in the user namespace associated with the
> + * given network namespace. The caller must initialize @uid and @gid to
> + * GLOBAL_ROOT_UID/GLOBAL_ROOT_GID before calling this function.
If they must be so initialized why not just enforce this directly in the
function? This way callers can rely on always getting back the correct
permissions and the comment can be removed as well.
Christian
> + */
> +void net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid)
> +{
> + if (net) {
> + kuid_t ns_root_uid = make_kuid(net->user_ns, 0);
> + kgid_t ns_root_gid = make_kgid(net->user_ns, 0);
> +
> + if (uid_valid(ns_root_uid))
> + *uid = ns_root_uid;
> +
> + if (gid_valid(ns_root_gid))
> + *gid = ns_root_gid;
> + }
> +}
> +EXPORT_SYMBOL_GPL(net_ns_get_ownership);
> +
> static void unhash_nsid(struct net *net, struct net *last)
> {
> struct net *tmp;
> --
> 2.7.4
>
> _______________________________________________
> Containers mailing list
> Containers@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/containers
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 0/5] ARM: dts: sunxi: Remove unused address-cells/size-cells of dwmac-sun8i
From: Maxime Ripard @ 2018-07-19 14:33 UTC (permalink / raw)
To: Corentin Labbe
Cc: catalin.marinas-5wv7dgnIgG8, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
wens-jdAy2FN1RRM, will.deacon-5wv7dgnIgG8,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <1531914041-14751-1-git-send-email-clabbe-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 531 bytes --]
On Wed, Jul 18, 2018 at 11:40:36AM +0000, Corentin Labbe wrote:
> address-cells/size-cells is unnecessary for dwmac-sun8i node.
> It was in early days, but since a mdio node is used, it could be
> removed.
>
> This patch fix the following DT warning:
> Warning (avoid_unnecessary_addr_size): /soc/ethernet@1c50000: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
Applied, thanks
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH] bpf: synchronize bpf uapi header with tools
From: Taeung Song @ 2018-07-19 14:21 UTC (permalink / raw)
To: Quentin Monnet
Cc: Alexei Starovoitov, Daniel Borkmann, netdev, linux-kernel,
Arnaldo Carvalho de Melo, David Ahern
In-Reply-To: <77e00498-74ae-1ee5-8f4b-ad8b3c5f8929@netronome.com>
Hi Quentin,
On 07/19/2018 11:01 PM, Quentin Monnet wrote:
> Hi Taeung,
>
> 2018-07-19 21:53 UTC+0900 ~ Taeung Song <treeze.taeung@gmail.com>
>> To pick the change in:
>>
>> 4c79579b44b1 ("bpf: Change bpf_fib_lookup to return lookup status")
>>
>> This bpftool build warning occurs:
>>
>> Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'
>>
>> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
>> Cc: David Ahern <dsahern@gmail.com>
>> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
>> ---
>> tools/include/uapi/linux/bpf.h | 28 +++++++++++++++++++++++-----
>> 1 file changed, 23 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
>> index 59b19b6a40d7..b7db3261c62d 100644
>> --- a/tools/include/uapi/linux/bpf.h
>> +++ b/tools/include/uapi/linux/bpf.h
>> @@ -1857,7 +1857,8 @@ union bpf_attr {
>> * is resolved), the nexthop address is returned in ipv4_dst
>> * or ipv6_dst based on family, smac is set to mac address of
>> * egress device, dmac is set to nexthop mac address, rt_metric
>> - * is set to metric from route (IPv4/IPv6 only).
>> + * is set to metric from route (IPv4/IPv6 only), and ifindex
>> + * is set to the device index of the nexthop from the FIB lookup.
>> *
>> * *plen* argument is the size of the passed in struct.
>> * *flags* argument can be a combination of one or more of the
>> @@ -1873,9 +1874,10 @@ union bpf_attr {
>> * *ctx* is either **struct xdp_md** for XDP programs or
>> * **struct sk_buff** tc cls_act programs.
>> * Return
>> - * Egress device index on success, 0 if packet needs to continue
>> - * up the stack for further processing or a negative error in case
>> - * of failure.
>> + * * < 0 if any input argument is invalid
>> + * * 0 on success (packet is forwarded, nexthop neighbor exists)
>> + * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
>> + * * packet is not forwarded or needs assist from full stack
>> *
>> * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
>> * Description
>> @@ -2612,6 +2614,18 @@ struct bpf_raw_tracepoint_args {
>> #define BPF_FIB_LOOKUP_DIRECT BIT(0)
>> #define BPF_FIB_LOOKUP_OUTPUT BIT(1)
>>
>> +enum {
>> + BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
>> + BPF_FIB_LKUP_RET_BLACKHOLE, /* dest is blackholed; can be dropped */
>> + BPF_FIB_LKUP_RET_UNREACHABLE, /* dest is unreachable; can be dropped */
>> + BPF_FIB_LKUP_RET_PROHIBIT, /* dest not allowed; can be dropped */
>> + BPF_FIB_LKUP_RET_NOT_FWDED, /* packet is not forwarded */
>> + BPF_FIB_LKUP_RET_FWD_DISABLED, /* fwding is not enabled on ingress */
>> + BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */
>> + BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */
>> + BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */
>> +};
>> +
>> struct bpf_fib_lookup {
>> /* input: network family for lookup (AF_INET, AF_INET6)
>> * output: network family of egress nexthop
>> @@ -2625,7 +2639,11 @@ struct bpf_fib_lookup {
>>
>> /* total length of packet from network header - used for MTU check */
>> __u16 tot_len;
>> - __u32 ifindex; /* L3 device index for lookup */
>> +
>> + /* input: L3 device index for lookup
>> + * output: device index from FIB lookup
>> + */
>> + __u32 ifindex;
>>
>> union {
>> /* inputs to lookup */
>>
>
> This has been updated in the bpf-next tree already, see commit
> 9b8ca3795199 ("tools: bpf: synchronise BPF UAPI header with tools").
>
> Best regards,
> Quentin
>
OK ! Thanks.
--
Thanks,
Taeung
^ permalink raw reply
* [PATCH net-next] libcxgb: replace vmalloc and memset with vzalloc
From: YueHaibing @ 2018-07-19 14:18 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, YueHaibing
Use vzalloc instead of the vmalloc, memset combo
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
index 0ed1616..74849be 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
+++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
@@ -412,12 +412,10 @@ int cxgbi_ppm_init(void **ppm_pp, struct net_device *ndev,
ppmax * (sizeof(struct cxgbi_ppod_data)) +
ppod_bmap_size * sizeof(unsigned long);
- ppm = vmalloc(alloc_sz);
+ ppm = vzalloc(alloc_sz);
if (!ppm)
goto release_ppm_pool;
- memset(ppm, 0, alloc_sz);
-
ppm->ppod_bmap = (unsigned long *)(&ppm->ppod_data[ppmax]);
if ((ppod_bmap_size >> 3) > (ppmax - ppmax_pool)) {
--
2.7.0
^ permalink raw reply related
* Re: [PATCH] net: mediatek: use dma_zalloc_coherent instead of allocator/memset
From: Russell King - ARM Linux @ 2018-07-19 14:17 UTC (permalink / raw)
To: YueHaibing
Cc: davem, nbd, john, sean.wang, nelson.chang, netdev, linux-kernel,
linux-mediatek, matthias.bgg, linux-arm-kernel
In-Reply-To: <20180719140955.19444-1-yuehaibing@huawei.com>
On Thu, Jul 19, 2018 at 10:09:55PM +0800, YueHaibing wrote:
> Use dma_zalloc_coherent instead of dma_alloc_coherent
> followed by memset 0.
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index d8ebf0a..fbdb3e3 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -1221,14 +1221,11 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
> if (!ring->buf)
> goto no_tx_mem;
>
> - ring->dma = dma_alloc_coherent(eth->dev,
> - MTK_DMA_SIZE * sz,
> - &ring->phys,
> - GFP_ATOMIC | __GFP_ZERO);
> + ring->dma = dma_zalloc_coherent(eth->dev, MTK_DMA_SIZE * sz,
> + &ring->phys, GFP_ATOMIC | __GFP_ZERO);
> if (!ring->dma)
> goto no_tx_mem;
>
> - memset(ring->dma, 0, MTK_DMA_SIZE * sz);
I have to wonder whether this code needs two forms of zeroing... in
the original code, __GFP_ZERO _and_ a call to memset() just in case
__GFP_ZERO failed to do its job, and in the replacement code, just
in case dma_zalloc_coherent() hasn't got the idea...
I think you can drop the __GFP_ZERO. ;)
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up
According to speedtest.net: 13Mbps down 490kbps up
^ permalink raw reply
* Re: [PATCH V4 net-next 3/3] tcp: Add tcp_clamp_rto_to_user_timeout() helper to improve accuracy
From: Eric Dumazet @ 2018-07-19 14:15 UTC (permalink / raw)
To: Jon Maxwell, davem
Cc: edumazet, ncardwell, David.Laight, kuznet, yoshfuji, netdev,
linux-kernel, jmaxwell
In-Reply-To: <20180719011444.4694-4-jmaxwell37@gmail.com>
On 07/18/2018 06:14 PM, Jon Maxwell wrote:
> Create the tcp_clamp_rto_to_user_timeout() helper routine. To calculate
> the correct rto, so that the TCP_USER_TIMEOUT socket option is more
> accurate. Taking suggestions and feedback into account from
> Eric Dumazet, Neal Cardwell and David Laight. Due to the 1st commit we
> can avoid the msecs_to_jiffies() and jiffies_to_msecs() dance.
>
> Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Thanks !
^ permalink raw reply
* [PATCH] net: mediatek: use dma_zalloc_coherent instead of allocator/memset
From: YueHaibing @ 2018-07-19 14:09 UTC (permalink / raw)
To: davem, nbd, john, sean.wang, nelson.chang
Cc: linux-kernel, netdev, matthias.bgg, linux-arm-kernel,
linux-mediatek, YueHaibing
Use dma_zalloc_coherent instead of dma_alloc_coherent
followed by memset 0.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index d8ebf0a..fbdb3e3 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1221,14 +1221,11 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
if (!ring->buf)
goto no_tx_mem;
- ring->dma = dma_alloc_coherent(eth->dev,
- MTK_DMA_SIZE * sz,
- &ring->phys,
- GFP_ATOMIC | __GFP_ZERO);
+ ring->dma = dma_zalloc_coherent(eth->dev, MTK_DMA_SIZE * sz,
+ &ring->phys, GFP_ATOMIC | __GFP_ZERO);
if (!ring->dma)
goto no_tx_mem;
- memset(ring->dma, 0, MTK_DMA_SIZE * sz);
for (i = 0; i < MTK_DMA_SIZE; i++) {
int next = (i + 1) % MTK_DMA_SIZE;
u32 next_ptr = ring->phys + next * sz;
--
2.7.0
^ permalink raw reply related
* [PATCH net-next] ixgb: use dma_zalloc_coherent instead of allocator/memset
From: YueHaibing @ 2018-07-19 14:04 UTC (permalink / raw)
To: davem, jeffrey.t.kirsher
Cc: linux-kernel, netdev, intel-wired-lan, YueHaibing
Use dma_zalloc_coherent instead of dma_alloc_coherent
followed by memset 0.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/intel/ixgb/ixgb_main.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index 43664ad..d3e72d0 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -771,14 +771,13 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc);
rxdr->size = ALIGN(rxdr->size, 4096);
- rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
- GFP_KERNEL);
+ rxdr->desc = dma_zalloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
+ GFP_KERNEL);
if (!rxdr->desc) {
vfree(rxdr->buffer_info);
return -ENOMEM;
}
- memset(rxdr->desc, 0, rxdr->size);
rxdr->next_to_clean = 0;
rxdr->next_to_use = 0;
--
2.7.0
^ permalink raw reply related
* Re: [PATCH] bpf: synchronize bpf uapi header with tools
From: Quentin Monnet @ 2018-07-19 14:01 UTC (permalink / raw)
To: Taeung Song, Alexei Starovoitov, Daniel Borkmann
Cc: netdev, linux-kernel, Arnaldo Carvalho de Melo, David Ahern
In-Reply-To: <20180719125355.26441-1-treeze.taeung@gmail.com>
Hi Taeung,
2018-07-19 21:53 UTC+0900 ~ Taeung Song <treeze.taeung@gmail.com>
> To pick the change in:
>
> 4c79579b44b1 ("bpf: Change bpf_fib_lookup to return lookup status")
>
> This bpftool build warning occurs:
>
> Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'
>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: David Ahern <dsahern@gmail.com>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
> tools/include/uapi/linux/bpf.h | 28 +++++++++++++++++++++++-----
> 1 file changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index 59b19b6a40d7..b7db3261c62d 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -1857,7 +1857,8 @@ union bpf_attr {
> * is resolved), the nexthop address is returned in ipv4_dst
> * or ipv6_dst based on family, smac is set to mac address of
> * egress device, dmac is set to nexthop mac address, rt_metric
> - * is set to metric from route (IPv4/IPv6 only).
> + * is set to metric from route (IPv4/IPv6 only), and ifindex
> + * is set to the device index of the nexthop from the FIB lookup.
> *
> * *plen* argument is the size of the passed in struct.
> * *flags* argument can be a combination of one or more of the
> @@ -1873,9 +1874,10 @@ union bpf_attr {
> * *ctx* is either **struct xdp_md** for XDP programs or
> * **struct sk_buff** tc cls_act programs.
> * Return
> - * Egress device index on success, 0 if packet needs to continue
> - * up the stack for further processing or a negative error in case
> - * of failure.
> + * * < 0 if any input argument is invalid
> + * * 0 on success (packet is forwarded, nexthop neighbor exists)
> + * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
> + * * packet is not forwarded or needs assist from full stack
> *
> * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
> * Description
> @@ -2612,6 +2614,18 @@ struct bpf_raw_tracepoint_args {
> #define BPF_FIB_LOOKUP_DIRECT BIT(0)
> #define BPF_FIB_LOOKUP_OUTPUT BIT(1)
>
> +enum {
> + BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
> + BPF_FIB_LKUP_RET_BLACKHOLE, /* dest is blackholed; can be dropped */
> + BPF_FIB_LKUP_RET_UNREACHABLE, /* dest is unreachable; can be dropped */
> + BPF_FIB_LKUP_RET_PROHIBIT, /* dest not allowed; can be dropped */
> + BPF_FIB_LKUP_RET_NOT_FWDED, /* packet is not forwarded */
> + BPF_FIB_LKUP_RET_FWD_DISABLED, /* fwding is not enabled on ingress */
> + BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */
> + BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */
> + BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */
> +};
> +
> struct bpf_fib_lookup {
> /* input: network family for lookup (AF_INET, AF_INET6)
> * output: network family of egress nexthop
> @@ -2625,7 +2639,11 @@ struct bpf_fib_lookup {
>
> /* total length of packet from network header - used for MTU check */
> __u16 tot_len;
> - __u32 ifindex; /* L3 device index for lookup */
> +
> + /* input: L3 device index for lookup
> + * output: device index from FIB lookup
> + */
> + __u32 ifindex;
>
> union {
> /* inputs to lookup */
>
This has been updated in the bpf-next tree already, see commit
9b8ca3795199 ("tools: bpf: synchronise BPF UAPI header with tools").
Best regards,
Quentin
^ permalink raw reply
* [PATCH net-next] net: hix5hd2_gmac: use dma_zalloc_coherent instead of allocator/memset
From: YueHaibing @ 2018-07-19 13:57 UTC (permalink / raw)
To: yisen.zhuang, salil.mehta, davem; +Cc: linux-kernel, netdev, YueHaibing
Use dma_zalloc_coherent instead of dma_alloc_coherent
followed by memset 0.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
index 25a6c87..c572700 100644
--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
@@ -1006,12 +1006,11 @@ static int hix5hd2_init_hw_desc_queue(struct hix5hd2_priv *priv)
for (i = 0; i < QUEUE_NUMS; i++) {
size = priv->pool[i].count * sizeof(struct hix5hd2_desc);
- virt_addr = dma_alloc_coherent(dev, size, &phys_addr,
- GFP_KERNEL);
+ virt_addr = dma_zalloc_coherent(dev, size, &phys_addr,
+ GFP_KERNEL);
if (virt_addr == NULL)
goto error_free_pool;
- memset(virt_addr, 0, size);
priv->pool[i].size = size;
priv->pool[i].desc = virt_addr;
priv->pool[i].phys_addr = phys_addr;
--
2.7.0
^ permalink raw reply related
* Re: [PATCH V4 net-next 2/3] tcp: Add tcp_retransmit_stamp() helper routine
From: Eric Dumazet @ 2018-07-19 13:49 UTC (permalink / raw)
To: Jon Maxwell, davem
Cc: edumazet, ncardwell, David.Laight, kuznet, yoshfuji, netdev,
linux-kernel, jmaxwell
In-Reply-To: <20180719011444.4694-3-jmaxwell37@gmail.com>
On 07/18/2018 06:14 PM, Jon Maxwell wrote:
> Create a seperate helper routine as per Neal Cardwells suggestion. To
> be used by the final commit in this series and retransmits_timed_out().
>
> Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: linux-next: build warning after merge of the net-next tree
From: Guenter Roeck @ 2018-07-19 13:49 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, Networking, Linux-Next Mailing List,
Linux Kernel Mailing List, Masahiro Yamada, Andrew Lunn
In-Reply-To: <20180719152940.0720e9c1@canb.auug.org.au>
On 07/18/2018 10:29 PM, Stephen Rothwell wrote:
> Hi Guenter,
>
> On Wed, 18 Jul 2018 20:52:56 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>>
>> On 07/18/2018 07:04 PM, Stephen Rothwell wrote:
>>>
>>> After merging the net-next tree, today's linux-next build (x86_64
>>> allmodconfig) produced this warning:
>>>
>>> *
>>> * Restart config...
>>> *
>>> ....
>>>
>>> This is output by my "make allmodconfig" and only started after merging
>>> the net-next tree today. It has continued for further merges/builds.
>>>
>>> I suspect commit
>>>
>>> 1323061a018a ("net: phy: sfp: Add HWMON support for module sensors")
>>>
>>> which added an "imply" clause.
>>>
>> I thought "imply" was better than "depends on HWMON || HWMON=n", but maybe
>> not. Is that a caveat when using "imply", and does it mean that "imply"
>> should better not be used ?
>
> I don't know, sorry. It was just my best guess from what I could see
> had changed.
>
> I wonder if it makes a difference that I am doing my "make
> allmodconfig" on top of a previous "make allmodconfig" and some symbols
> are marked as "NEW" (though they are not symbols related to the changes
> that happened during the net-next tree merge)?
>
I tried to reproduce the problem, but I don't see the message.
What I do see, though, is that "make allmodconfig" on a clean tree,
followed by "make menuconfig", results in configuration changes.
Specifically,
> CONFIG_ARC_EMAC_CORE=m
> CONFIG_ARC_EMAC=m
> CONFIG_EMAC_ROCKCHIP=m
is removed by menuconfig, and a large number of "# ... is not set"
configuration lines are added. Weird and bad, since several of the
disabled configurations _should_ be enabled by "make allmodconfig",
and a large number of hwmon drivers are affected. Bisect does point
to "net: phy: sfp: Add HWMON support for module sensors", meaning
"imply hwmon" does have severe side effects and can not be used.
I'll try to find a fix.
Guenter
^ permalink raw reply
* [PATCH net-next 4/4] act_mirred: use ACT_MIRRED when possible
From: Paolo Abeni @ 2018-07-19 13:02 UTC (permalink / raw)
To: netdev
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, Daniel Borkmann,
Marcelo Ricardo Leitner, Eyal Birger
In-Reply-To: <cover.1531941678.git.pabeni@redhat.com>
When mirred is invoked from the ingress path, and it wants to redirect
the processed packet, it can now use the ACT_MIRRED action,
filling the tcf_result accordingly, and avoiding a per packet
skb_clone().
Overall this gives a ~10% improvement in forwarding performance for the
TC S/W data path and TC S/W performances are now comparable to the
kernel openswitch datapath.
v1 -> v2: use ACT_MIRRED instead of ACT_REDIRECT
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/sched/act_mirred.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index eeb335f03102..fa06c161f139 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -171,10 +171,12 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_mirred *m = to_mirred(a);
+ struct sk_buff *skb2 = skb;
bool m_mac_header_xmit;
struct net_device *dev;
- struct sk_buff *skb2;
int retval, err = 0;
+ bool want_ingress;
+ bool is_redirect;
int m_eaction;
int mac_len;
@@ -196,16 +198,19 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
goto out;
}
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (!skb2)
- goto out;
+ is_redirect = tcf_mirred_is_act_redirect(m_eaction);
+ if (!skb_at_tc_ingress(skb) || !is_redirect) {
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (!skb2)
+ goto out;
+ }
/* If action's target direction differs than filter's direction,
* and devices expect a mac header on xmit, then mac push/pull is
* needed.
*/
- if (skb_at_tc_ingress(skb) != tcf_mirred_act_wants_ingress(m_eaction) &&
- m_mac_header_xmit) {
+ want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
+ if (skb_at_tc_ingress(skb) != want_ingress && m_mac_header_xmit) {
if (!skb_at_tc_ingress(skb)) {
/* caught at egress, act ingress: pull mac */
mac_len = skb_network_header(skb) - skb_mac_header(skb);
@@ -216,14 +221,22 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
}
}
+ skb2->skb_iif = skb->dev->ifindex;
+ skb2->dev = dev;
+
/* mirror is always swallowed */
- if (tcf_mirred_is_act_redirect(m_eaction)) {
+ if (is_redirect) {
skb2->tc_redirected = 1;
skb2->tc_from_ingress = skb2->tc_at_ingress;
+
+ /* let's the caller reinject the packet, if possible */
+ if (skb_at_tc_ingress(skb)) {
+ res->ingress = want_ingress;
+ res->qstats = this_cpu_ptr(m->common.cpu_qstats);
+ return TC_ACT_MIRRED;
+ }
}
- skb2->skb_iif = skb->dev->ifindex;
- skb2->dev = dev;
if (!tcf_mirred_act_wants_ingress(m_eaction))
err = dev_queue_xmit(skb2);
else
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 3/4] net/tc: introduce TC_ACT_MIRRED.
From: Paolo Abeni @ 2018-07-19 13:02 UTC (permalink / raw)
To: netdev
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, Daniel Borkmann,
Marcelo Ricardo Leitner, Eyal Birger
In-Reply-To: <cover.1531941678.git.pabeni@redhat.com>
This is similar TC_ACT_REDIRECT, but with a slightly different
semantic:
- on ingress the mirred skbs are passed to the target device
network stack without any additional check not scrubbing.
- the rcu-protected stats provided via the tcf_result struct
are updated on error conditions.
v1 -> v2: do not touch TC_ACT_REDIRECT code path, introduce
a new action type instead
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
include/net/sch_generic.h | 19 +++++++++++++++++++
include/uapi/linux/pkt_cls.h | 3 ++-
net/core/dev.c | 4 ++++
net/sched/act_api.c | 6 ++++--
4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 056dc1083aa3..667d7b66fee2 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -235,6 +235,12 @@ struct tcf_result {
u32 classid;
};
const struct tcf_proto *goto_tp;
+
+ /* used by the TC_ACT_MIRRED action */
+ struct {
+ bool ingress;
+ struct gnet_stats_queue *qstats;
+ };
};
};
@@ -1091,4 +1097,17 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
struct mini_Qdisc __rcu **p_miniq);
+static inline void skb_tc_redirect(struct sk_buff *skb, struct tcf_result *res)
+{
+ struct gnet_stats_queue *stats = res->qstats;
+ int ret;
+
+ if (res->ingress)
+ ret = netif_receive_skb(skb);
+ else
+ ret = dev_queue_xmit(skb);
+ if (ret && stats)
+ qstats_overlimit_inc(res->qstats);
+}
+
#endif
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 7cdd62b51106..1a5e8a3217f3 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -45,7 +45,8 @@ enum {
* the skb and act like everything
* is alright.
*/
-#define TC_ACT_LAST TC_ACT_TRAP
+#define TC_ACT_MIRRED 9
+#define TC_ACT_LAST TC_ACT_MIRRED
/* There is a special kind of actions called "extended actions",
* which need a value parameter. These have a local opcode located in
diff --git a/net/core/dev.c b/net/core/dev.c
index 14a748ee8cc9..3822f29d730f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4602,6 +4602,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
__skb_push(skb, skb->mac_len);
skb_do_redirect(skb);
return NULL;
+ case TC_ACT_MIRRED:
+ /* this does not scrub the packet, and updates stats on error */
+ skb_tc_redirect(skb, &cl_res);
+ return NULL;
default:
break;
}
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index f6438f246dab..029302e2813e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -895,8 +895,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
}
}
- if (a->tcfa_action == TC_ACT_REDIRECT) {
- net_warn_ratelimited("TC_ACT_REDIRECT can't be used directly");
+ if (a->tcfa_action == TC_ACT_REDIRECT ||
+ a->tcfa_action == TC_ACT_MIRRED) {
+ net_warn_ratelimited("action %d can't be used directly",
+ a->tcfa_action);
a->tcfa_action = TC_ACT_LAST + 1;
}
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 2/4] tc/act: remove unneeded RCU lock in action callback
From: Paolo Abeni @ 2018-07-19 13:02 UTC (permalink / raw)
To: netdev
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, Daniel Borkmann,
Marcelo Ricardo Leitner, Eyal Birger
In-Reply-To: <cover.1531941678.git.pabeni@redhat.com>
Each lockless action currently does its own RCU locking in ->act().
This is allows using plain RCU accessor, even if the context
is really RCU BH.
This change drops the per action RCU lock, replace the accessors
with _bh variant, cleans up a bit the surronding code and documents
the RCU status in the relevant header.
No functional nor performance change is intended.
The goal of this patch is clarifying that the RCU critical section
used by the tc actions extends up to the classifier's caller.
v1 -> v2:
- preserve rcu lock in act_bpf: it's needed by eBPF helpers,
as pointed out by Daniel
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
include/net/act_api.h | 2 +-
include/net/sch_generic.h | 2 ++
net/sched/act_csum.c | 12 +++---------
net/sched/act_ife.c | 5 +----
net/sched/act_mirred.c | 4 +---
net/sched/act_sample.c | 4 +---
net/sched/act_skbedit.c | 10 +++-------
net/sched/act_skbmod.c | 21 +++++++++------------
net/sched/act_tunnel_key.c | 6 +-----
net/sched/act_vlan.c | 19 +++++++------------
10 files changed, 29 insertions(+), 56 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 683ce41053d9..8c9bc02d05e1 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -85,7 +85,7 @@ struct tc_action_ops {
size_t size;
struct module *owner;
int (*act)(struct sk_buff *, const struct tc_action *,
- struct tcf_result *);
+ struct tcf_result *); /* called under RCU BH lock*/
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void (*cleanup)(struct tc_action *);
int (*lookup)(struct net *net, struct tc_action **a, u32 index,
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 7432100027b7..056dc1083aa3 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -275,6 +275,8 @@ struct tcf_proto {
/* Fast access part */
struct tcf_proto __rcu *next;
void __rcu *root;
+
+ /* called under RCU BH lock*/
int (*classify)(struct sk_buff *,
const struct tcf_proto *,
struct tcf_result *);
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index bd232d3bd022..4f092fbd1e20 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -561,15 +561,14 @@ static int tcf_csum(struct sk_buff *skb, const struct tc_action *a,
u32 update_flags;
int action;
- rcu_read_lock();
- params = rcu_dereference(p->params);
+ params = rcu_dereference_bh(p->params);
tcf_lastuse_update(&p->tcf_tm);
bstats_cpu_update(this_cpu_ptr(p->common.cpu_bstats), skb);
action = params->action;
if (unlikely(action == TC_ACT_SHOT))
- goto drop_stats;
+ goto drop;
update_flags = params->update_flags;
switch (tc_skb_protocol(skb)) {
@@ -583,16 +582,11 @@ static int tcf_csum(struct sk_buff *skb, const struct tc_action *a,
break;
}
-unlock:
- rcu_read_unlock();
return action;
drop:
- action = TC_ACT_SHOT;
-
-drop_stats:
qstats_drop_inc(this_cpu_ptr(p->common.cpu_qstats));
- goto unlock;
+ return TC_ACT_SHOT;
}
static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 3d6e265758c0..df4060e32d43 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -820,14 +820,11 @@ static int tcf_ife_act(struct sk_buff *skb, const struct tc_action *a,
struct tcf_ife_params *p;
int ret;
- rcu_read_lock();
- p = rcu_dereference(ife->params);
+ p = rcu_dereference_bh(ife->params);
if (p->flags & IFE_ENCODE) {
ret = tcf_ife_encode(skb, a, res, p);
- rcu_read_unlock();
return ret;
}
- rcu_read_unlock();
return tcf_ife_decode(skb, a, res);
}
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 6afd89a36c69..eeb335f03102 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -181,11 +181,10 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
tcf_lastuse_update(&m->tcf_tm);
bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb);
- rcu_read_lock();
m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
m_eaction = READ_ONCE(m->tcfm_eaction);
retval = READ_ONCE(m->tcf_action);
- dev = rcu_dereference(m->tcfm_dev);
+ dev = rcu_dereference_bh(m->tcfm_dev);
if (unlikely(!dev)) {
pr_notice_once("tc mirred: target device is gone\n");
goto out;
@@ -236,7 +235,6 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
if (tcf_mirred_is_act_redirect(m_eaction))
retval = TC_ACT_SHOT;
}
- rcu_read_unlock();
return retval;
}
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
index 3079e7be5bde..2608ccc83e5e 100644
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@ -140,8 +140,7 @@ static int tcf_sample_act(struct sk_buff *skb, const struct tc_action *a,
bstats_cpu_update(this_cpu_ptr(s->common.cpu_bstats), skb);
retval = READ_ONCE(s->tcf_action);
- rcu_read_lock();
- psample_group = rcu_dereference(s->psample_group);
+ psample_group = rcu_dereference_bh(s->psample_group);
/* randomly sample packets according to rate */
if (psample_group && (prandom_u32() % s->rate == 0)) {
@@ -165,7 +164,6 @@ static int tcf_sample_act(struct sk_buff *skb, const struct tc_action *a,
skb_pull(skb, skb->mac_len);
}
- rcu_read_unlock();
return retval;
}
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index da56e6938c9e..a6db47ebec11 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -43,8 +43,7 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a,
tcf_lastuse_update(&d->tcf_tm);
bstats_cpu_update(this_cpu_ptr(d->common.cpu_bstats), skb);
- rcu_read_lock();
- params = rcu_dereference(d->params);
+ params = rcu_dereference_bh(d->params);
action = READ_ONCE(d->tcf_action);
if (params->flags & SKBEDIT_F_PRIORITY)
@@ -77,14 +76,11 @@ static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a,
}
if (params->flags & SKBEDIT_F_PTYPE)
skb->pkt_type = params->ptype;
-
-unlock:
- rcu_read_unlock();
return action;
+
err:
qstats_drop_inc(this_cpu_ptr(d->common.cpu_qstats));
- action = TC_ACT_SHOT;
- goto unlock;
+ return TC_ACT_SHOT;
}
static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
index cdc6bacfb190..c437c6d51a71 100644
--- a/net/sched/act_skbmod.c
+++ b/net/sched/act_skbmod.c
@@ -41,20 +41,14 @@ static int tcf_skbmod_run(struct sk_buff *skb, const struct tc_action *a,
* then MAX_EDIT_LEN needs to change appropriately
*/
err = skb_ensure_writable(skb, MAX_EDIT_LEN);
- if (unlikely(err)) { /* best policy is to drop on the floor */
- qstats_overlimit_inc(this_cpu_ptr(d->common.cpu_qstats));
- return TC_ACT_SHOT;
- }
+ if (unlikely(err)) /* best policy is to drop on the floor */
+ goto drop;
- rcu_read_lock();
action = READ_ONCE(d->tcf_action);
- if (unlikely(action == TC_ACT_SHOT)) {
- qstats_overlimit_inc(this_cpu_ptr(d->common.cpu_qstats));
- rcu_read_unlock();
- return action;
- }
+ if (unlikely(action == TC_ACT_SHOT))
+ goto drop;
- p = rcu_dereference(d->skbmod_p);
+ p = rcu_dereference_bh(d->skbmod_p);
flags = p->flags;
if (flags & SKBMOD_F_DMAC)
ether_addr_copy(eth_hdr(skb)->h_dest, p->eth_dst);
@@ -62,7 +56,6 @@ static int tcf_skbmod_run(struct sk_buff *skb, const struct tc_action *a,
ether_addr_copy(eth_hdr(skb)->h_source, p->eth_src);
if (flags & SKBMOD_F_ETYPE)
eth_hdr(skb)->h_proto = p->eth_type;
- rcu_read_unlock();
if (flags & SKBMOD_F_SWAPMAC) {
u16 tmpaddr[ETH_ALEN / 2]; /* ether_addr_copy() requirement */
@@ -73,6 +66,10 @@ static int tcf_skbmod_run(struct sk_buff *skb, const struct tc_action *a,
}
return action;
+
+drop:
+ qstats_overlimit_inc(this_cpu_ptr(d->common.cpu_qstats));
+ return TC_ACT_SHOT;
}
static const struct nla_policy skbmod_policy[TCA_SKBMOD_MAX + 1] = {
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 3ec585d58762..1ab959ef3547 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -31,9 +31,7 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
struct tcf_tunnel_key_params *params;
int action;
- rcu_read_lock();
-
- params = rcu_dereference(t->params);
+ params = rcu_dereference_bh(t->params);
tcf_lastuse_update(&t->tcf_tm);
bstats_cpu_update(this_cpu_ptr(t->common.cpu_bstats), skb);
@@ -53,8 +51,6 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
break;
}
- rcu_read_unlock();
-
return action;
}
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index ad37f308175a..15a0ee214c9c 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -40,11 +40,9 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
if (skb_at_tc_ingress(skb))
skb_push_rcsum(skb, skb->mac_len);
- rcu_read_lock();
-
action = READ_ONCE(v->tcf_action);
- p = rcu_dereference(v->vlan_p);
+ p = rcu_dereference_bh(v->vlan_p);
switch (p->tcfv_action) {
case TCA_VLAN_ACT_POP:
@@ -61,7 +59,7 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
case TCA_VLAN_ACT_MODIFY:
/* No-op if no vlan tag (either hw-accel or in-payload) */
if (!skb_vlan_tagged(skb))
- goto unlock;
+ goto out;
/* extract existing tag (and guarantee no hw-accel tag) */
if (skb_vlan_tag_present(skb)) {
tci = skb_vlan_tag_get(skb);
@@ -86,18 +84,15 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
BUG();
}
- goto unlock;
-
-drop:
- action = TC_ACT_SHOT;
- qstats_drop_inc(this_cpu_ptr(v->common.cpu_qstats));
-
-unlock:
- rcu_read_unlock();
+out:
if (skb_at_tc_ingress(skb))
skb_pull_rcsum(skb, skb->mac_len);
return action;
+
+drop:
+ qstats_drop_inc(this_cpu_ptr(v->common.cpu_qstats));
+ return TC_ACT_SHOT;
}
static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 1/4] tc/act: user space can't use TC_ACT_REDIRECT directly
From: Paolo Abeni @ 2018-07-19 13:02 UTC (permalink / raw)
To: netdev
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, Daniel Borkmann,
Marcelo Ricardo Leitner, Eyal Birger
In-Reply-To: <cover.1531941678.git.pabeni@redhat.com>
Only cls_bpf and act_bpf can safely use such value. If a generic
action is configured by user space to return TC_ACT_REDIRECT,
the usually visible behavior is passing the skb up the stack - as
for unknown action, but, with complex configuration, more random
results can be obtained.
This patch forcefully converts TC_ACT_REDIRECT to TC_ACT_LAST + 1
at action init time, making the kernel behavior more consistent.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
include/uapi/linux/pkt_cls.h | 1 +
net/sched/act_api.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index c4262d911596..7cdd62b51106 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -45,6 +45,7 @@ enum {
* the skb and act like everything
* is alright.
*/
+#define TC_ACT_LAST TC_ACT_TRAP
/* There is a special kind of actions called "extended actions",
* which need a value parameter. These have a local opcode located in
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 148a89ab789b..f6438f246dab 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -895,6 +895,11 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
}
}
+ if (a->tcfa_action == TC_ACT_REDIRECT) {
+ net_warn_ratelimited("TC_ACT_REDIRECT can't be used directly");
+ a->tcfa_action = TC_ACT_LAST + 1;
+ }
+
return a;
err_mod:
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 0/4] TC: refactor act_mirred packets re-injection
From: Paolo Abeni @ 2018-07-19 13:02 UTC (permalink / raw)
To: netdev
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, Daniel Borkmann,
Marcelo Ricardo Leitner, Eyal Birger
This series is aimed at improving the act_mirred redirect performances.
Such action is used by OVS to represent TC S/W flows, and it's current largest
bottle-neck is the need for a skb_clone() for each packet.
The first 2 patches introduce some cleanup and safeguards to allow extending
tca_result: we will use it to store RCU protected redirect information.
Then a new tca_action value is introduced: TC_ACT_MIRRED, similar to
TC_ACT_REDIRECT, but preserving the mirred semantic. The last patch exploits
the introduced infrastructure in the act_mirred action, to avoid a skb_clone,
when possible.
Overall this the above gives a ~10% performance improvement in forwarding tput,
when using the TC S/W datapath.
v1 -> v2:
- preserve the rcu lock in act_bpf
- add and use a new action value to reinject the packets, preserving the mirred
semantic
Paolo Abeni (4):
tc/act: user space can't use TC_ACT_REDIRECT directly
tc/act: remove unneeded RCU lock in action callback
net/tc: introduce TC_ACT_MIRRED.
act_mirred: use ACT_MIRRED when possible
include/net/act_api.h | 2 +-
include/net/sch_generic.h | 21 +++++++++++++++++++++
include/uapi/linux/pkt_cls.h | 2 ++
net/core/dev.c | 4 ++++
net/sched/act_api.c | 7 +++++++
net/sched/act_csum.c | 12 +++---------
net/sched/act_ife.c | 5 +----
net/sched/act_mirred.c | 35 +++++++++++++++++++++++------------
net/sched/act_sample.c | 4 +---
net/sched/act_skbedit.c | 10 +++-------
net/sched/act_skbmod.c | 21 +++++++++------------
net/sched/act_tunnel_key.c | 6 +-----
net/sched/act_vlan.c | 19 +++++++------------
13 files changed, 83 insertions(+), 65 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH V4 net-next 1/3] tcp: convert icsk_user_timeout from jiffies to msecs
From: Eric Dumazet @ 2018-07-19 13:33 UTC (permalink / raw)
To: Jon Maxwell, davem
Cc: edumazet, ncardwell, David.Laight, kuznet, yoshfuji, netdev,
linux-kernel, jmaxwell
In-Reply-To: <20180719011444.4694-2-jmaxwell37@gmail.com>
On 07/18/2018 06:14 PM, Jon Maxwell wrote:
> This is a preparatory commit. Part of this series that improves the
> socket TCP_USER_TIMEOUT option accuracy. Implement Eric Dumazets idea
> to convert icsk->icsk_user_timeout from jiffies to msecs. To eliminate
> the msecs_to_jiffies() and jiffies_to_msecs() dance in future.
>
> Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* [PATCH] netfilter: use PTR_ERR_OR_ZERO()
From: YueHaibing @ 2018-07-19 13:20 UTC (permalink / raw)
To: pablo, kadlec, fw
Cc: linux-kernel, netdev, davem, netfilter-devel, coreteam,
YueHaibing
Fix ptr_ret.cocci warnings:
net/netfilter/xt_connlimit.c:96:1-3: WARNING: PTR_ERR_OR_ZERO can be used
net/netfilter/nft_numgen.c:240:1-3: WARNING: PTR_ERR_OR_ZERO can be used
Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
Generated by: scripts/coccinelle/api/ptr_ret.cocci
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
net/netfilter/nft_numgen.c | 4 +---
net/netfilter/xt_connlimit.c | 4 +---
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index 1f4d085..649d170 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -237,10 +237,8 @@ static int nft_ng_random_map_init(const struct nft_ctx *ctx,
priv->map = nft_set_lookup_global(ctx->net, ctx->table,
tb[NFTA_NG_SET_NAME],
tb[NFTA_NG_SET_ID], genmask);
- if (IS_ERR(priv->map))
- return PTR_ERR(priv->map);
- return 0;
+ return PTR_ERR_OR_ZERO(priv->map);
}
static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 6275106..bc6c8ab 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -93,10 +93,8 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
/* init private data */
info->data = nf_conncount_init(par->net, par->family, keylen);
- if (IS_ERR(info->data))
- return PTR_ERR(info->data);
- return 0;
+ return PTR_ERR_OR_ZERO(info->data);
}
static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
--
2.7.0
^ permalink raw reply related
* Re: [PATCH] net: phy: use generic clause 45 autonegotiation done
From: Russell King - ARM Linux @ 2018-07-19 12:56 UTC (permalink / raw)
To: Camelia Alexandra Groza
Cc: Andrew Lunn, f.fainelli@gmail.com, davem@davemloft.net,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <VI1PR04MB4799F126865F4A5C115D1B16F2520@VI1PR04MB4799.eurprd04.prod.outlook.com>
On Thu, Jul 19, 2018 at 12:47:18PM +0000, Camelia Alexandra Groza wrote:
> > -----Original Message-----
> > From: Andrew Lunn [mailto:andrew@lunn.ch]
> > Sent: Wednesday, July 18, 2018 17:39
> > To: Camelia Alexandra Groza <camelia.groza@nxp.com>
> > Cc: f.fainelli@gmail.com; davem@davemloft.net; netdev@vger.kernel.org;
> > linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH] net: phy: use generic clause 45 autonegotiation done
> >
> > On Wed, Jul 18, 2018 at 04:12:15PM +0300, Camelia Groza wrote:
> > > Only Clause 22 PHYs can use genphy_aneg_done(). Use
> > > genphy_c45_aneg_done() for PHYs that implement Clause 45 without the
> > > Clause 22 register set.
> > >
> > > This change follows the model of phy_restart_aneg() which
> > > differentiates between the two implementations in a similar way.
> >
> > Hi Camelia
> >
> > What about phy_config_aneg()? I would assume any sort of auto-neg action
> > needs to check for c45 without c22, before calling a genphy_ function. Do you
> > think it is possible to write a genphy_c45_config_aneg()? If not, we might
> > want to return -EOPNOTSUPP.
>
> Hi Andrew,
>
> Adding Russell to the thread as well, since he wrote the c45 helpers.
>
> Sure, I'll send a v2 with an additional generic phy_config_aneg(). I'll
> stick to returning -EOPNOTSUPP for c22-less PHYs for now.
Be aware that there are no generic registers for configuring (eg) 1G
speeds in C45 phys - that is vendor specific.
It may be that the expectation in the 802.3 specs is that such PHYs
implement the C22 register set in devad 0, but I've no visibility of
that (and the 10G PHYs that phylib does have, apart from marvell10g,
are particularly poor in the features they implement.)
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up
According to speedtest.net: 13Mbps down 490kbps up
^ permalink raw reply
* [PATCH] bpf: synchronize bpf uapi header with tools
From: Taeung Song @ 2018-07-19 12:53 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: netdev, linux-kernel, Arnaldo Carvalho de Melo, David Ahern
To pick the change in:
4c79579b44b1 ("bpf: Change bpf_fib_lookup to return lookup status")
This bpftool build warning occurs:
Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/include/uapi/linux/bpf.h | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 59b19b6a40d7..b7db3261c62d 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1857,7 +1857,8 @@ union bpf_attr {
* is resolved), the nexthop address is returned in ipv4_dst
* or ipv6_dst based on family, smac is set to mac address of
* egress device, dmac is set to nexthop mac address, rt_metric
- * is set to metric from route (IPv4/IPv6 only).
+ * is set to metric from route (IPv4/IPv6 only), and ifindex
+ * is set to the device index of the nexthop from the FIB lookup.
*
* *plen* argument is the size of the passed in struct.
* *flags* argument can be a combination of one or more of the
@@ -1873,9 +1874,10 @@ union bpf_attr {
* *ctx* is either **struct xdp_md** for XDP programs or
* **struct sk_buff** tc cls_act programs.
* Return
- * Egress device index on success, 0 if packet needs to continue
- * up the stack for further processing or a negative error in case
- * of failure.
+ * * < 0 if any input argument is invalid
+ * * 0 on success (packet is forwarded, nexthop neighbor exists)
+ * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
+ * * packet is not forwarded or needs assist from full stack
*
* int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
* Description
@@ -2612,6 +2614,18 @@ struct bpf_raw_tracepoint_args {
#define BPF_FIB_LOOKUP_DIRECT BIT(0)
#define BPF_FIB_LOOKUP_OUTPUT BIT(1)
+enum {
+ BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
+ BPF_FIB_LKUP_RET_BLACKHOLE, /* dest is blackholed; can be dropped */
+ BPF_FIB_LKUP_RET_UNREACHABLE, /* dest is unreachable; can be dropped */
+ BPF_FIB_LKUP_RET_PROHIBIT, /* dest not allowed; can be dropped */
+ BPF_FIB_LKUP_RET_NOT_FWDED, /* packet is not forwarded */
+ BPF_FIB_LKUP_RET_FWD_DISABLED, /* fwding is not enabled on ingress */
+ BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */
+ BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */
+ BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */
+};
+
struct bpf_fib_lookup {
/* input: network family for lookup (AF_INET, AF_INET6)
* output: network family of egress nexthop
@@ -2625,7 +2639,11 @@ struct bpf_fib_lookup {
/* total length of packet from network header - used for MTU check */
__u16 tot_len;
- __u32 ifindex; /* L3 device index for lookup */
+
+ /* input: L3 device index for lookup
+ * output: device index from FIB lookup
+ */
+ __u32 ifindex;
union {
/* inputs to lookup */
--
2.17.1
^ permalink raw reply related
* RE: [PATCH] net: phy: use generic clause 45 autonegotiation done
From: Camelia Alexandra Groza @ 2018-07-19 12:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: rmk+kernel@armlinux.org.uk, f.fainelli@gmail.com,
davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20180718143919.GA10856@lunn.ch>
> -----Original Message-----
> From: Andrew Lunn [mailto:andrew@lunn.ch]
> Sent: Wednesday, July 18, 2018 17:39
> To: Camelia Alexandra Groza <camelia.groza@nxp.com>
> Cc: f.fainelli@gmail.com; davem@davemloft.net; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] net: phy: use generic clause 45 autonegotiation done
>
> On Wed, Jul 18, 2018 at 04:12:15PM +0300, Camelia Groza wrote:
> > Only Clause 22 PHYs can use genphy_aneg_done(). Use
> > genphy_c45_aneg_done() for PHYs that implement Clause 45 without the
> > Clause 22 register set.
> >
> > This change follows the model of phy_restart_aneg() which
> > differentiates between the two implementations in a similar way.
>
> Hi Camelia
>
> What about phy_config_aneg()? I would assume any sort of auto-neg action
> needs to check for c45 without c22, before calling a genphy_ function. Do you
> think it is possible to write a genphy_c45_config_aneg()? If not, we might
> want to return -EOPNOTSUPP.
Hi Andrew,
Adding Russell to the thread as well, since he wrote the c45 helpers.
Sure, I'll send a v2 with an additional generic phy_config_aneg(). I'll stick to returning -EOPNOTSUPP for c22-less PHYs for now.
Thanks,
Camelia
^ permalink raw reply
* Re: [PATCH v2 2/3] net: add support for nvmem to eth_platform_get_mac_address()
From: Dan Carpenter @ 2018-07-19 12:37 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Rob Herring, Grygorii Strashko, David Lechner, Ivan Khoronzhuk,
Kevin Hilman, Greg Kroah-Hartman, Sekhar Nori, Russell King, LKML,
Andrew Lunn, Bartosz Golaszewski, Lukas Wunner,
Srinivas Kandagatla, netdev, Florian Fainelli, Linux-OMAP,
David S . Miller, arm-soc
In-Reply-To: <CAMRc=Mdu5CLA99p48nNFZBSFHBKiERzp-m59vKDDe5STjjKZNA@mail.gmail.com>
On Thu, Jul 19, 2018 at 12:06:51PM +0200, Bartosz Golaszewski wrote:
> It looks simpler as long as you don't add all the new routines
> resulting from this approach. I've just tried to quickly implement
> this solution and it resulted in much bigger and duplicated code
> (checking the validity of mac_addr, copying it etc.). I would prefer
> the current approach and would like to read someone else's opinion on
> that.
It's not too bad. There is two extra ether_addr_copy() calls and one
extra is_valid_ether_addr(). There are two extra alen declarations and
one extra addr declaration. The functions don't share *that* much code.
regards,
dan carpenter
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index fd8faa0dfa61..8ab7289a5069 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -54,6 +54,8 @@
#include <linux/if_ether.h>
#include <linux/of_net.h>
#include <linux/pci.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
#include <net/dst.h>
#include <net/arp.h>
#include <net/sock.h>
@@ -525,7 +527,7 @@ unsigned char * __weak arch_get_platform_mac_address(void)
return NULL;
}
-int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+static int of_eth_get_mac_address(struct device *dev, u8 *mac_addr)
{
const unsigned char *addr;
struct device_node *dp;
@@ -547,4 +549,82 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
ether_addr_copy(mac_addr, addr);
return 0;
}
+
+static int nvmem_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct nvmem_cell *nvmem;
+ unsigned char *addr;
+ size_t alen;
+ int ret = 0;
+
+ nvmem = nvmem_cell_get(dev, "mac-address");
+ if (PTR_ERR(nvmem) == -EPROBE_DEFER)
+ /* We may have a lookup registered for MAC address but the
+ * corresponding nvmem provider hasn't been registered yet.
+ */
+ return -EPROBE_DEFER;
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+ addr = nvmem_cell_read(nvmem, &alen);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto put_nvmem;
+ }
+ if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
+ ret = -EINVAL;
+ goto free_addr;
+ }
+ ether_addr_copy(mac_addr, addr);
+free_addr:
+ kfree(addr);
+put_nvmem:
+ nvmem_cell_put(nvmem);
+ return ret;
+}
+
+static int mtd_eth_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ struct mtd_info *mtd;
+ u8 addrbuf[ETH_ALEN];
+ size_t alen;
+ int ret;
+
+ /* This function should go away as soon as MTD gets nvmem support. */
+ if (!IS_ENABLED(CONFIG_MTD))
+ return -ENODEV;
+
+ mtd = get_mtd_device_nm("MAC-Address");
+ if (IS_ERR(mtd))
+ return PTR_ERR(mtd);
+ ret = mtd_read(mtd, 0, ETH_ALEN, &alen, addrbuf);
+ if (ret)
+ goto put_mtd;
+ if (!is_valid_ether_addr(addrbuf)) {
+ ret = -EINVAL;
+ goto put_mtd;
+ }
+ ether_addr_copy(mac_addr, addrbuf);
+put_mtd:
+ put_mtd_device(mtd);
+ return ret;
+}
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+ int ret;
+
+ ret = of_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+ ret = nvmem_eth_get_mac_address(dev, mac_addr);
+ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (!ret)
+ return 0;
+ ret = mtd_eth_get_mac_address(dev, mac_addr);
+ if (!ret)
+ return 0;
+
+ return -ENODEV;
+}
EXPORT_SYMBOL(eth_platform_get_mac_address);
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox