951-add-upstream-cake-to-tc.patch 42 KB

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