Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2015-2018 Atomic Rules LLC
3 : : */
4 : :
5 : : #include <stdlib.h>
6 : : #include <unistd.h>
7 : :
8 : : #include <rte_string_fns.h>
9 : : #include <rte_malloc.h>
10 : :
11 : : #include "ark_pktchkr.h"
12 : : #include "ark_logs.h"
13 : :
14 : : static int set_arg(char *arg, char *val);
15 : : static int ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle);
16 : :
17 : : #define ARK_MAX_STR_LEN 64
18 : : union OPTV {
19 : : int INT;
20 : : int BOOL;
21 : : uint64_t LONG;
22 : : char STR[ARK_MAX_STR_LEN];
23 : : };
24 : :
25 : : enum OPTYPE {
26 : : OTINT,
27 : : OTLONG,
28 : : OTBOOL,
29 : : OTSTRING
30 : : };
31 : :
32 : : struct OPTIONS {
33 : : char opt[ARK_MAX_STR_LEN];
34 : : enum OPTYPE t;
35 : : union OPTV v;
36 : : };
37 : :
38 : : static struct OPTIONS toptions[] = {
39 : : {{"configure"}, OTBOOL, {1} },
40 : : {{"port"}, OTINT, {0} },
41 : : {{"mac-dump"}, OTBOOL, {0} },
42 : : {{"dg-mode"}, OTBOOL, {1} },
43 : : {{"run"}, OTBOOL, {0} },
44 : : {{"stop"}, OTBOOL, {0} },
45 : : {{"dump"}, OTBOOL, {0} },
46 : : {{"en_resync"}, OTBOOL, {0} },
47 : : {{"tuser_err_val"}, OTINT, {1} },
48 : : {{"gen_forever"}, OTBOOL, {0} },
49 : : {{"en_slaved_start"}, OTBOOL, {0} },
50 : : {{"vary_length"}, OTBOOL, {0} },
51 : : {{"incr_payload"}, OTINT, {0} },
52 : : {{"incr_first_byte"}, OTBOOL, {0} },
53 : : {{"ins_seq_num"}, OTBOOL, {0} },
54 : : {{"ins_time_stamp"}, OTBOOL, {1} },
55 : : {{"ins_udp_hdr"}, OTBOOL, {0} },
56 : : {{"num_pkts"}, OTLONG, .v.LONG = 10000000000000L},
57 : : {{"payload_byte"}, OTINT, {0x55} },
58 : : {{"pkt_spacing"}, OTINT, {60} },
59 : : {{"pkt_size_min"}, OTINT, {2005} },
60 : : {{"pkt_size_max"}, OTINT, {1514} },
61 : : {{"pkt_size_incr"}, OTINT, {1} },
62 : : {{"eth_type"}, OTINT, {0x0800} },
63 : : {{"src_mac_addr"}, OTLONG, .v.LONG = 0xdC3cF6425060L},
64 : : {{"dst_mac_addr"}, OTLONG, .v.LONG = 0x112233445566L},
65 : : {{"hdr_dW0"}, OTINT, {0x0016e319} },
66 : : {{"hdr_dW1"}, OTINT, {0x27150004} },
67 : : {{"hdr_dW2"}, OTINT, {0x76967bda} },
68 : : {{"hdr_dW3"}, OTINT, {0x08004500} },
69 : : {{"hdr_dW4"}, OTINT, {0x005276ed} },
70 : : {{"hdr_dW5"}, OTINT, {0x40004006} },
71 : : {{"hdr_dW6"}, OTINT, {0x56cfc0a8} },
72 : : {{"start_offset"}, OTINT, {0} },
73 : : {{"dst_ip"}, OTSTRING, .v.STR = "169.254.10.240"},
74 : : {{"dst_port"}, OTINT, {65536} },
75 : : {{"src_port"}, OTINT, {65536} },
76 : : };
77 : :
78 : : ark_pkt_chkr_t
79 : 0 : ark_pktchkr_init(void *addr, int ord, int l2_mode)
80 : : {
81 : : struct ark_pkt_chkr_inst *inst =
82 : 0 : rte_malloc("ark_pkt_chkr_inst",
83 : : sizeof(struct ark_pkt_chkr_inst), 0);
84 [ # # ]: 0 : if (inst == NULL) {
85 : 0 : ARK_PMD_LOG(ERR, "Failed to malloc ark_pkt_chkr_inst.\n");
86 : 0 : return inst;
87 : : }
88 : 0 : inst->sregs = (struct ark_pkt_chkr_stat_regs *)addr;
89 : 0 : inst->cregs =
90 : 0 : (struct ark_pkt_chkr_ctl_regs *)(((uint8_t *)addr) + 0x100);
91 : 0 : inst->ordinal = ord;
92 : 0 : inst->l2_mode = l2_mode;
93 : 0 : return inst;
94 : : }
95 : :
96 : : void
97 : 0 : ark_pktchkr_uninit(ark_pkt_chkr_t handle)
98 : : {
99 : 0 : rte_free(handle);
100 : 0 : }
101 : :
102 : : void
103 : 0 : ark_pktchkr_run(ark_pkt_chkr_t handle)
104 : : {
105 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
106 : :
107 : 0 : inst->sregs->pkt_start_stop = 0;
108 : 0 : inst->sregs->pkt_start_stop = 0x1;
109 : 0 : }
110 : :
111 : : int
112 : 0 : ark_pktchkr_stopped(ark_pkt_chkr_t handle)
113 : : {
114 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
115 : 0 : uint32_t r = inst->sregs->pkt_start_stop;
116 : :
117 [ # # # # ]: 0 : return (((r >> 16) & 1) == 1) || (r == 0);
118 : : }
119 : :
120 : : void
121 : 0 : ark_pktchkr_stop(ark_pkt_chkr_t handle)
122 : : {
123 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
124 : : int wait_cycle = 10;
125 : :
126 : 0 : inst->sregs->pkt_start_stop = 0;
127 [ # # # # ]: 0 : while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
128 : 0 : usleep(1000);
129 : 0 : wait_cycle--;
130 : 0 : ARK_PMD_LOG(DEBUG, "Waiting for pktchk %d to stop...\n",
131 : : inst->ordinal);
132 : : }
133 : 0 : ARK_PMD_LOG(DEBUG, "Pktchk %d stopped.\n", inst->ordinal);
134 : 0 : }
135 : :
136 : : int
137 : 0 : ark_pktchkr_is_running(ark_pkt_chkr_t handle)
138 : : {
139 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
140 : 0 : uint32_t r = inst->sregs->pkt_start_stop;
141 : :
142 : 0 : return ((r & 1) == 1);
143 : : }
144 : :
145 : : static void
146 : : ark_pktchkr_set_pkt_ctrl(ark_pkt_chkr_t handle,
147 : : uint32_t gen_forever,
148 : : uint32_t vary_length,
149 : : uint32_t incr_payload,
150 : : uint32_t incr_first_byte,
151 : : uint32_t ins_seq_num,
152 : : uint32_t ins_udp_hdr,
153 : : uint32_t en_resync,
154 : : uint32_t tuser_err_val,
155 : : uint32_t ins_time_stamp)
156 : : {
157 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
158 : 0 : uint32_t r = (tuser_err_val << 16) | (en_resync << 0);
159 : :
160 : 0 : inst->sregs->pkt_ctrl = r;
161 : 0 : if (!inst->l2_mode)
162 : : ins_udp_hdr = 0;
163 : 0 : r = ((gen_forever << 24) |
164 : 0 : (vary_length << 16) |
165 : 0 : (incr_payload << 12) |
166 : 0 : (incr_first_byte << 8) |
167 : 0 : (ins_time_stamp << 5) |
168 : 0 : (ins_seq_num << 4) |
169 : : ins_udp_hdr);
170 : 0 : inst->cregs->pkt_ctrl = r;
171 : 0 : }
172 : :
173 : : static
174 : : int
175 : : ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle)
176 : : {
177 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
178 : 0 : uint32_t r = inst->cregs->pkt_ctrl;
179 : :
180 : 0 : return (((r >> 24) & 1) == 1);
181 : : }
182 : :
183 : : int
184 : 0 : ark_pktchkr_wait_done(ark_pkt_chkr_t handle)
185 : : {
186 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
187 : :
188 [ # # ]: 0 : if (ark_pktchkr_is_gen_forever(handle)) {
189 : 0 : ARK_PMD_LOG(NOTICE, "Pktchk wait_done will not terminate"
190 : : " because gen_forever=1\n");
191 : 0 : return -1;
192 : : }
193 : : int wait_cycle = 10;
194 : :
195 [ # # # # ]: 0 : while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
196 : 0 : usleep(1000);
197 : 0 : wait_cycle--;
198 : 0 : ARK_PMD_LOG(DEBUG, "Waiting for packet checker %d's"
199 : : " internal pktgen to finish sending...\n",
200 : : inst->ordinal);
201 : 0 : ARK_PMD_LOG(DEBUG, "Pktchk %d's pktgen done.\n",
202 : : inst->ordinal);
203 : : }
204 : : return 0;
205 : : }
206 : :
207 : : int
208 : 0 : ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle)
209 : : {
210 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
211 : :
212 : 0 : return inst->cregs->pkts_sent;
213 : : }
214 : :
215 : : void
216 : 0 : ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b)
217 : : {
218 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
219 : :
220 : 0 : inst->cregs->pkt_payload = b;
221 : 0 : }
222 : :
223 : : void
224 : 0 : ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x)
225 : : {
226 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
227 : :
228 : 0 : inst->cregs->pkt_size_min = x;
229 : 0 : }
230 : :
231 : : void
232 : 0 : ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x)
233 : : {
234 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
235 : :
236 : 0 : inst->cregs->pkt_size_max = x;
237 : 0 : }
238 : :
239 : : void
240 : 0 : ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x)
241 : : {
242 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
243 : :
244 : 0 : inst->cregs->pkt_size_incr = x;
245 : 0 : }
246 : :
247 : : void
248 : 0 : ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x)
249 : : {
250 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
251 : :
252 : 0 : inst->cregs->num_pkts = x;
253 : 0 : }
254 : :
255 : : void
256 : 0 : ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
257 : : {
258 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
259 : :
260 : 0 : inst->cregs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;
261 : 0 : inst->cregs->src_mac_addr_l = mac_addr & 0xffffffff;
262 : 0 : }
263 : :
264 : : void
265 : 0 : ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
266 : : {
267 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
268 : :
269 : 0 : inst->cregs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;
270 : 0 : inst->cregs->dst_mac_addr_l = mac_addr & 0xffffffff;
271 : 0 : }
272 : :
273 : : void
274 : 0 : ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x)
275 : : {
276 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
277 : :
278 : 0 : inst->cregs->eth_type = x;
279 : 0 : }
280 : :
281 : : void
282 : 0 : ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr)
283 : : {
284 : : uint32_t i;
285 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
286 : :
287 [ # # ]: 0 : for (i = 0; i < 7; i++)
288 : 0 : inst->cregs->hdr_dw[i] = hdr[i];
289 : 0 : }
290 : :
291 : : void
292 : 0 : ark_pktchkr_dump_stats(ark_pkt_chkr_t handle)
293 : : {
294 : : struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
295 : :
296 : 0 : ARK_PMD_LOG(INFO, "pkts_rcvd = (%'u)\n",
297 : : inst->sregs->pkts_rcvd);
298 : 0 : ARK_PMD_LOG(INFO, "bytes_rcvd = (%'" PRIU64 ")\n",
299 : : inst->sregs->bytes_rcvd);
300 : 0 : ARK_PMD_LOG(INFO, "pkts_ok = (%'u)\n",
301 : : inst->sregs->pkts_ok);
302 : 0 : ARK_PMD_LOG(INFO, "pkts_mismatch = (%'u)\n",
303 : : inst->sregs->pkts_mismatch);
304 : 0 : ARK_PMD_LOG(INFO, "pkts_err = (%'u)\n",
305 : : inst->sregs->pkts_err);
306 : 0 : ARK_PMD_LOG(INFO, "first_mismatch = (%'u)\n",
307 : : inst->sregs->first_mismatch);
308 : 0 : ARK_PMD_LOG(INFO, "resync_events = (%'u)\n",
309 : : inst->sregs->resync_events);
310 : 0 : ARK_PMD_LOG(INFO, "pkts_missing = (%'u)\n",
311 : : inst->sregs->pkts_missing);
312 : 0 : ARK_PMD_LOG(INFO, "min_latency = (%'u)\n",
313 : : inst->sregs->min_latency);
314 : 0 : ARK_PMD_LOG(INFO, "max_latency = (%'u)\n",
315 : : inst->sregs->max_latency);
316 : 0 : }
317 : :
318 : : static struct OPTIONS *
319 : 0 : options(const char *id)
320 : : {
321 : : unsigned int i;
322 : :
323 [ # # ]: 0 : for (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {
324 [ # # ]: 0 : if (strcmp(id, toptions[i].opt) == 0)
325 : 0 : return &toptions[i];
326 : : }
327 : 0 : ARK_PMD_LOG(ERR,
328 : : "pktchkr: Could not find requested option!, option = %s\n",
329 : : id);
330 : 0 : return NULL;
331 : : }
332 : :
333 : : static int
334 : 0 : set_arg(char *arg, char *val)
335 : : {
336 : 0 : struct OPTIONS *o = options(arg);
337 : :
338 [ # # ]: 0 : if (o) {
339 [ # # # # ]: 0 : switch (o->t) {
340 : : case OTINT:
341 : : case OTBOOL:
342 : 0 : o->v.INT = atoi(val);
343 : 0 : break;
344 : : case OTLONG:
345 : 0 : o->v.INT = atoll(val);
346 : 0 : break;
347 : 0 : case OTSTRING:
348 : 0 : strlcpy(o->v.STR, val, ARK_MAX_STR_LEN);
349 : : break;
350 : : }
351 : 0 : return 1;
352 : : }
353 : : return 0;
354 : : }
355 : :
356 : : /******
357 : : * Arg format = "opt0=v,opt_n=v ..."
358 : : ******/
359 : : void
360 : 0 : ark_pktchkr_parse(char *args)
361 : : {
362 : : char *argv, *v;
363 : 0 : const char toks[] = "=\n\t\v\f \r";
364 : 0 : argv = strtok(args, toks);
365 : 0 : v = strtok(NULL, toks);
366 [ # # ]: 0 : while (argv && v) {
367 : 0 : set_arg(argv, v);
368 : 0 : argv = strtok(NULL, toks);
369 : 0 : v = strtok(NULL, toks);
370 : : }
371 : 0 : }
372 : :
373 : : static int32_t parse_ipv4_string(char const *ip_address);
374 : : static int32_t
375 : 0 : parse_ipv4_string(char const *ip_address)
376 : : {
377 : : unsigned int ip[4];
378 : :
379 [ # # ]: 0 : if (sscanf(ip_address, "%u.%u.%u.%u",
380 : : &ip[0], &ip[1], &ip[2], &ip[3]) != 4)
381 : : return 0;
382 : 0 : return ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;
383 : : }
384 : :
385 : : void
386 : 0 : ark_pktchkr_setup(ark_pkt_chkr_t handle)
387 : : {
388 : : uint32_t hdr[7];
389 : 0 : int32_t dst_ip = parse_ipv4_string(options("dst_ip")->v.STR);
390 : :
391 [ # # # # ]: 0 : if (!options("stop")->v.BOOL && options("configure")->v.BOOL) {
392 : 0 : ark_pktchkr_set_payload_byte(handle,
393 : 0 : options("payload_byte")->v.INT);
394 : 0 : ark_pktchkr_set_src_mac_addr(handle,
395 : 0 : options("src_mac_addr")->v.INT);
396 : 0 : ark_pktchkr_set_dst_mac_addr(handle,
397 : 0 : options("dst_mac_addr")->v.LONG);
398 : :
399 : 0 : ark_pktchkr_set_eth_type(handle,
400 : 0 : options("eth_type")->v.INT);
401 [ # # ]: 0 : if (options("dg-mode")->v.BOOL) {
402 : 0 : hdr[0] = options("hdr_dW0")->v.INT;
403 : 0 : hdr[1] = options("hdr_dW1")->v.INT;
404 : 0 : hdr[2] = options("hdr_dW2")->v.INT;
405 : 0 : hdr[3] = options("hdr_dW3")->v.INT;
406 : 0 : hdr[4] = options("hdr_dW4")->v.INT;
407 : 0 : hdr[5] = options("hdr_dW5")->v.INT;
408 : 0 : hdr[6] = options("hdr_dW6")->v.INT;
409 : : } else {
410 : 0 : hdr[0] = dst_ip;
411 : 0 : hdr[1] = options("dst_port")->v.INT;
412 : 0 : hdr[2] = options("src_port")->v.INT;
413 : 0 : hdr[3] = 0;
414 : 0 : hdr[4] = 0;
415 : 0 : hdr[5] = 0;
416 : 0 : hdr[6] = 0;
417 : : }
418 : 0 : ark_pktchkr_set_hdr_dW(handle, hdr);
419 : 0 : ark_pktchkr_set_num_pkts(handle,
420 : 0 : options("num_pkts")->v.INT);
421 : 0 : ark_pktchkr_set_pkt_size_min(handle,
422 : 0 : options("pkt_size_min")->v.INT);
423 : 0 : ark_pktchkr_set_pkt_size_max(handle,
424 : 0 : options("pkt_size_max")->v.INT);
425 : 0 : ark_pktchkr_set_pkt_size_incr(handle,
426 : 0 : options("pkt_size_incr")->v.INT);
427 : 0 : ark_pktchkr_set_pkt_ctrl(handle,
428 [ # # ]: 0 : options("gen_forever")->v.BOOL,
429 : 0 : options("vary_length")->v.BOOL,
430 : 0 : options("incr_payload")->v.BOOL,
431 : 0 : options("incr_first_byte")->v.BOOL,
432 : 0 : options("ins_seq_num")->v.INT,
433 : 0 : options("ins_udp_hdr")->v.BOOL,
434 : 0 : options("en_resync")->v.BOOL,
435 : 0 : options("tuser_err_val")->v.INT,
436 : 0 : options("ins_time_stamp")->v.INT);
437 : : }
438 : :
439 [ # # ]: 0 : if (options("stop")->v.BOOL)
440 : 0 : ark_pktchkr_stop(handle);
441 : :
442 [ # # ]: 0 : if (options("run")->v.BOOL) {
443 : 0 : ARK_PMD_LOG(DEBUG, "Starting packet checker on port %d\n",
444 : : options("port")->v.INT);
445 : 0 : ark_pktchkr_run(handle);
446 : : }
447 : 0 : }
|