190-add-cake-to-tc.patch 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662
  1. --- a/include/uapi/linux/pkt_sched.h
  2. +++ b/include/uapi/linux/pkt_sched.h
  3. @@ -934,4 +934,118 @@ enum {
  4. #define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
  5. +/* CAKE */
  6. +enum {
  7. + TCA_CAKE_UNSPEC,
  8. + TCA_CAKE_PAD,
  9. + TCA_CAKE_BASE_RATE64,
  10. + TCA_CAKE_DIFFSERV_MODE,
  11. + TCA_CAKE_ATM,
  12. + TCA_CAKE_FLOW_MODE,
  13. + TCA_CAKE_OVERHEAD,
  14. + TCA_CAKE_RTT,
  15. + TCA_CAKE_TARGET,
  16. + TCA_CAKE_AUTORATE,
  17. + TCA_CAKE_MEMORY,
  18. + TCA_CAKE_NAT,
  19. + TCA_CAKE_RAW, // was _ETHERNET
  20. + TCA_CAKE_WASH,
  21. + TCA_CAKE_MPU,
  22. + TCA_CAKE_INGRESS,
  23. + TCA_CAKE_ACK_FILTER,
  24. + TCA_CAKE_SPLIT_GSO,
  25. + __TCA_CAKE_MAX
  26. +};
  27. +#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1)
  28. +
  29. +enum {
  30. + __TCA_CAKE_STATS_INVALID,
  31. + TCA_CAKE_STATS_PAD,
  32. + TCA_CAKE_STATS_CAPACITY_ESTIMATE64,
  33. + TCA_CAKE_STATS_MEMORY_LIMIT,
  34. + TCA_CAKE_STATS_MEMORY_USED,
  35. + TCA_CAKE_STATS_AVG_NETOFF,
  36. + TCA_CAKE_STATS_MIN_NETLEN,
  37. + TCA_CAKE_STATS_MAX_NETLEN,
  38. + TCA_CAKE_STATS_MIN_ADJLEN,
  39. + TCA_CAKE_STATS_MAX_ADJLEN,
  40. + TCA_CAKE_STATS_TIN_STATS,
  41. + TCA_CAKE_STATS_DEFICIT,
  42. + TCA_CAKE_STATS_COBALT_COUNT,
  43. + TCA_CAKE_STATS_DROPPING,
  44. + TCA_CAKE_STATS_DROP_NEXT_US,
  45. + TCA_CAKE_STATS_P_DROP,
  46. + TCA_CAKE_STATS_BLUE_TIMER_US,
  47. + __TCA_CAKE_STATS_MAX
  48. +};
  49. +#define TCA_CAKE_STATS_MAX (__TCA_CAKE_STATS_MAX - 1)
  50. +
  51. +enum {
  52. + __TCA_CAKE_TIN_STATS_INVALID,
  53. + TCA_CAKE_TIN_STATS_PAD,
  54. + TCA_CAKE_TIN_STATS_SENT_PACKETS,
  55. + TCA_CAKE_TIN_STATS_SENT_BYTES64,
  56. + TCA_CAKE_TIN_STATS_DROPPED_PACKETS,
  57. + TCA_CAKE_TIN_STATS_DROPPED_BYTES64,
  58. + TCA_CAKE_TIN_STATS_ACKS_DROPPED_PACKETS,
  59. + TCA_CAKE_TIN_STATS_ACKS_DROPPED_BYTES64,
  60. + TCA_CAKE_TIN_STATS_ECN_MARKED_PACKETS,
  61. + TCA_CAKE_TIN_STATS_ECN_MARKED_BYTES64,
  62. + TCA_CAKE_TIN_STATS_BACKLOG_PACKETS,
  63. + TCA_CAKE_TIN_STATS_BACKLOG_BYTES,
  64. + TCA_CAKE_TIN_STATS_THRESHOLD_RATE64,
  65. + TCA_CAKE_TIN_STATS_TARGET_US,
  66. + TCA_CAKE_TIN_STATS_INTERVAL_US,
  67. + TCA_CAKE_TIN_STATS_WAY_INDIRECT_HITS,
  68. + TCA_CAKE_TIN_STATS_WAY_MISSES,
  69. + TCA_CAKE_TIN_STATS_WAY_COLLISIONS,
  70. + TCA_CAKE_TIN_STATS_PEAK_DELAY_US,
  71. + TCA_CAKE_TIN_STATS_AVG_DELAY_US,
  72. + TCA_CAKE_TIN_STATS_BASE_DELAY_US,
  73. + TCA_CAKE_TIN_STATS_SPARSE_FLOWS,
  74. + TCA_CAKE_TIN_STATS_BULK_FLOWS,
  75. + TCA_CAKE_TIN_STATS_UNRESPONSIVE_FLOWS,
  76. + TCA_CAKE_TIN_STATS_MAX_SKBLEN,
  77. + TCA_CAKE_TIN_STATS_FLOW_QUANTUM,
  78. + __TCA_CAKE_TIN_STATS_MAX
  79. +};
  80. +#define TCA_CAKE_TIN_STATS_MAX (__TCA_CAKE_TIN_STATS_MAX - 1)
  81. +#define TC_CAKE_MAX_TINS (8)
  82. +
  83. +enum {
  84. + CAKE_FLOW_NONE = 0,
  85. + CAKE_FLOW_SRC_IP,
  86. + CAKE_FLOW_DST_IP,
  87. + CAKE_FLOW_HOSTS, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_DST_IP */
  88. + CAKE_FLOW_FLOWS,
  89. + CAKE_FLOW_DUAL_SRC, /* = CAKE_FLOW_SRC_IP | CAKE_FLOW_FLOWS */
  90. + CAKE_FLOW_DUAL_DST, /* = CAKE_FLOW_DST_IP | CAKE_FLOW_FLOWS */
  91. + CAKE_FLOW_TRIPLE, /* = CAKE_FLOW_HOSTS | CAKE_FLOW_FLOWS */
  92. + CAKE_FLOW_MAX,
  93. +};
  94. +
  95. +enum {
  96. + CAKE_DIFFSERV_DIFFSERV3 = 0,
  97. + CAKE_DIFFSERV_DIFFSERV4,
  98. + CAKE_DIFFSERV_DIFFSERV8,
  99. + CAKE_DIFFSERV_BESTEFFORT,
  100. + CAKE_DIFFSERV_PRECEDENCE,
  101. + CAKE_DIFFSERV_MAX
  102. +};
  103. +
  104. +enum {
  105. + CAKE_ACK_NONE = 0,
  106. + CAKE_ACK_FILTER,
  107. + CAKE_ACK_AGGRESSIVE,
  108. + CAKE_ACK_MAX
  109. +};
  110. +
  111. +enum {
  112. + CAKE_ATM_NONE = 0,
  113. + CAKE_ATM_ATM,
  114. + CAKE_ATM_PTM,
  115. + CAKE_ATM_MAX
  116. +};
  117. +
  118. +
  119. #endif
  120. --- /dev/null
  121. +++ b/man/man8/tc-cake.8
  122. @@ -0,0 +1,710 @@
  123. +.TH CAKE 8 "19 July 2018" "iproute2" "Linux"
  124. +.SH NAME
  125. +CAKE \- Common Applications Kept Enhanced (CAKE)
  126. +.SH SYNOPSIS
  127. +.B tc qdisc ... cake
  128. +.br
  129. +[
  130. +.BR bandwidth
  131. +RATE |
  132. +.BR unlimited*
  133. +|
  134. +.BR autorate-ingress
  135. +]
  136. +.br
  137. +[
  138. +.BR rtt
  139. +TIME |
  140. +.BR datacentre
  141. +|
  142. +.BR lan
  143. +|
  144. +.BR metro
  145. +|
  146. +.BR regional
  147. +|
  148. +.BR internet*
  149. +|
  150. +.BR oceanic
  151. +|
  152. +.BR satellite
  153. +|
  154. +.BR interplanetary
  155. +]
  156. +.br
  157. +[
  158. +.BR besteffort
  159. +|
  160. +.BR diffserv8
  161. +|
  162. +.BR diffserv4
  163. +|
  164. +.BR diffserv3*
  165. +]
  166. +.br
  167. +[
  168. +.BR flowblind
  169. +|
  170. +.BR srchost
  171. +|
  172. +.BR dsthost
  173. +|
  174. +.BR hosts
  175. +|
  176. +.BR flows
  177. +|
  178. +.BR dual-srchost
  179. +|
  180. +.BR dual-dsthost
  181. +|
  182. +.BR triple-isolate*
  183. +]
  184. +.br
  185. +[
  186. +.BR nat
  187. +|
  188. +.BR nonat*
  189. +]
  190. +.br
  191. +[
  192. +.BR wash
  193. +|
  194. +.BR nowash*
  195. +]
  196. +.br
  197. +[
  198. +.BR split-gso*
  199. +|
  200. +.BR no-split-gso
  201. +]
  202. +.br
  203. +[
  204. +.BR ack-filter
  205. +|
  206. +.BR ack-filter-aggressive
  207. +|
  208. +.BR no-ack-filter*
  209. +]
  210. +.br
  211. +[
  212. +.BR memlimit
  213. +LIMIT ]
  214. +.br
  215. +[
  216. +.BR ptm
  217. +|
  218. +.BR atm
  219. +|
  220. +.BR noatm*
  221. +]
  222. +.br
  223. +[
  224. +.BR overhead
  225. +N |
  226. +.BR conservative
  227. +|
  228. +.BR raw*
  229. +]
  230. +.br
  231. +[
  232. +.BR mpu
  233. +N ]
  234. +.br
  235. +[
  236. +.BR ingress
  237. +|
  238. +.BR egress*
  239. +]
  240. +.br
  241. +(* marks defaults)
  242. +
  243. +
  244. +.SH DESCRIPTION
  245. +CAKE (Common Applications Kept Enhanced) is a shaping-capable queue discipline
  246. +which uses both AQM and FQ. It combines COBALT, which is an AQM algorithm
  247. +combining Codel and BLUE, a shaper which operates in deficit mode, and a variant
  248. +of DRR++ for flow isolation. 8-way set-associative hashing is used to virtually
  249. +eliminate hash collisions. Priority queuing is available through a simplified
  250. +diffserv implementation. Overhead compensation for various encapsulation
  251. +schemes is tightly integrated.
  252. +
  253. +All settings are optional; the default settings are chosen to be sensible in
  254. +most common deployments. Most people will only need to set the
  255. +.B bandwidth
  256. +parameter to get useful results, but reading the
  257. +.B Overhead Compensation
  258. +and
  259. +.B Round Trip Time
  260. +sections is strongly encouraged.
  261. +
  262. +.SH SHAPER PARAMETERS
  263. +CAKE uses a deficit-mode shaper, which does not exhibit the initial burst
  264. +typical of token-bucket shapers. It will automatically burst precisely as much
  265. +as required to maintain the configured throughput. As such, it is very
  266. +straightforward to configure.
  267. +.PP
  268. +.B unlimited
  269. +(default)
  270. +.br
  271. + No limit on the bandwidth.
  272. +.PP
  273. +.B bandwidth
  274. +RATE
  275. +.br
  276. + Set the shaper bandwidth. See
  277. +.BR tc(8)
  278. +or examples below for details of the RATE value.
  279. +.PP
  280. +.B autorate-ingress
  281. +.br
  282. + Automatic capacity estimation based on traffic arriving at this qdisc.
  283. +This is most likely to be useful with cellular links, which tend to change
  284. +quality randomly. A
  285. +.B bandwidth
  286. +parameter can be used in conjunction to specify an initial estimate. The shaper
  287. +will periodically be set to a bandwidth slightly below the estimated rate. This
  288. +estimator cannot estimate the bandwidth of links downstream of itself.
  289. +
  290. +.SH OVERHEAD COMPENSATION PARAMETERS
  291. +The size of each packet on the wire may differ from that seen by Linux. The
  292. +following parameters allow CAKE to compensate for this difference by internally
  293. +considering each packet to be bigger than Linux informs it. To assist users who
  294. +are not expert network engineers, keywords have been provided to represent a
  295. +number of common link technologies.
  296. +
  297. +.SS Manual Overhead Specification
  298. +.B overhead
  299. +BYTES
  300. +.br
  301. + Adds BYTES to the size of each packet. BYTES may be negative; values
  302. +between -64 and 256 (inclusive) are accepted.
  303. +.PP
  304. +.B mpu
  305. +BYTES
  306. +.br
  307. + Rounds each packet (including overhead) up to a minimum length
  308. +BYTES. BYTES may not be negative; values between 0 and 256 (inclusive)
  309. +are accepted.
  310. +.PP
  311. +.B atm
  312. +.br
  313. + Compensates for ATM cell framing, which is normally found on ADSL links.
  314. +This is performed after the
  315. +.B overhead
  316. +parameter above. ATM uses fixed 53-byte cells, each of which can carry 48 bytes
  317. +payload.
  318. +.PP
  319. +.B ptm
  320. +.br
  321. + Compensates for PTM encoding, which is normally found on VDSL2 links and
  322. +uses a 64b/65b encoding scheme. It is even more efficient to simply
  323. +derate the specified shaper bandwidth by a factor of 64/65 or 0.984. See
  324. +ITU G.992.3 Annex N and IEEE 802.3 Section 61.3 for details.
  325. +.PP
  326. +.B noatm
  327. +.br
  328. + Disables ATM and PTM compensation.
  329. +
  330. +.SS Failsafe Overhead Keywords
  331. +These two keywords are provided for quick-and-dirty setup. Use them if you
  332. +can't be bothered to read the rest of this section.
  333. +.PP
  334. +.B raw
  335. +(default)
  336. +.br
  337. + Turns off all overhead compensation in CAKE. The packet size reported
  338. +by Linux will be used directly.
  339. +.PP
  340. + Other overhead keywords may be added after "raw". The effect of this is
  341. +to make the overhead compensation operate relative to the reported packet size,
  342. +not the underlying IP packet size.
  343. +.PP
  344. +.B conservative
  345. +.br
  346. + Compensates for more overhead than is likely to occur on any
  347. +widely-deployed link technology.
  348. +.br
  349. + Equivalent to
  350. +.B overhead 48 atm.
  351. +
  352. +.SS ADSL Overhead Keywords
  353. +Most ADSL modems have a way to check which framing scheme is in use. Often this
  354. +is also specified in the settings document provided by the ISP. The keywords in
  355. +this section are intended to correspond with these sources of information. All
  356. +of them implicitly set the
  357. +.B atm
  358. +flag.
  359. +.PP
  360. +.B pppoa-vcmux
  361. +.br
  362. + Equivalent to
  363. +.B overhead 10 atm
  364. +.PP
  365. +.B pppoa-llc
  366. +.br
  367. + Equivalent to
  368. +.B overhead 14 atm
  369. +.PP
  370. +.B pppoe-vcmux
  371. +.br
  372. + Equivalent to
  373. +.B overhead 32 atm
  374. +.PP
  375. +.B pppoe-llcsnap
  376. +.br
  377. + Equivalent to
  378. +.B overhead 40 atm
  379. +.PP
  380. +.B bridged-vcmux
  381. +.br
  382. + Equivalent to
  383. +.B overhead 24 atm
  384. +.PP
  385. +.B bridged-llcsnap
  386. +.br
  387. + Equivalent to
  388. +.B overhead 32 atm
  389. +.PP
  390. +.B ipoa-vcmux
  391. +.br
  392. + Equivalent to
  393. +.B overhead 8 atm
  394. +.PP
  395. +.B ipoa-llcsnap
  396. +.br
  397. + Equivalent to
  398. +.B overhead 16 atm
  399. +.PP
  400. +See also the Ethernet Correction Factors section below.
  401. +
  402. +.SS VDSL2 Overhead Keywords
  403. +ATM was dropped from VDSL2 in favour of PTM, which is a much more
  404. +straightforward framing scheme. Some ISPs retained PPPoE for compatibility with
  405. +their existing back-end systems.
  406. +.PP
  407. +.B pppoe-ptm
  408. +.br
  409. + Equivalent to
  410. +.B overhead 30 ptm
  411. +
  412. +.br
  413. + PPPoE: 2B PPP + 6B PPPoE +
  414. +.br
  415. + ETHERNET: 6B dest MAC + 6B src MAC + 2B ethertype + 4B Frame Check Sequence +
  416. +.br
  417. + PTM: 1B Start of Frame (S) + 1B End of Frame (Ck) + 2B TC-CRC (PTM-FCS)
  418. +.br
  419. +.PP
  420. +.B bridged-ptm
  421. +.br
  422. + Equivalent to
  423. +.B overhead 22 ptm
  424. +.br
  425. + ETHERNET: 6B dest MAC + 6B src MAC + 2B ethertype + 4B Frame Check Sequence +
  426. +.br
  427. + PTM: 1B Start of Frame (S) + 1B End of Frame (Ck) + 2B TC-CRC (PTM-FCS)
  428. +.br
  429. +.PP
  430. +See also the Ethernet Correction Factors section below.
  431. +
  432. +.SS DOCSIS Cable Overhead Keyword
  433. +DOCSIS is the universal standard for providing Internet service over cable-TV
  434. +infrastructure.
  435. +
  436. +In this case, the actual on-wire overhead is less important than the packet size
  437. +the head-end equipment uses for shaping and metering. This is specified to be
  438. +an Ethernet frame including the CRC (aka FCS).
  439. +.PP
  440. +.B docsis
  441. +.br
  442. + Equivalent to
  443. +.B overhead 18 mpu 64 noatm
  444. +
  445. +.SS Ethernet Overhead Keywords
  446. +.PP
  447. +.B ethernet
  448. +.br
  449. + Accounts for Ethernet's preamble, inter-frame gap, and Frame Check
  450. +Sequence. Use this keyword when the bottleneck being shaped for is an
  451. +actual Ethernet cable.
  452. +.br
  453. + Equivalent to
  454. +.B overhead 38 mpu 84 noatm
  455. +.PP
  456. +.B ether-vlan
  457. +.br
  458. + Adds 4 bytes to the overhead compensation, accounting for an IEEE 802.1Q
  459. +VLAN header appended to the Ethernet frame header. NB: Some ISPs use one or
  460. +even two of these within PPPoE; this keyword may be repeated as necessary to
  461. +express this.
  462. +
  463. +.SH ROUND TRIP TIME PARAMETERS
  464. +Active Queue Management (AQM) consists of embedding congestion signals in the
  465. +packet flow, which receivers use to instruct senders to slow down when the queue
  466. +is persistently occupied. CAKE uses ECN signalling when available, and packet
  467. +drops otherwise, according to a combination of the Codel and BLUE AQM algorithms
  468. +called COBALT.
  469. +
  470. +Very short latencies require a very rapid AQM response to adequately control
  471. +latency. However, such a rapid response tends to impair throughput when the
  472. +actual RTT is relatively long. CAKE allows specifying the RTT it assumes for
  473. +tuning various parameters. Actual RTTs within an order of magnitude of this
  474. +will generally work well for both throughput and latency management.
  475. +
  476. +At the 'lan' setting and below, the time constants are similar in magnitude to
  477. +the jitter in the Linux kernel itself, so congestion might be signalled
  478. +prematurely. The flows will then become sparse and total throughput reduced,
  479. +leaving little or no back-pressure for the fairness logic to work against. Use
  480. +the "metro" setting for local lans unless you have a custom kernel.
  481. +.PP
  482. +.B rtt
  483. +TIME
  484. +.br
  485. + Manually specify an RTT.
  486. +.PP
  487. +.B datacentre
  488. +.br
  489. + For extremely high-performance 10GigE+ networks only. Equivalent to
  490. +.B rtt 100us.
  491. +.PP
  492. +.B lan
  493. +.br
  494. + For pure Ethernet (not Wi-Fi) networks, at home or in the office. Don't
  495. +use this when shaping for an Internet access link. Equivalent to
  496. +.B rtt 1ms.
  497. +.PP
  498. +.B metro
  499. +.br
  500. + For traffic mostly within a single city. Equivalent to
  501. +.B rtt 10ms.
  502. +.PP
  503. +.B regional
  504. +.br
  505. + For traffic mostly within a European-sized country. Equivalent to
  506. +.B rtt 30ms.
  507. +.PP
  508. +.B internet
  509. +(default)
  510. +.br
  511. + This is suitable for most Internet traffic. Equivalent to
  512. +.B rtt 100ms.
  513. +.PP
  514. +.B oceanic
  515. +.br
  516. + For Internet traffic with generally above-average latency, such as that
  517. +suffered by Australasian residents. Equivalent to
  518. +.B rtt 300ms.
  519. +.PP
  520. +.B satellite
  521. +.br
  522. + For traffic via geostationary satellites. Equivalent to
  523. +.B rtt 1000ms.
  524. +.PP
  525. +.B interplanetary
  526. +.br
  527. + So named because Jupiter is about 1 light-hour from Earth. Use this to
  528. +(almost) completely disable AQM actions. Equivalent to
  529. +.B rtt 3600s.
  530. +
  531. +.SH FLOW ISOLATION PARAMETERS
  532. +With flow isolation enabled, CAKE places packets from different flows into
  533. +different queues, each of which carries its own AQM state. Packets from each
  534. +queue are then delivered fairly, according to a DRR++ algorithm which minimises
  535. +latency for "sparse" flows. CAKE uses a set-associative hashing algorithm to
  536. +minimise flow collisions.
  537. +
  538. +These keywords specify whether fairness based on source address, destination
  539. +address, individual flows, or any combination of those is desired.
  540. +.PP
  541. +.B flowblind
  542. +.br
  543. + Disables flow isolation; all traffic passes through a single queue for
  544. +each tin.
  545. +.PP
  546. +.B srchost
  547. +.br
  548. + Flows are defined only by source address. Could be useful on the egress
  549. +path of an ISP backhaul.
  550. +.PP
  551. +.B dsthost
  552. +.br
  553. + Flows are defined only by destination address. Could be useful on the
  554. +ingress path of an ISP backhaul.
  555. +.PP
  556. +.B hosts
  557. +.br
  558. + Flows are defined by source-destination host pairs. This is host
  559. +isolation, rather than flow isolation.
  560. +.PP
  561. +.B flows
  562. +.br
  563. + Flows are defined by the entire 5-tuple of source address, destination
  564. +address, transport protocol, source port and destination port. This is the type
  565. +of flow isolation performed by SFQ and fq_codel.
  566. +.PP
  567. +.B dual-srchost
  568. +.br
  569. + Flows are defined by the 5-tuple, and fairness is applied first over
  570. +source addresses, then over individual flows. Good for use on egress traffic
  571. +from a LAN to the internet, where it'll prevent any one LAN host from
  572. +monopolising the uplink, regardless of the number of flows they use.
  573. +.PP
  574. +.B dual-dsthost
  575. +.br
  576. + Flows are defined by the 5-tuple, and fairness is applied first over
  577. +destination addresses, then over individual flows. Good for use on ingress
  578. +traffic to a LAN from the internet, where it'll prevent any one LAN host from
  579. +monopolising the downlink, regardless of the number of flows they use.
  580. +.PP
  581. +.B triple-isolate
  582. +(default)
  583. +.br
  584. + Flows are defined by the 5-tuple, and fairness is applied over source
  585. +*and* destination addresses intelligently (ie. not merely by host-pairs), and
  586. +also over individual flows. Use this if you're not certain whether to use
  587. +dual-srchost or dual-dsthost; it'll do both jobs at once, preventing any one
  588. +host on *either* side of the link from monopolising it with a large number of
  589. +flows.
  590. +.PP
  591. +.B nat
  592. +.br
  593. + Instructs Cake to perform a NAT lookup before applying flow-isolation
  594. +rules, to determine the true addresses and port numbers of the packet, to
  595. +improve fairness between hosts "inside" the NAT. This has no practical effect
  596. +in "flowblind" or "flows" modes, or if NAT is performed on a different host.
  597. +.PP
  598. +.B nonat
  599. +(default)
  600. +.br
  601. + Cake will not perform a NAT lookup. Flow isolation will be performed
  602. +using the addresses and port numbers directly visible to the interface Cake is
  603. +attached to.
  604. +
  605. +.SH PRIORITY QUEUE PARAMETERS
  606. +CAKE can divide traffic into "tins" based on the Diffserv field. Each tin has
  607. +its own independent set of flow-isolation queues, and is serviced based on a WRR
  608. +algorithm. To avoid perverse Diffserv marking incentives, tin weights have a
  609. +"priority sharing" value when bandwidth used by that tin is below a threshold,
  610. +and a lower "bandwidth sharing" value when above. Bandwidth is compared against
  611. +the threshold using the same algorithm as the deficit-mode shaper.
  612. +
  613. +Detailed customisation of tin parameters is not provided. The following presets
  614. +perform all necessary tuning, relative to the current shaper bandwidth and RTT
  615. +settings.
  616. +.PP
  617. +.B besteffort
  618. +.br
  619. + Disables priority queuing by placing all traffic in one tin.
  620. +.PP
  621. +.B precedence
  622. +.br
  623. + Enables legacy interpretation of TOS "Precedence" field. Use of this
  624. +preset on the modern Internet is firmly discouraged.
  625. +.PP
  626. +.B diffserv4
  627. +.br
  628. + Provides a general-purpose Diffserv implementation with four tins:
  629. +.br
  630. + Bulk (CS1), 6.25% threshold, generally low priority.
  631. +.br
  632. + Best Effort (general), 100% threshold.
  633. +.br
  634. + Video (AF4x, AF3x, CS3, AF2x, CS2, TOS4, TOS1), 50% threshold.
  635. +.br
  636. + Voice (CS7, CS6, EF, VA, CS5, CS4), 25% threshold.
  637. +.PP
  638. +.B diffserv3
  639. +(default)
  640. +.br
  641. + Provides a simple, general-purpose Diffserv implementation with three tins:
  642. +.br
  643. + Bulk (CS1), 6.25% threshold, generally low priority.
  644. +.br
  645. + Best Effort (general), 100% threshold.
  646. +.br
  647. + Voice (CS7, CS6, EF, VA, TOS4), 25% threshold, reduced Codel interval.
  648. +
  649. +.SH OTHER PARAMETERS
  650. +.B memlimit
  651. +LIMIT
  652. +.br
  653. + Limit the memory consumed by Cake to LIMIT bytes. Note that this does
  654. +not translate directly to queue size (so do not size this based on bandwidth
  655. +delay product considerations, but rather on worst case acceptable memory
  656. +consumption), as there is some overhead in the data structures containing the
  657. +packets, especially for small packets.
  658. +
  659. + By default, the limit is calculated based on the bandwidth and RTT
  660. +settings.
  661. +
  662. +.PP
  663. +.B wash
  664. +
  665. +.br
  666. + Traffic entering your diffserv domain is frequently mis-marked in
  667. +transit from the perspective of your network, and traffic exiting yours may be
  668. +mis-marked from the perspective of the transiting provider.
  669. +
  670. +Apply the wash option to clear all extra diffserv (but not ECN bits), after
  671. +priority queuing has taken place.
  672. +
  673. +If you are shaping inbound, and cannot trust the diffserv markings (as is the
  674. +case for Comcast Cable, among others), it is best to use a single queue
  675. +"besteffort" mode with wash.
  676. +
  677. +.PP
  678. +.B split-gso
  679. +
  680. +.br
  681. + This option controls whether CAKE will split General Segmentation
  682. +Offload (GSO) super-packets into their on-the-wire components and
  683. +dequeue them individually.
  684. +
  685. +.br
  686. +Super-packets are created by the networking stack to improve efficiency.
  687. +However, because they are larger they take longer to dequeue, which
  688. +translates to higher latency for competing flows, especially at lower
  689. +bandwidths. CAKE defaults to splitting GSO packets to achieve the lowest
  690. +possible latency. At link speeds higher than 10 Gbps, setting the
  691. +no-split-gso parameter can increase the maximum achievable throughput by
  692. +retaining the full GSO packets.
  693. +
  694. +.SH OVERRIDING CLASSIFICATION WITH TC FILTERS
  695. +
  696. +CAKE supports overriding of its internal classification of packets through the
  697. +tc filter mechanism. Packets can be assigned to different priority tins by
  698. +setting the
  699. +.B priority
  700. +field on the skb, and the flow hashing can be overridden by setting the
  701. +.B classid
  702. +parameter.
  703. +
  704. +.PP
  705. +.B Tin override
  706. +
  707. +.br
  708. + To assign a priority tin, the major number of the priority field needs
  709. +to match the qdisc handle of the cake instance; if it does, the minor number
  710. +will be interpreted as the tin index. For example, to classify all ICMP packets
  711. +as 'bulk', the following filter can be used:
  712. +
  713. +.br
  714. + # tc qdisc replace dev eth0 handle 1: root cake diffserv3
  715. + # tc filter add dev eth0 parent 1: protocol ip prio 1 \\
  716. + u32 match icmp type 0 0 action skbedit priority 1:1
  717. +
  718. +.PP
  719. +.B Flow hash override
  720. +
  721. +.br
  722. + To override flow hashing, the classid can be set. CAKE will interpret
  723. +the major number of the classid as the host hash used in host isolation mode,
  724. +and the minor number as the flow hash used for flow-based queueing. One or both
  725. +of those can be set, and will be used if the relevant flow isolation parameter
  726. +is set (i.e., the major number will be ignored if CAKE is not configured in
  727. +hosts mode, and the minor number will be ignored if CAKE is not configured in
  728. +flows mode).
  729. +
  730. +.br
  731. +This example will assign all ICMP packets to the first queue:
  732. +
  733. +.br
  734. + # tc qdisc replace dev eth0 handle 1: root cake
  735. + # tc filter add dev eth0 parent 1: protocol ip prio 1 \\
  736. + u32 match icmp type 0 0 classid 0:1
  737. +
  738. +.br
  739. +If only one of the host and flow overrides is set, CAKE will compute the other
  740. +hash from the packet as normal. Note, however, that the host isolation mode
  741. +works by assigning a host ID to the flow queue; so if overriding both host and
  742. +flow, the same flow cannot have more than one host assigned. In addition, it is
  743. +not possible to assign different source and destination host IDs through the
  744. +override mechanism; if a host ID is assigned, it will be used as both source and
  745. +destination host.
  746. +
  747. +
  748. +
  749. +.SH EXAMPLES
  750. +# tc qdisc delete root dev eth0
  751. +.br
  752. +# tc qdisc add root dev eth0 cake bandwidth 100Mbit ethernet
  753. +.br
  754. +# tc -s qdisc show dev eth0
  755. +.br
  756. +qdisc cake 1: root refcnt 2 bandwidth 100Mbit diffserv3 triple-isolate rtt 100.0ms noatm overhead 38 mpu 84
  757. + Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
  758. + backlog 0b 0p requeues 0
  759. + memory used: 0b of 5000000b
  760. + capacity estimate: 100Mbit
  761. + min/max network layer size: 65535 / 0
  762. + min/max overhead-adjusted size: 65535 / 0
  763. + average network hdr offset: 0
  764. +
  765. + Bulk Best Effort Voice
  766. + thresh 6250Kbit 100Mbit 25Mbit
  767. + target 5.0ms 5.0ms 5.0ms
  768. + interval 100.0ms 100.0ms 100.0ms
  769. + pk_delay 0us 0us 0us
  770. + av_delay 0us 0us 0us
  771. + sp_delay 0us 0us 0us
  772. + pkts 0 0 0
  773. + bytes 0 0 0
  774. + way_inds 0 0 0
  775. + way_miss 0 0 0
  776. + way_cols 0 0 0
  777. + drops 0 0 0
  778. + marks 0 0 0
  779. + ack_drop 0 0 0
  780. + sp_flows 0 0 0
  781. + bk_flows 0 0 0
  782. + un_flows 0 0 0
  783. + max_len 0 0 0
  784. + quantum 300 1514 762
  785. +
  786. +After some use:
  787. +.br
  788. +# tc -s qdisc show dev eth0
  789. +
  790. +qdisc cake 1: root refcnt 2 bandwidth 100Mbit diffserv3 triple-isolate rtt 100.0ms noatm overhead 38 mpu 84
  791. + Sent 44709231 bytes 31931 pkt (dropped 45, overlimits 93782 requeues 0)
  792. + backlog 33308b 22p requeues 0
  793. + memory used: 292352b of 5000000b
  794. + capacity estimate: 100Mbit
  795. + min/max network layer size: 28 / 1500
  796. + min/max overhead-adjusted size: 84 / 1538
  797. + average network hdr offset: 14
  798. +
  799. + Bulk Best Effort Voice
  800. + thresh 6250Kbit 100Mbit 25Mbit
  801. + target 5.0ms 5.0ms 5.0ms
  802. + interval 100.0ms 100.0ms 100.0ms
  803. + pk_delay 8.7ms 6.9ms 5.0ms
  804. + av_delay 4.9ms 5.3ms 3.8ms
  805. + sp_delay 727us 1.4ms 511us
  806. + pkts 2590 21271 8137
  807. + bytes 3081804 30302659 11426206
  808. + way_inds 0 46 0
  809. + way_miss 3 17 4
  810. + way_cols 0 0 0
  811. + drops 20 15 10
  812. + marks 0 0 0
  813. + ack_drop 0 0 0
  814. + sp_flows 2 4 1
  815. + bk_flows 1 2 1
  816. + un_flows 0 0 0
  817. + max_len 1514 1514 1514
  818. + quantum 300 1514 762
  819. +
  820. +.SH SEE ALSO
  821. +.BR tc (8),
  822. +.BR tc-codel (8),
  823. +.BR tc-fq_codel (8),
  824. +.BR tc-htb (8)
  825. +
  826. +.SH AUTHORS
  827. +Cake's principal author is Jonathan Morton, with contributions from
  828. +Tony Ambardar, Kevin Darbyshire-Bryant, Toke Høiland-Jørgensen,
  829. +Sebastian Moeller, Ryan Mounce, Dean Scarff, Nils Andreas Svee, and Dave Täht.
  830. +
  831. +This manual page was written by Loganaden Velvindron. Please report corrections
  832. +to the Linux Networking mailing list <[email protected]>.
  833. --- a/man/man8/tc.8
  834. +++ b/man/man8/tc.8
  835. @@ -795,6 +795,7 @@ was written by Alexey N. Kuznetsov and a
  836. .BR tc-basic (8),
  837. .BR tc-bfifo (8),
  838. .BR tc-bpf (8),
  839. +.BR tc-cake (8),
  840. .BR tc-cbq (8),
  841. .BR tc-cgroup (8),
  842. .BR tc-choke (8),
  843. --- a/tc/Makefile
  844. +++ b/tc/Makefile
  845. @@ -66,6 +66,7 @@ TCMODULES += q_codel.o
  846. TCMODULES += q_fq_codel.o
  847. TCMODULES += q_fq.o
  848. TCMODULES += q_pie.o
  849. +TCMODULES += q_cake.o
  850. TCMODULES += q_hhf.o
  851. TCMODULES += q_clsact.o
  852. TCMODULES += e_bpf.o
  853. --- /dev/null
  854. +++ b/tc/q_cake.c
  855. @@ -0,0 +1,805 @@
  856. +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  857. +
  858. +/*
  859. + * Common Applications Kept Enhanced -- CAKE
  860. + *
  861. + * Copyright (C) 2014-2018 Jonathan Morton <[email protected]>
  862. + * Copyright (C) 2017-2018 Toke Høiland-Jørgensen <[email protected]>
  863. + */
  864. +
  865. +#include <stddef.h>
  866. +#include <stdio.h>
  867. +#include <stdlib.h>
  868. +#include <unistd.h>
  869. +#include <syslog.h>
  870. +#include <fcntl.h>
  871. +#include <sys/socket.h>
  872. +#include <netinet/in.h>
  873. +#include <arpa/inet.h>
  874. +#include <string.h>
  875. +#include <inttypes.h>
  876. +
  877. +#include "utils.h"
  878. +#include "tc_util.h"
  879. +
  880. +struct cake_preset {
  881. + char *name;
  882. + unsigned int target;
  883. + unsigned int interval;
  884. +};
  885. +
  886. +static struct cake_preset presets[] = {
  887. + {"datacentre", 5, 100},
  888. + {"lan", 50, 1000},
  889. + {"metro", 500, 10000},
  890. + {"regional", 1500, 30000},
  891. + {"internet", 5000, 100000},
  892. + {"oceanic", 15000, 300000},
  893. + {"satellite", 50000, 1000000},
  894. + {"interplanetary", 50000000, 1000000000},
  895. +};
  896. +
  897. +static const char * diffserv_names[CAKE_DIFFSERV_MAX] = {
  898. + [CAKE_DIFFSERV_DIFFSERV3] = "diffserv3",
  899. + [CAKE_DIFFSERV_DIFFSERV4] = "diffserv4",
  900. + [CAKE_DIFFSERV_DIFFSERV8] = "diffserv8",
  901. + [CAKE_DIFFSERV_BESTEFFORT] = "besteffort",
  902. + [CAKE_DIFFSERV_PRECEDENCE] = "precedence",
  903. +};
  904. +
  905. +static const char * flowmode_names[CAKE_FLOW_MAX] = {
  906. + [CAKE_FLOW_NONE] = "flowblind",
  907. + [CAKE_FLOW_SRC_IP] = "srchost",
  908. + [CAKE_FLOW_DST_IP] = "dsthost",
  909. + [CAKE_FLOW_HOSTS] = "hosts",
  910. + [CAKE_FLOW_FLOWS] = "flows",
  911. + [CAKE_FLOW_DUAL_SRC] = "dual-srchost",
  912. + [CAKE_FLOW_DUAL_DST] = "dual-dsthost",
  913. + [CAKE_FLOW_TRIPLE] = "triple-isolate",
  914. +};
  915. +
  916. +static struct cake_preset *find_preset(char *argv)
  917. +{
  918. + int i;
  919. +
  920. + for (i = 0; i < ARRAY_SIZE(presets); i++)
  921. + if (!strcmp(argv, presets[i].name))
  922. + return &presets[i];
  923. + return NULL;
  924. +}
  925. +
  926. +static void explain(void)
  927. +{
  928. + fprintf(stderr,
  929. +"Usage: ... cake [ bandwidth RATE | unlimited* | autorate-ingress ]\n"
  930. +" [ rtt TIME | datacentre | lan | metro | regional |\n"
  931. +" internet* | oceanic | satellite | interplanetary ]\n"
  932. +" [ besteffort | diffserv8 | diffserv4 | diffserv3* ]\n"
  933. +" [ flowblind | srchost | dsthost | hosts | flows |\n"
  934. +" dual-srchost | dual-dsthost | triple-isolate* ]\n"
  935. +" [ nat | nonat* ]\n"
  936. +" [ wash | nowash* ]\n"
  937. +" [ split-gso* | no-split-gso ]\n"
  938. +" [ ack-filter | ack-filter-aggressive | no-ack-filter* ]\n"
  939. +" [ memlimit LIMIT ]\n"
  940. +" [ ptm | atm | noatm* ] [ overhead N | conservative | raw* ]\n"
  941. +" [ mpu N ] [ ingress | egress* ]\n"
  942. +" (* marks defaults)\n");
  943. +}
  944. +
  945. +static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv,
  946. + struct nlmsghdr *n, const char *dev)
  947. +{
  948. + struct cake_preset *preset, *preset_set = NULL;
  949. + bool overhead_override = false;
  950. + bool overhead_set = false;
  951. + unsigned int interval = 0;
  952. + unsigned int diffserv = 0;
  953. + unsigned int memlimit = 0;
  954. + unsigned int target = 0;
  955. + __u64 bandwidth = 0;
  956. + int ack_filter = -1;
  957. + struct rtattr *tail;
  958. + int split_gso = -1;
  959. + int unlimited = 0;
  960. + int flowmode = -1;
  961. + int autorate = -1;
  962. + int ingress = -1;
  963. + int overhead = 0;
  964. + int wash = -1;
  965. + int nat = -1;
  966. + int atm = -1;
  967. + int mpu = 0;
  968. +
  969. + while (argc > 0) {
  970. + if (strcmp(*argv, "bandwidth") == 0) {
  971. + NEXT_ARG();
  972. + if (get_rate64(&bandwidth, *argv)) {
  973. + fprintf(stderr, "Illegal \"bandwidth\"\n");
  974. + return -1;
  975. + }
  976. + unlimited = 0;
  977. + autorate = 0;
  978. + } else if (strcmp(*argv, "unlimited") == 0) {
  979. + bandwidth = 0;
  980. + unlimited = 1;
  981. + autorate = 0;
  982. + } else if (strcmp(*argv, "autorate-ingress") == 0) {
  983. + autorate = 1;
  984. + } else if (strcmp(*argv, "rtt") == 0) {
  985. + NEXT_ARG();
  986. + if (get_time(&interval, *argv)) {
  987. + fprintf(stderr, "Illegal \"rtt\"\n");
  988. + return -1;
  989. + }
  990. + target = interval / 20;
  991. + if (!target)
  992. + target = 1;
  993. + } else if ((preset = find_preset(*argv))) {
  994. + if (preset_set)
  995. + duparg(*argv, preset_set->name);
  996. + preset_set = preset;
  997. + target = preset->target;
  998. + interval = preset->interval;
  999. + } else if (strcmp(*argv, "besteffort") == 0) {
  1000. + diffserv = CAKE_DIFFSERV_BESTEFFORT;
  1001. + } else if (strcmp(*argv, "precedence") == 0) {
  1002. + diffserv = CAKE_DIFFSERV_PRECEDENCE;
  1003. + } else if (strcmp(*argv, "diffserv8") == 0) {
  1004. + diffserv = CAKE_DIFFSERV_DIFFSERV8;
  1005. + } else if (strcmp(*argv, "diffserv4") == 0) {
  1006. + diffserv = CAKE_DIFFSERV_DIFFSERV4;
  1007. + } else if (strcmp(*argv, "diffserv") == 0) {
  1008. + diffserv = CAKE_DIFFSERV_DIFFSERV4;
  1009. + } else if (strcmp(*argv, "diffserv3") == 0) {
  1010. + diffserv = CAKE_DIFFSERV_DIFFSERV3;
  1011. + } else if (strcmp(*argv, "nowash") == 0) {
  1012. + wash = 0;
  1013. + } else if (strcmp(*argv, "wash") == 0) {
  1014. + wash = 1;
  1015. + } else if (strcmp(*argv, "split-gso") == 0) {
  1016. + split_gso = 1;
  1017. + } else if (strcmp(*argv, "no-split-gso") == 0) {
  1018. + split_gso = 0;
  1019. + } else if (strcmp(*argv, "flowblind") == 0) {
  1020. + flowmode = CAKE_FLOW_NONE;
  1021. + } else if (strcmp(*argv, "srchost") == 0) {
  1022. + flowmode = CAKE_FLOW_SRC_IP;
  1023. + } else if (strcmp(*argv, "dsthost") == 0) {
  1024. + flowmode = CAKE_FLOW_DST_IP;
  1025. + } else if (strcmp(*argv, "hosts") == 0) {
  1026. + flowmode = CAKE_FLOW_HOSTS;
  1027. + } else if (strcmp(*argv, "flows") == 0) {
  1028. + flowmode = CAKE_FLOW_FLOWS;
  1029. + } else if (strcmp(*argv, "dual-srchost") == 0) {
  1030. + flowmode = CAKE_FLOW_DUAL_SRC;
  1031. + } else if (strcmp(*argv, "dual-dsthost") == 0) {
  1032. + flowmode = CAKE_FLOW_DUAL_DST;
  1033. + } else if (strcmp(*argv, "triple-isolate") == 0) {
  1034. + flowmode = CAKE_FLOW_TRIPLE;
  1035. + } else if (strcmp(*argv, "nat") == 0) {
  1036. + nat = 1;
  1037. + } else if (strcmp(*argv, "nonat") == 0) {
  1038. + nat = 0;
  1039. + } else if (strcmp(*argv, "ptm") == 0) {
  1040. + atm = CAKE_ATM_PTM;
  1041. + } else if (strcmp(*argv, "atm") == 0) {
  1042. + atm = CAKE_ATM_ATM;
  1043. + } else if (strcmp(*argv, "noatm") == 0) {
  1044. + atm = CAKE_ATM_NONE;
  1045. + } else if (strcmp(*argv, "raw") == 0) {
  1046. + atm = CAKE_ATM_NONE;
  1047. + overhead = 0;
  1048. + overhead_set = true;
  1049. + overhead_override = true;
  1050. + } else if (strcmp(*argv, "conservative") == 0) {
  1051. + /*
  1052. + * Deliberately over-estimate overhead:
  1053. + * one whole ATM cell plus ATM framing.
  1054. + * A safe choice if the actual overhead is unknown.
  1055. + */
  1056. + atm = CAKE_ATM_ATM;
  1057. + overhead = 48;
  1058. + overhead_set = true;
  1059. +
  1060. + /* Various ADSL framing schemes, all over ATM cells */
  1061. + } else if (strcmp(*argv, "ipoa-vcmux") == 0) {
  1062. + atm = CAKE_ATM_ATM;
  1063. + overhead += 8;
  1064. + overhead_set = true;
  1065. + } else if (strcmp(*argv, "ipoa-llcsnap") == 0) {
  1066. + atm = CAKE_ATM_ATM;
  1067. + overhead += 16;
  1068. + overhead_set = true;
  1069. + } else if (strcmp(*argv, "bridged-vcmux") == 0) {
  1070. + atm = CAKE_ATM_ATM;
  1071. + overhead += 24;
  1072. + overhead_set = true;
  1073. + } else if (strcmp(*argv, "bridged-llcsnap") == 0) {
  1074. + atm = CAKE_ATM_ATM;
  1075. + overhead += 32;
  1076. + overhead_set = true;
  1077. + } else if (strcmp(*argv, "pppoa-vcmux") == 0) {
  1078. + atm = CAKE_ATM_ATM;
  1079. + overhead += 10;
  1080. + overhead_set = true;
  1081. + } else if (strcmp(*argv, "pppoa-llc") == 0) {
  1082. + atm = CAKE_ATM_ATM;
  1083. + overhead += 14;
  1084. + overhead_set = true;
  1085. + } else if (strcmp(*argv, "pppoe-vcmux") == 0) {
  1086. + atm = CAKE_ATM_ATM;
  1087. + overhead += 32;
  1088. + overhead_set = true;
  1089. + } else if (strcmp(*argv, "pppoe-llcsnap") == 0) {
  1090. + atm = CAKE_ATM_ATM;
  1091. + overhead += 40;
  1092. + overhead_set = true;
  1093. +
  1094. + /* Typical VDSL2 framing schemes, both over PTM */
  1095. + /* PTM has 64b/65b coding which absorbs some bandwidth */
  1096. + } else if (strcmp(*argv, "pppoe-ptm") == 0) {
  1097. + /* 2B PPP + 6B PPPoE + 6B dest MAC + 6B src MAC
  1098. + * + 2B ethertype + 4B Frame Check Sequence
  1099. + * + 1B Start of Frame (S) + 1B End of Frame (Ck)
  1100. + * + 2B TC-CRC (PTM-FCS) = 30B
  1101. + */
  1102. + atm = CAKE_ATM_PTM;
  1103. + overhead += 30;
  1104. + overhead_set = true;
  1105. + } else if (strcmp(*argv, "bridged-ptm") == 0) {
  1106. + /* 6B dest MAC + 6B src MAC + 2B ethertype
  1107. + * + 4B Frame Check Sequence
  1108. + * + 1B Start of Frame (S) + 1B End of Frame (Ck)
  1109. + * + 2B TC-CRC (PTM-FCS) = 22B
  1110. + */
  1111. + atm = CAKE_ATM_PTM;
  1112. + overhead += 22;
  1113. + overhead_set = true;
  1114. + } else if (strcmp(*argv, "via-ethernet") == 0) {
  1115. + /*
  1116. + * We used to use this flag to manually compensate for
  1117. + * Linux including the Ethernet header on Ethernet-type
  1118. + * interfaces, but not on IP-type interfaces.
  1119. + *
  1120. + * It is no longer needed, because Cake now adjusts for
  1121. + * that automatically, and is thus ignored.
  1122. + *
  1123. + * It would be deleted entirely, but it appears in the
  1124. + * stats output when the automatic compensation is
  1125. + * active.
  1126. + */
  1127. + } else if (strcmp(*argv, "ethernet") == 0) {
  1128. + /* ethernet pre-amble & interframe gap & FCS
  1129. + * you may need to add vlan tag
  1130. + */
  1131. + overhead += 38;
  1132. + overhead_set = true;
  1133. + mpu = 84;
  1134. +
  1135. + /* Additional Ethernet-related overhead used by some ISPs */
  1136. + } else if (strcmp(*argv, "ether-vlan") == 0) {
  1137. + /* 802.1q VLAN tag - may be repeated */
  1138. + overhead += 4;
  1139. + overhead_set = true;
  1140. +
  1141. + /*
  1142. + * DOCSIS cable shapers account for Ethernet frame with FCS,
  1143. + * but not interframe gap or preamble.
  1144. + */
  1145. + } else if (strcmp(*argv, "docsis") == 0) {
  1146. + atm = CAKE_ATM_NONE;
  1147. + overhead += 18;
  1148. + overhead_set = true;
  1149. + mpu = 64;
  1150. + } else if (strcmp(*argv, "overhead") == 0) {
  1151. + char *p = NULL;
  1152. +
  1153. + NEXT_ARG();
  1154. + overhead = strtol(*argv, &p, 10);
  1155. + if (!p || *p || !*argv ||
  1156. + overhead < -64 || overhead > 256) {
  1157. + fprintf(stderr,
  1158. + "Illegal \"overhead\", valid range is -64 to 256\\n");
  1159. + return -1;
  1160. + }
  1161. + overhead_set = true;
  1162. +
  1163. + } else if (strcmp(*argv, "mpu") == 0) {
  1164. + char *p = NULL;
  1165. +
  1166. + NEXT_ARG();
  1167. + mpu = strtol(*argv, &p, 10);
  1168. + if (!p || *p || !*argv || mpu < 0 || mpu > 256) {
  1169. + fprintf(stderr,
  1170. + "Illegal \"mpu\", valid range is 0 to 256\\n");
  1171. + return -1;
  1172. + }
  1173. + } else if (strcmp(*argv, "ingress") == 0) {
  1174. + ingress = 1;
  1175. + } else if (strcmp(*argv, "egress") == 0) {
  1176. + ingress = 0;
  1177. + } else if (strcmp(*argv, "no-ack-filter") == 0) {
  1178. + ack_filter = CAKE_ACK_NONE;
  1179. + } else if (strcmp(*argv, "ack-filter") == 0) {
  1180. + ack_filter = CAKE_ACK_FILTER;
  1181. + } else if (strcmp(*argv, "ack-filter-aggressive") == 0) {
  1182. + ack_filter = CAKE_ACK_AGGRESSIVE;
  1183. + } else if (strcmp(*argv, "memlimit") == 0) {
  1184. + NEXT_ARG();
  1185. + if (get_size(&memlimit, *argv)) {
  1186. + fprintf(stderr,
  1187. + "Illegal value for \"memlimit\": \"%s\"\n", *argv);
  1188. + return -1;
  1189. + }
  1190. + } else if (strcmp(*argv, "help") == 0) {
  1191. + explain();
  1192. + return -1;
  1193. + } else {
  1194. + fprintf(stderr, "What is \"%s\"?\n", *argv);
  1195. + explain();
  1196. + return -1;
  1197. + }
  1198. + argc--; argv++;
  1199. + }
  1200. +
  1201. + tail = NLMSG_TAIL(n);
  1202. + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
  1203. + if (bandwidth || unlimited)
  1204. + addattr_l(n, 1024, TCA_CAKE_BASE_RATE64, &bandwidth,
  1205. + sizeof(bandwidth));
  1206. + if (diffserv)
  1207. + addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv,
  1208. + sizeof(diffserv));
  1209. + if (atm != -1)
  1210. + addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm));
  1211. + if (flowmode != -1)
  1212. + addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode,
  1213. + sizeof(flowmode));
  1214. + if (overhead_set)
  1215. + addattr_l(n, 1024, TCA_CAKE_OVERHEAD, &overhead,
  1216. + sizeof(overhead));
  1217. + if (overhead_override) {
  1218. + unsigned int zero = 0;
  1219. +
  1220. + addattr_l(n, 1024, TCA_CAKE_RAW, &zero, sizeof(zero));
  1221. + }
  1222. + if (mpu > 0)
  1223. + addattr_l(n, 1024, TCA_CAKE_MPU, &mpu, sizeof(mpu));
  1224. + if (interval)
  1225. + addattr_l(n, 1024, TCA_CAKE_RTT, &interval, sizeof(interval));
  1226. + if (target)
  1227. + addattr_l(n, 1024, TCA_CAKE_TARGET, &target, sizeof(target));
  1228. + if (autorate != -1)
  1229. + addattr_l(n, 1024, TCA_CAKE_AUTORATE, &autorate,
  1230. + sizeof(autorate));
  1231. + if (memlimit)
  1232. + addattr_l(n, 1024, TCA_CAKE_MEMORY, &memlimit,
  1233. + sizeof(memlimit));
  1234. + if (nat != -1)
  1235. + addattr_l(n, 1024, TCA_CAKE_NAT, &nat, sizeof(nat));
  1236. + if (wash != -1)
  1237. + addattr_l(n, 1024, TCA_CAKE_WASH, &wash, sizeof(wash));
  1238. + if (split_gso != -1)
  1239. + addattr_l(n, 1024, TCA_CAKE_SPLIT_GSO, &split_gso,
  1240. + sizeof(split_gso));
  1241. + if (ingress != -1)
  1242. + addattr_l(n, 1024, TCA_CAKE_INGRESS, &ingress, sizeof(ingress));
  1243. + if (ack_filter != -1)
  1244. + addattr_l(n, 1024, TCA_CAKE_ACK_FILTER, &ack_filter,
  1245. + sizeof(ack_filter));
  1246. +
  1247. + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
  1248. + return 0;
  1249. +}
  1250. +
  1251. +static void cake_print_mode(unsigned int value, unsigned int max,
  1252. + const char *key, const char **table)
  1253. +{
  1254. + if (value < max && table[value]) {
  1255. + print_string(PRINT_ANY, key, "%s ", table[value]);
  1256. + } else {
  1257. + print_string(PRINT_JSON, key, NULL, "unknown");
  1258. + print_string(PRINT_FP, NULL, "(?%s?)", key);
  1259. + }
  1260. +}
  1261. +
  1262. +static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
  1263. +{
  1264. + struct rtattr *tb[TCA_CAKE_MAX + 1];
  1265. + unsigned int interval = 0;
  1266. + unsigned int memlimit = 0;
  1267. + __u64 bandwidth = 0;
  1268. + int ack_filter = 0;
  1269. + int split_gso = 0;
  1270. + int overhead = 0;
  1271. + int autorate = 0;
  1272. + int ingress = 0;
  1273. + int wash = 0;
  1274. + int raw = 0;
  1275. + int mpu = 0;
  1276. + int atm = 0;
  1277. + int nat = 0;
  1278. +
  1279. + SPRINT_BUF(b1);
  1280. + SPRINT_BUF(b2);
  1281. +
  1282. + if (opt == NULL)
  1283. + return 0;
  1284. +
  1285. + parse_rtattr_nested(tb, TCA_CAKE_MAX, opt);
  1286. +
  1287. + if (tb[TCA_CAKE_BASE_RATE64] &&
  1288. + RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) {
  1289. + bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]);
  1290. + if (bandwidth) {
  1291. + print_uint(PRINT_JSON, "bandwidth", NULL, bandwidth);
  1292. + print_string(PRINT_FP, NULL, "bandwidth %s ",
  1293. + sprint_rate(bandwidth, b1));
  1294. + } else
  1295. + print_string(PRINT_ANY, "bandwidth", "bandwidth %s ",
  1296. + "unlimited");
  1297. + }
  1298. + if (tb[TCA_CAKE_AUTORATE] &&
  1299. + RTA_PAYLOAD(tb[TCA_CAKE_AUTORATE]) >= sizeof(__u32)) {
  1300. + autorate = rta_getattr_u32(tb[TCA_CAKE_AUTORATE]);
  1301. + if (autorate == 1)
  1302. + print_string(PRINT_ANY, "autorate", "%s ",
  1303. + "autorate-ingress");
  1304. + else if (autorate)
  1305. + print_string(PRINT_ANY, "autorate", "(?autorate?) ",
  1306. + "unknown");
  1307. + }
  1308. + if (tb[TCA_CAKE_DIFFSERV_MODE] &&
  1309. + RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) {
  1310. + cake_print_mode(rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]),
  1311. + CAKE_DIFFSERV_MAX, "diffserv", diffserv_names);
  1312. + }
  1313. + if (tb[TCA_CAKE_FLOW_MODE] &&
  1314. + RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) {
  1315. + cake_print_mode(rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]),
  1316. + CAKE_FLOW_MAX, "flowmode", flowmode_names);
  1317. + }
  1318. +
  1319. + if (tb[TCA_CAKE_NAT] &&
  1320. + RTA_PAYLOAD(tb[TCA_CAKE_NAT]) >= sizeof(__u32)) {
  1321. + nat = rta_getattr_u32(tb[TCA_CAKE_NAT]);
  1322. + }
  1323. +
  1324. + if (nat)
  1325. + print_string(PRINT_FP, NULL, "nat ", NULL);
  1326. + else
  1327. + print_string(PRINT_FP, NULL, "nonat ", NULL);
  1328. + print_bool(PRINT_JSON, "nat", NULL, nat);
  1329. +
  1330. + if (tb[TCA_CAKE_WASH] &&
  1331. + RTA_PAYLOAD(tb[TCA_CAKE_WASH]) >= sizeof(__u32)) {
  1332. + wash = rta_getattr_u32(tb[TCA_CAKE_WASH]);
  1333. + }
  1334. + if (tb[TCA_CAKE_ATM] &&
  1335. + RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) {
  1336. + atm = rta_getattr_u32(tb[TCA_CAKE_ATM]);
  1337. + }
  1338. + if (tb[TCA_CAKE_OVERHEAD] &&
  1339. + RTA_PAYLOAD(tb[TCA_CAKE_OVERHEAD]) >= sizeof(__s32)) {
  1340. + overhead = *(__s32 *) RTA_DATA(tb[TCA_CAKE_OVERHEAD]);
  1341. + }
  1342. + if (tb[TCA_CAKE_MPU] &&
  1343. + RTA_PAYLOAD(tb[TCA_CAKE_MPU]) >= sizeof(__u32)) {
  1344. + mpu = rta_getattr_u32(tb[TCA_CAKE_MPU]);
  1345. + }
  1346. + if (tb[TCA_CAKE_INGRESS] &&
  1347. + RTA_PAYLOAD(tb[TCA_CAKE_INGRESS]) >= sizeof(__u32)) {
  1348. + ingress = rta_getattr_u32(tb[TCA_CAKE_INGRESS]);
  1349. + }
  1350. + if (tb[TCA_CAKE_ACK_FILTER] &&
  1351. + RTA_PAYLOAD(tb[TCA_CAKE_ACK_FILTER]) >= sizeof(__u32)) {
  1352. + ack_filter = rta_getattr_u32(tb[TCA_CAKE_ACK_FILTER]);
  1353. + }
  1354. + if (tb[TCA_CAKE_SPLIT_GSO] &&
  1355. + RTA_PAYLOAD(tb[TCA_CAKE_SPLIT_GSO]) >= sizeof(__u32)) {
  1356. + split_gso = rta_getattr_u32(tb[TCA_CAKE_SPLIT_GSO]);
  1357. + }
  1358. + if (tb[TCA_CAKE_RAW]) {
  1359. + raw = 1;
  1360. + }
  1361. + if (tb[TCA_CAKE_RTT] &&
  1362. + RTA_PAYLOAD(tb[TCA_CAKE_RTT]) >= sizeof(__u32)) {
  1363. + interval = rta_getattr_u32(tb[TCA_CAKE_RTT]);
  1364. + }
  1365. +
  1366. + if (wash)
  1367. + print_string(PRINT_FP, NULL, "wash ", NULL);
  1368. + else
  1369. + print_string(PRINT_FP, NULL, "nowash ", NULL);
  1370. + print_bool(PRINT_JSON, "wash", NULL, wash);
  1371. +
  1372. + if (ingress)
  1373. + print_string(PRINT_FP, NULL, "ingress ", NULL);
  1374. + print_bool(PRINT_JSON, "ingress", NULL, ingress);
  1375. +
  1376. + if (ack_filter == CAKE_ACK_AGGRESSIVE)
  1377. + print_string(PRINT_ANY, "ack-filter", "ack-filter-%s ",
  1378. + "aggressive");
  1379. + else if (ack_filter == CAKE_ACK_FILTER)
  1380. + print_string(PRINT_ANY, "ack-filter", "ack-filter ", "enabled");
  1381. + else
  1382. + print_string(PRINT_ANY, "ack-filter", "no-ack-filter ", "disabled");
  1383. +
  1384. + if (split_gso)
  1385. + print_string(PRINT_FP, NULL, "split-gso ", NULL);
  1386. + else
  1387. + print_string(PRINT_FP, NULL, "no-split-gso ", NULL);
  1388. + print_bool(PRINT_JSON, "split_gso", NULL, split_gso);
  1389. +
  1390. + if (interval)
  1391. + print_string(PRINT_FP, NULL, "rtt %s ",
  1392. + sprint_time(interval, b2));
  1393. + print_uint(PRINT_JSON, "rtt", NULL, interval);
  1394. +
  1395. + if (raw)
  1396. + print_string(PRINT_FP, NULL, "raw ", NULL);
  1397. + print_bool(PRINT_JSON, "raw", NULL, raw);
  1398. +
  1399. + if (atm == CAKE_ATM_ATM)
  1400. + print_string(PRINT_ANY, "atm", "%s ", "atm");
  1401. + else if (atm == CAKE_ATM_PTM)
  1402. + print_string(PRINT_ANY, "atm", "%s ", "ptm");
  1403. + else if (!raw)
  1404. + print_string(PRINT_ANY, "atm", "%s ", "noatm");
  1405. +
  1406. + print_int(PRINT_ANY, "overhead", "overhead %d ", overhead);
  1407. +
  1408. + if (mpu)
  1409. + print_uint(PRINT_ANY, "mpu", "mpu %u ", mpu);
  1410. +
  1411. + if (memlimit) {
  1412. + print_uint(PRINT_JSON, "memlimit", NULL, memlimit);
  1413. + print_string(PRINT_FP, NULL, "memlimit %s",
  1414. + sprint_size(memlimit, b1));
  1415. + }
  1416. +
  1417. + return 0;
  1418. +}
  1419. +
  1420. +static void cake_print_json_tin(struct rtattr **tstat)
  1421. +{
  1422. +#define PRINT_TSTAT_JSON(type, name, attr) if (tstat[TCA_CAKE_TIN_STATS_ ## attr]) \
  1423. + print_u64(PRINT_JSON, name, NULL, \
  1424. + rta_getattr_ ## type((struct rtattr *) \
  1425. + tstat[TCA_CAKE_TIN_STATS_ ## attr]))
  1426. +
  1427. + open_json_object(NULL);
  1428. + PRINT_TSTAT_JSON(u64, "threshold_rate", THRESHOLD_RATE64);
  1429. + PRINT_TSTAT_JSON(u64, "sent_bytes", SENT_BYTES64);
  1430. + PRINT_TSTAT_JSON(u32, "backlog_bytes", BACKLOG_BYTES);
  1431. + PRINT_TSTAT_JSON(u32, "target_us", TARGET_US);
  1432. + PRINT_TSTAT_JSON(u32, "interval_us", INTERVAL_US);
  1433. + PRINT_TSTAT_JSON(u32, "peak_delay_us", PEAK_DELAY_US);
  1434. + PRINT_TSTAT_JSON(u32, "avg_delay_us", AVG_DELAY_US);
  1435. + PRINT_TSTAT_JSON(u32, "base_delay_us", BASE_DELAY_US);
  1436. + PRINT_TSTAT_JSON(u32, "sent_packets", SENT_PACKETS);
  1437. + PRINT_TSTAT_JSON(u32, "way_indirect_hits", WAY_INDIRECT_HITS);
  1438. + PRINT_TSTAT_JSON(u32, "way_misses", WAY_MISSES);
  1439. + PRINT_TSTAT_JSON(u32, "way_collisions", WAY_COLLISIONS);
  1440. + PRINT_TSTAT_JSON(u32, "drops", DROPPED_PACKETS);
  1441. + PRINT_TSTAT_JSON(u32, "ecn_mark", ECN_MARKED_PACKETS);
  1442. + PRINT_TSTAT_JSON(u32, "ack_drops", ACKS_DROPPED_PACKETS);
  1443. + PRINT_TSTAT_JSON(u32, "sparse_flows", SPARSE_FLOWS);
  1444. + PRINT_TSTAT_JSON(u32, "bulk_flows", BULK_FLOWS);
  1445. + PRINT_TSTAT_JSON(u32, "unresponsive_flows", UNRESPONSIVE_FLOWS);
  1446. + PRINT_TSTAT_JSON(u32, "max_pkt_len", MAX_SKBLEN);
  1447. + PRINT_TSTAT_JSON(u32, "flow_quantum", FLOW_QUANTUM);
  1448. + close_json_object();
  1449. +
  1450. +#undef PRINT_TSTAT_JSON
  1451. +}
  1452. +
  1453. +static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
  1454. + struct rtattr *xstats)
  1455. +{
  1456. + struct rtattr *st[TCA_CAKE_STATS_MAX + 1];
  1457. + SPRINT_BUF(b1);
  1458. + int i;
  1459. +
  1460. + if (xstats == NULL)
  1461. + return 0;
  1462. +
  1463. +#define GET_STAT_U32(attr) rta_getattr_u32(st[TCA_CAKE_STATS_ ## attr])
  1464. +#define GET_STAT_S32(attr) (*(__s32 *)RTA_DATA(st[TCA_CAKE_STATS_ ## attr]))
  1465. +#define GET_STAT_U64(attr) rta_getattr_u64(st[TCA_CAKE_STATS_ ## attr])
  1466. +
  1467. + parse_rtattr_nested(st, TCA_CAKE_STATS_MAX, xstats);
  1468. +
  1469. + if (st[TCA_CAKE_STATS_MEMORY_USED] &&
  1470. + st[TCA_CAKE_STATS_MEMORY_LIMIT]) {
  1471. + print_string(PRINT_FP, NULL, " memory used: %s",
  1472. + sprint_size(GET_STAT_U32(MEMORY_USED), b1));
  1473. +
  1474. + print_string(PRINT_FP, NULL, " of %s\n",
  1475. + sprint_size(GET_STAT_U32(MEMORY_LIMIT), b1));
  1476. +
  1477. + print_uint(PRINT_JSON, "memory_used", NULL,
  1478. + GET_STAT_U32(MEMORY_USED));
  1479. + print_uint(PRINT_JSON, "memory_limit", NULL,
  1480. + GET_STAT_U32(MEMORY_LIMIT));
  1481. + }
  1482. +
  1483. + if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) {
  1484. + print_string(PRINT_FP, NULL, " capacity estimate: %s\n",
  1485. + sprint_rate(GET_STAT_U64(CAPACITY_ESTIMATE64), b1));
  1486. + print_uint(PRINT_JSON, "capacity_estimate", NULL,
  1487. + GET_STAT_U64(CAPACITY_ESTIMATE64));
  1488. + }
  1489. +
  1490. + if (st[TCA_CAKE_STATS_MIN_NETLEN] &&
  1491. + st[TCA_CAKE_STATS_MAX_NETLEN]) {
  1492. + print_uint(PRINT_ANY, "min_network_size",
  1493. + " min/max network layer size: %12u",
  1494. + GET_STAT_U32(MIN_NETLEN));
  1495. + print_uint(PRINT_ANY, "max_network_size",
  1496. + " /%8u\n", GET_STAT_U32(MAX_NETLEN));
  1497. + }
  1498. +
  1499. + if (st[TCA_CAKE_STATS_MIN_ADJLEN] &&
  1500. + st[TCA_CAKE_STATS_MAX_ADJLEN]) {
  1501. + print_uint(PRINT_ANY, "min_adj_size",
  1502. + " min/max overhead-adjusted size: %8u",
  1503. + GET_STAT_U32(MIN_ADJLEN));
  1504. + print_uint(PRINT_ANY, "max_adj_size",
  1505. + " /%8u\n", GET_STAT_U32(MAX_ADJLEN));
  1506. + }
  1507. +
  1508. + if (st[TCA_CAKE_STATS_AVG_NETOFF])
  1509. + print_uint(PRINT_ANY, "avg_hdr_offset",
  1510. + " average network hdr offset: %12u\n\n",
  1511. + GET_STAT_U32(AVG_NETOFF));
  1512. +
  1513. + /* class stats */
  1514. + if (st[TCA_CAKE_STATS_DEFICIT])
  1515. + print_int(PRINT_ANY, "deficit", " deficit %u",
  1516. + GET_STAT_S32(DEFICIT));
  1517. + if (st[TCA_CAKE_STATS_COBALT_COUNT])
  1518. + print_uint(PRINT_ANY, "count", " count %u",
  1519. + GET_STAT_U32(COBALT_COUNT));
  1520. +
  1521. + if (st[TCA_CAKE_STATS_DROPPING] && GET_STAT_U32(DROPPING)) {
  1522. + print_bool(PRINT_ANY, "dropping", " dropping", true);
  1523. + if (st[TCA_CAKE_STATS_DROP_NEXT_US]) {
  1524. + int drop_next = GET_STAT_S32(DROP_NEXT_US);
  1525. +
  1526. + if (drop_next < 0) {
  1527. + print_string(PRINT_FP, NULL, " drop_next -%s",
  1528. + sprint_time(drop_next, b1));
  1529. + } else {
  1530. + print_uint(PRINT_JSON, "drop_next", NULL,
  1531. + drop_next);
  1532. + print_string(PRINT_FP, NULL, " drop_next %s",
  1533. + sprint_time(drop_next, b1));
  1534. + }
  1535. + }
  1536. + }
  1537. +
  1538. + if (st[TCA_CAKE_STATS_P_DROP]) {
  1539. + print_uint(PRINT_ANY, "blue_prob", " blue_prob %u",
  1540. + GET_STAT_U32(P_DROP));
  1541. + if (st[TCA_CAKE_STATS_BLUE_TIMER_US]) {
  1542. + int blue_timer = GET_STAT_S32(BLUE_TIMER_US);
  1543. +
  1544. + if (blue_timer < 0) {
  1545. + print_string(PRINT_FP, NULL, " blue_timer -%s",
  1546. + sprint_time(blue_timer, b1));
  1547. + } else {
  1548. + print_uint(PRINT_JSON, "blue_timer", NULL,
  1549. + blue_timer);
  1550. + print_string(PRINT_FP, NULL, " blue_timer %s",
  1551. + sprint_time(blue_timer, b1));
  1552. + }
  1553. + }
  1554. + }
  1555. +
  1556. +#undef GET_STAT_U32
  1557. +#undef GET_STAT_S32
  1558. +#undef GET_STAT_U64
  1559. +
  1560. + if (st[TCA_CAKE_STATS_TIN_STATS]) {
  1561. + struct rtattr *tstat[TC_CAKE_MAX_TINS][TCA_CAKE_TIN_STATS_MAX + 1];
  1562. + struct rtattr *tins[TC_CAKE_MAX_TINS + 1];
  1563. + int num_tins = 0;
  1564. +
  1565. + parse_rtattr_nested(tins, TC_CAKE_MAX_TINS,
  1566. + st[TCA_CAKE_STATS_TIN_STATS]);
  1567. +
  1568. + for (i = 1; i <= TC_CAKE_MAX_TINS && tins[i]; i++) {
  1569. + parse_rtattr_nested(tstat[i-1], TCA_CAKE_TIN_STATS_MAX,
  1570. + tins[i]);
  1571. + num_tins++;
  1572. + }
  1573. +
  1574. + if (!num_tins)
  1575. + return 0;
  1576. +
  1577. + if (is_json_context()) {
  1578. + open_json_array(PRINT_JSON, "tins");
  1579. + for (i = 0; i < num_tins; i++)
  1580. + cake_print_json_tin(tstat[i]);
  1581. + close_json_array(PRINT_JSON, NULL);
  1582. +
  1583. + return 0;
  1584. + }
  1585. +
  1586. +
  1587. + switch (num_tins) {
  1588. + case 3:
  1589. + fprintf(f, " Bulk Best Effort Voice\n");
  1590. + break;
  1591. +
  1592. + case 4:
  1593. + fprintf(f, " Bulk Best Effort Video Voice\n");
  1594. + break;
  1595. +
  1596. + default:
  1597. + fprintf(f, " ");
  1598. + for (i = 0; i < num_tins; i++)
  1599. + fprintf(f, " Tin %u", i);
  1600. + fprintf(f, "\n");
  1601. + };
  1602. +
  1603. +#define GET_TSTAT(i, attr) (tstat[i][TCA_CAKE_TIN_STATS_ ## attr])
  1604. +#define PRINT_TSTAT(name, attr, fmts, val) do { \
  1605. + if (GET_TSTAT(0, attr)) { \
  1606. + fprintf(f, name); \
  1607. + for (i = 0; i < num_tins; i++) \
  1608. + fprintf(f, " %12" fmts, val); \
  1609. + fprintf(f, "\n"); \
  1610. + } \
  1611. + } while (0)
  1612. +
  1613. +#define SPRINT_TSTAT(pfunc, type, name, attr) PRINT_TSTAT( \
  1614. + name, attr, "s", sprint_ ## pfunc( \
  1615. + rta_getattr_ ## type(GET_TSTAT(i, attr)), b1))
  1616. +
  1617. +#define PRINT_TSTAT_U32(name, attr) PRINT_TSTAT( \
  1618. + name, attr, "u", rta_getattr_u32(GET_TSTAT(i, attr)))
  1619. +
  1620. +#define PRINT_TSTAT_U64(name, attr) PRINT_TSTAT( \
  1621. + name, attr, "llu", rta_getattr_u64(GET_TSTAT(i, attr)))
  1622. +
  1623. + SPRINT_TSTAT(rate, u64, " thresh ", THRESHOLD_RATE64);
  1624. + SPRINT_TSTAT(time, u32, " target ", TARGET_US);
  1625. + SPRINT_TSTAT(time, u32, " interval", INTERVAL_US);
  1626. + SPRINT_TSTAT(time, u32, " pk_delay", PEAK_DELAY_US);
  1627. + SPRINT_TSTAT(time, u32, " av_delay", AVG_DELAY_US);
  1628. + SPRINT_TSTAT(time, u32, " sp_delay", BASE_DELAY_US);
  1629. + SPRINT_TSTAT(size, u32, " backlog ", BACKLOG_BYTES);
  1630. +
  1631. + PRINT_TSTAT_U32(" pkts ", SENT_PACKETS);
  1632. + PRINT_TSTAT_U64(" bytes ", SENT_BYTES64);
  1633. +
  1634. + PRINT_TSTAT_U32(" way_inds", WAY_INDIRECT_HITS);
  1635. + PRINT_TSTAT_U32(" way_miss", WAY_MISSES);
  1636. + PRINT_TSTAT_U32(" way_cols", WAY_COLLISIONS);
  1637. + PRINT_TSTAT_U32(" drops ", DROPPED_PACKETS);
  1638. + PRINT_TSTAT_U32(" marks ", ECN_MARKED_PACKETS);
  1639. + PRINT_TSTAT_U32(" ack_drop", ACKS_DROPPED_PACKETS);
  1640. + PRINT_TSTAT_U32(" sp_flows", SPARSE_FLOWS);
  1641. + PRINT_TSTAT_U32(" bk_flows", BULK_FLOWS);
  1642. + PRINT_TSTAT_U32(" un_flows", UNRESPONSIVE_FLOWS);
  1643. + PRINT_TSTAT_U32(" max_len ", MAX_SKBLEN);
  1644. + PRINT_TSTAT_U32(" quantum ", FLOW_QUANTUM);
  1645. +
  1646. +#undef GET_STAT
  1647. +#undef PRINT_TSTAT
  1648. +#undef SPRINT_TSTAT
  1649. +#undef PRINT_TSTAT_U32
  1650. +#undef PRINT_TSTAT_U64
  1651. + }
  1652. + return 0;
  1653. +}
  1654. +
  1655. +struct qdisc_util cake_qdisc_util = {
  1656. + .id = "cake",
  1657. + .parse_qopt = cake_parse_opt,
  1658. + .print_qopt = cake_print_opt,
  1659. + .print_xstats = cake_print_xstats,
  1660. +};