]>
Commit | Line | Data |
---|---|---|
ea43b024 BS |
1 | #include <config.h> |
2 | #include "fuzzer.h" | |
3 | #undef NDEBUG | |
4 | #include "odp-util.h" | |
5 | #include <stdio.h> | |
6 | #include "openvswitch/dynamic-string.h" | |
7 | #include "flow.h" | |
8 | #include "openvswitch/match.h" | |
9 | #include "openvswitch/ofpbuf.h" | |
10 | #include "util.h" | |
11 | #include "openvswitch/ofp-flow.h" | |
12 | #include "openvswitch/vlog.h" | |
13 | ||
14 | static int | |
15 | parse_keys(bool wc_keys, const char *in) | |
16 | { | |
17 | int exit_code = 0; | |
18 | ||
19 | enum odp_key_fitness fitness; | |
20 | struct ofpbuf odp_key; | |
21 | struct ofpbuf odp_mask; | |
22 | struct flow flow; | |
23 | struct ds out; | |
24 | int error; | |
25 | ||
26 | /* Convert string to OVS DP key. */ | |
27 | ofpbuf_init(&odp_key, 0); | |
28 | ofpbuf_init(&odp_mask, 0); | |
29 | error = odp_flow_from_string(in, NULL, | |
abe3cf8f | 30 | &odp_key, &odp_mask, NULL); |
ea43b024 BS |
31 | if (error) { |
32 | printf("odp_flow_from_string: error\n"); | |
33 | goto next; | |
34 | } | |
35 | ||
36 | if (!wc_keys) { | |
37 | struct odp_flow_key_parms odp_parms = { | |
38 | .flow = &flow, | |
39 | .support = { | |
40 | .recirc = true, | |
41 | .ct_state = true, | |
42 | .ct_zone = true, | |
43 | .ct_mark = true, | |
44 | .ct_label = true, | |
45 | .max_vlan_headers = SIZE_MAX, | |
46 | }, | |
47 | }; | |
48 | ||
49 | /* Convert odp_key to flow. */ | |
abe3cf8f YS |
50 | fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, |
51 | &flow, NULL); | |
ea43b024 BS |
52 | switch (fitness) { |
53 | case ODP_FIT_PERFECT: | |
54 | break; | |
55 | ||
56 | case ODP_FIT_TOO_LITTLE: | |
57 | printf("ODP_FIT_TOO_LITTLE: "); | |
58 | break; | |
59 | ||
60 | case ODP_FIT_TOO_MUCH: | |
61 | printf("ODP_FIT_TOO_MUCH: "); | |
62 | break; | |
63 | ||
64 | case ODP_FIT_ERROR: | |
65 | printf("odp_flow_key_to_flow: error\n"); | |
66 | goto next; | |
67 | } | |
68 | /* Convert cls_rule back to odp_key. */ | |
69 | ofpbuf_uninit(&odp_key); | |
70 | ofpbuf_init(&odp_key, 0); | |
71 | odp_flow_key_from_flow(&odp_parms, &odp_key); | |
72 | ||
73 | if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) { | |
74 | printf ("too long: %"PRIu32" > %d\n", | |
75 | odp_key.size, ODPUTIL_FLOW_KEY_BYTES); | |
76 | exit_code = 1; | |
77 | } | |
78 | } | |
79 | ||
80 | /* Convert odp_key to string. */ | |
81 | ds_init(&out); | |
82 | if (wc_keys) { | |
83 | odp_flow_format(odp_key.data, odp_key.size, | |
84 | odp_mask.data, odp_mask.size, NULL, &out, false); | |
85 | } else { | |
86 | odp_flow_key_format(odp_key.data, odp_key.size, &out); | |
87 | } | |
88 | puts(ds_cstr(&out)); | |
89 | ds_destroy(&out); | |
90 | ||
91 | next: | |
92 | ofpbuf_uninit(&odp_key); | |
93 | ofpbuf_uninit(&odp_mask); | |
94 | ||
95 | return exit_code; | |
96 | } | |
97 | ||
98 | static int | |
99 | parse_actions(const char *in) | |
100 | { | |
101 | struct ofpbuf odp_actions; | |
102 | struct ds out; | |
103 | int error; | |
104 | ||
105 | /* Convert string to OVS DP actions. */ | |
106 | ofpbuf_init(&odp_actions, 0); | |
107 | error = odp_actions_from_string(in, NULL, &odp_actions); | |
108 | if (error) { | |
109 | printf("odp_actions_from_string: error\n"); | |
110 | goto next; | |
111 | } | |
112 | ||
113 | /* Convert odp_actions back to string. */ | |
114 | ds_init(&out); | |
115 | format_odp_actions(&out, odp_actions.data, odp_actions.size, NULL); | |
116 | puts(ds_cstr(&out)); | |
117 | ds_destroy(&out); | |
118 | ||
119 | next: | |
120 | ofpbuf_uninit(&odp_actions); | |
121 | return 0; | |
122 | } | |
123 | ||
124 | int | |
125 | LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | |
126 | { | |
127 | /* Bail out if we cannot construct at least a 1 char string. */ | |
128 | const char *input = (const char *) data; | |
937cdd85 BS |
129 | if (size < 2 || input[size - 1] != '\0' || strchr(input, '\n') || |
130 | strlen(input) != size - 1) { | |
ea43b024 BS |
131 | return 0; |
132 | } | |
133 | ||
134 | /* Disable logging to avoid write to disk. */ | |
135 | static bool isInit = false; | |
136 | if (!isInit) { | |
137 | vlog_set_verbosity("off"); | |
138 | isInit = true; | |
139 | } | |
140 | ||
141 | /* Parse keys and wc keys. */ | |
142 | parse_keys(false, input); | |
143 | parse_keys(true, input); | |
144 | ||
145 | /* Parse actions. */ | |
146 | parse_actions(input); | |
147 | ||
148 | return 0; | |
149 | } |