|  | 
|  | 1 | +-- SPDX-License-Identifier: GPL-2.0 | 
|  | 2 | +-- Copyright (c) 2022 Freysteinn Alfredsson <[email protected]> | 
|  | 3 | + | 
|  | 4 | +--  Fair Queuing with Controlled Delay (FQ_CoDel) | 
|  | 5 | +config.bpf.file = "./sched_fq_codel.bpf.o" | 
|  | 6 | + | 
|  | 7 | + | 
|  | 8 | +-- Setup flows | 
|  | 9 | +-- We use this flow to test sparse flow handling | 
|  | 10 | +packet_sparse_flow_tester = Udp:new() | 
|  | 11 | +packet_sparse_flow_tester.udp.dest = 8000 | 
|  | 12 | + | 
|  | 13 | +-- The background stream flow increments the time bytes | 
|  | 14 | +-- so that we can test our sparse flow tester when time has passed | 
|  | 15 | +packet_flow_background_stream = Udp:new() | 
|  | 16 | +packet_flow_background_stream.udp.dest = 8001 | 
|  | 17 | +-- Make the packet the size of full a quantom (1522 - 62) | 
|  | 18 | +packet_flow_background_stream.udp.payload = create_payload(1460) | 
|  | 19 | + | 
|  | 20 | + | 
|  | 21 | +-- Test scheduler | 
|  | 22 | + | 
|  | 23 | +-- | 
|  | 24 | +-- 1. Sparse flow tests | 
|  | 25 | +-- | 
|  | 26 | +-- In our implementation of FQ-CoDel, the time_bytes variable is the only thing | 
|  | 27 | +-- that connects sparse flows. Therefore, we can test all possible scenarios | 
|  | 28 | +-- using only two flows. One background flow that we only use to advance time. | 
|  | 29 | +-- And the flow that we use for testing. | 
|  | 30 | + | 
|  | 31 | +function make_sparse(flow) | 
|  | 32 | +  -- The background flow needs two packets to be a stream: | 
|  | 33 | +  -- * The first packet will be sparse. | 
|  | 34 | +  -- * The second packet exceeds the sparse quantom. | 
|  | 35 | +  flow.udp.payload = create_payload(1460) | 
|  | 36 | +  enqueue(flow) -- Sparse | 
|  | 37 | +  enqueue(flow) -- Stream | 
|  | 38 | +  dequeue_cmp(flow) -- Dequeue sparse | 
|  | 39 | +  dequeue_cmp(flow) -- Dequeue sparse | 
|  | 40 | +  -- Note that the type_bytes has not advanced at this point but will after the | 
|  | 41 | +  -- next dequeued packet. | 
|  | 42 | +end | 
|  | 43 | + | 
|  | 44 | +-- 1.1 Test when a sparse flow ends while sparse | 
|  | 45 | +function fq_codel_sparse_test1() | 
|  | 46 | +  -- This test does the following: | 
|  | 47 | +  -- 1. Creates a sparse flow with a couple of packets. | 
|  | 48 | +  -- 2. Advance time_bytes and expire the sparse flow. | 
|  | 49 | +  -- 3. Creates a new sparse flow with a couple of packets. | 
|  | 50 | +  -- 4. Advance time_bytes and expire the new sparse flow. | 
|  | 51 | +  -- In steps two and four the test confirms that the sparse flows | 
|  | 52 | +  -- were still sparse. | 
|  | 53 | +  make_sparse(packet_flow_background_stream) | 
|  | 54 | + | 
|  | 55 | +  -- Prime the background stream so it can update the time_bytes variable later. | 
|  | 56 | +  enqueue(packet_flow_background_stream) -- Prime for updating time_bytes | 
|  | 57 | +  enqueue(packet_flow_background_stream) -- Make sure the flow is not recycled after update | 
|  | 58 | + | 
|  | 59 | +  -- Make the packet the size of half a quantom (1522/2 - 62) | 
|  | 60 | +  -- The flow will cease being a sparse flow after two packets. | 
|  | 61 | +  packet_sparse_flow_tester.udp.payload = create_payload(699) | 
|  | 62 | + | 
|  | 63 | +  -- The sparse flow gets a full quantom of packets. | 
|  | 64 | +  enqueue(packet_sparse_flow_tester) -- Sparse 1 | 
|  | 65 | +  enqueue(packet_sparse_flow_tester) -- Sparse 2 | 
|  | 66 | + | 
|  | 67 | +  -- Remove all sparse packets. | 
|  | 68 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue sparse | 
|  | 69 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue sparse | 
|  | 70 | + | 
|  | 71 | +  -- Advance time_bytes | 
|  | 72 | +  dequeue_cmp(packet_flow_background_stream) -- Advances time_bytes one quantom | 
|  | 73 | +  -- Our FQ-CoDel algorithm should have expired the sparse_flow_tester | 
|  | 74 | +  -- flow at this point, but not the background stream. | 
|  | 75 | + | 
|  | 76 | +  -- Test that the sparse_flow_tester is indeed expired. | 
|  | 77 | +  enqueue(packet_sparse_flow_tester) -- Add sparse packet with a higher priority | 
|  | 78 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue the sparse packet | 
|  | 79 | +  dequeue_cmp(packet_flow_background_stream) -- Advances time_bytes one quantom | 
|  | 80 | +  -- Our FQ-CoDel algorithm should have expired both the sparse_flow_tester | 
|  | 81 | +  -- flow and the background stream at this point. | 
|  | 82 | +end | 
|  | 83 | + | 
|  | 84 | +-- 1.2 Test a sparse flow when the time_bytes advances while the flow is sparse | 
|  | 85 | +function fq_codel_sparse_test2() | 
|  | 86 | +  -- This test does the following: | 
|  | 87 | +  -- 1. Creates a sparse flow with a couple of packets. | 
|  | 88 | +  -- 2. Advances time_bytes by a half a quantom | 
|  | 89 | +  -- 3. Adds a couple of packets to the sparse flow. | 
|  | 90 | +  -- In steps one and three the test confirms that the sparse flow | 
|  | 91 | +  -- is still sparse. | 
|  | 92 | +  make_sparse(packet_flow_background_stream) | 
|  | 93 | + | 
|  | 94 | +  -- Make the packet the size of half a quantom (1522/2 - 62) | 
|  | 95 | +  packet_flow_background_stream.udp.payload = create_payload(699) | 
|  | 96 | + | 
|  | 97 | +  -- Make each packet 50 bytes for our sparse flow | 
|  | 98 | +  packet_sparse_flow_tester.udp.payload = create_payload(38) | 
|  | 99 | + | 
|  | 100 | +  -- Keep in mind that the last background packet ends at a full quantom. Therefore, | 
|  | 101 | +  -- if we want to update the time_bytes by a half a quantom, we will need to enqueue | 
|  | 102 | +  -- and deqeueu a half a quantom packet. | 
|  | 103 | +  enqueue(packet_flow_background_stream) -- Used to advance time_bytes by half a quantom | 
|  | 104 | +  enqueue(packet_flow_background_stream) -- Used to advance time_bytes by half a quantom | 
|  | 105 | +  enqueue(packet_flow_background_stream) -- Make sure the flow is not recycled after update | 
|  | 106 | +  dequeue_cmp(packet_flow_background_stream) -- Advances time_bytes by a half a quantom | 
|  | 107 | + | 
|  | 108 | +  -- Confirm that the sparse flow has a higher priority than the background stream. | 
|  | 109 | +  enqueue(packet_sparse_flow_tester) -- Add a sparse packet | 
|  | 110 | +  enqueue(packet_sparse_flow_tester) -- Add a sparse packet | 
|  | 111 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue the sparse packet | 
|  | 112 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue the sparse packet | 
|  | 113 | + | 
|  | 114 | +  dequeue_cmp(packet_flow_background_stream) -- Advances time_bytes by a half a quantom | 
|  | 115 | + | 
|  | 116 | +  -- Confirm that the sparse flow has a higher priority than the stream. | 
|  | 117 | +  enqueue(packet_sparse_flow_tester) -- Add a sparse packet | 
|  | 118 | +  enqueue(packet_sparse_flow_tester) -- Add a sparse packet | 
|  | 119 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue the sparse packet | 
|  | 120 | +  dequeue_cmp(packet_sparse_flow_tester) -- Dequeue the sparse packet | 
|  | 121 | + | 
|  | 122 | +  -- Recycle both flows. | 
|  | 123 | +  dequeue_cmp(packet_flow_background_stream) -- Recycle both flows | 
|  | 124 | +end | 
|  | 125 | + | 
|  | 126 | +-- 1.3 Test a flow that becomes a stream. | 
|  | 127 | +function fq_codel_sparse_test3() | 
|  | 128 | +  -- This test does the following: | 
|  | 129 | +  -- 1. Creates a sparse flow and adds a full quantom to it. | 
|  | 130 | +  -- 2. Adds packets to the flow to make it a stream. | 
|  | 131 | +  -- 3. Advances time_bytes by a half a quantom. | 
|  | 132 | +  -- 4. Adds packets to the stream | 
|  | 133 | +  -- In steps two and four the test confirms that the flow is a stream. | 
|  | 134 | +  make_sparse(packet_flow_background_stream) | 
|  | 135 | + | 
|  | 136 | +  -- Make the packet the size of half a quantom (1522/2 - 62) | 
|  | 137 | +  packet_sparse_flow_tester.udp.payload = create_payload(699) | 
|  | 138 | + | 
|  | 139 | +  -- Make the packet the size of half a quantom (1522/2 - 62) | 
|  | 140 | +  packet_flow_background_stream.udp.payload = create_payload(699) | 
|  | 141 | + | 
|  | 142 | +  -- Keep in mind that the last background packet ends at a full quantom. Therefore, | 
|  | 143 | +  -- if we want to update the time_bytes by a half a quantom, we will need to enqueue | 
|  | 144 | +  -- and deqeueu a half a quantom packet. | 
|  | 145 | +  enqueue(packet_flow_background_stream) -- Used to advance time_bytes by half a quantom | 
|  | 146 | +  enqueue(packet_flow_background_stream) -- Used to advance time_bytes by half a quantom | 
|  | 147 | +  enqueue(packet_flow_background_stream) -- Make sure the flow is not recycled after update | 
|  | 148 | +  dequeue_cmp(packet_flow_background_stream) -- Advances time_bytes by a half a quantom | 
|  | 149 | + | 
|  | 150 | +  -- Make the sparse_flow_tester flow a stream. | 
|  | 151 | +  enqueue(packet_sparse_flow_tester) -- Add sparse packet | 
|  | 152 | +  enqueue(packet_sparse_flow_tester) -- Add sparse packet | 
|  | 153 | +  enqueue(packet_sparse_flow_tester) -- Make the flow a stream | 
|  | 154 | +  enqueue(packet_sparse_flow_tester) -- Add stream packet | 
|  | 155 | + | 
|  | 156 | +  --  Dequeue the sparse flow packets. | 
|  | 157 | +  dequeue_cmp(packet_sparse_flow_tester) | 
|  | 158 | +  dequeue_cmp(packet_sparse_flow_tester) | 
|  | 159 | + | 
|  | 160 | +  -- Confirm that both flows are streams with equal priority. | 
|  | 161 | +  dequeue_cmp(packet_sparse_flow_tester) | 
|  | 162 | +  dequeue_cmp(packet_flow_background_stream) | 
|  | 163 | +  dequeue_cmp(packet_sparse_flow_tester) | 
|  | 164 | +  dequeue_cmp(packet_flow_background_stream) | 
|  | 165 | +end | 
|  | 166 | + | 
|  | 167 | +-- Run tests | 
|  | 168 | +fq_codel_sparse_test1() | 
|  | 169 | +fq_codel_sparse_test2() | 
|  | 170 | +fq_codel_sparse_test3() | 
0 commit comments