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