Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : : #undef NDEBUG
19 : : #include "odp-util.h"
20 : : #include <stdio.h>
21 : : #include "openvswitch/dynamic-string.h"
22 : : #include "flow.h"
23 : : #include "openvswitch/match.h"
24 : : #include "openvswitch/ofpbuf.h"
25 : : #include "ovstest.h"
26 : : #include "util.h"
27 : : #include "openvswitch/ofp-parse.h"
28 : : #include "openvswitch/vlog.h"
29 : :
30 : : static int
31 : 2 : parse_keys(bool wc_keys)
32 : : {
33 : 2 : int exit_code = 0;
34 : : struct ds in;
35 : :
36 : 2 : ds_init(&in);
37 : 2 : vlog_set_levels_from_string_assert("odp_util:console:dbg");
38 [ + + ]: 363 : while (!ds_get_test_line(&in, stdin)) {
39 : : enum odp_key_fitness fitness;
40 : : struct ofpbuf odp_key;
41 : : struct ofpbuf odp_mask;
42 : : struct flow flow;
43 : : struct ds out;
44 : : int error;
45 : :
46 : : /* Convert string to OVS DP key. */
47 : 361 : ofpbuf_init(&odp_key, 0);
48 : 361 : ofpbuf_init(&odp_mask, 0);
49 : 361 : error = odp_flow_from_string(ds_cstr(&in), NULL,
50 : : &odp_key, &odp_mask);
51 [ - + ]: 361 : if (error) {
52 : 0 : printf("odp_flow_from_string: error\n");
53 : 0 : goto next;
54 : : }
55 : :
56 [ + + ]: 361 : if (!wc_keys) {
57 : 184 : struct odp_flow_key_parms odp_parms = {
58 : : .flow = &flow,
59 : : .support = {
60 : : .recirc = true,
61 : : .ct_state = true,
62 : : .ct_zone = true,
63 : : .ct_mark = true,
64 : : .ct_label = true,
65 : : },
66 : : };
67 : :
68 : : /* Convert odp_key to flow. */
69 : 184 : fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow);
70 [ + + - - : 184 : switch (fitness) {
- ]
71 : : case ODP_FIT_PERFECT:
72 : 170 : break;
73 : :
74 : : case ODP_FIT_TOO_LITTLE:
75 : 14 : printf("ODP_FIT_TOO_LITTLE: ");
76 : 14 : break;
77 : :
78 : : case ODP_FIT_TOO_MUCH:
79 : 0 : printf("ODP_FIT_TOO_MUCH: ");
80 : 0 : break;
81 : :
82 : : case ODP_FIT_ERROR:
83 : 0 : printf("odp_flow_key_to_flow: error\n");
84 : 0 : goto next;
85 : : }
86 : : /* Convert cls_rule back to odp_key. */
87 : 184 : ofpbuf_uninit(&odp_key);
88 : 184 : ofpbuf_init(&odp_key, 0);
89 : 184 : odp_flow_key_from_flow(&odp_parms, &odp_key);
90 : :
91 [ - + ]: 184 : if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) {
92 : 0 : printf ("too long: %"PRIu32" > %d\n",
93 : : odp_key.size, ODPUTIL_FLOW_KEY_BYTES);
94 : 184 : exit_code = 1;
95 : : }
96 : : }
97 : :
98 : : /* Convert odp_key to string. */
99 : 361 : ds_init(&out);
100 [ + + ]: 361 : if (wc_keys) {
101 : 177 : odp_flow_format(odp_key.data, odp_key.size,
102 : 354 : odp_mask.data, odp_mask.size, NULL, &out, false);
103 : : } else {
104 : 184 : odp_flow_key_format(odp_key.data, odp_key.size, &out);
105 : : }
106 : 361 : puts(ds_cstr(&out));
107 : 361 : ds_destroy(&out);
108 : :
109 : : next:
110 : 361 : ofpbuf_uninit(&odp_key);
111 : 361 : ofpbuf_uninit(&odp_mask);
112 : : }
113 : 2 : ds_destroy(&in);
114 : :
115 : 2 : return exit_code;
116 : : }
117 : :
118 : : static int
119 : 1 : parse_actions(void)
120 : : {
121 : : struct ds in;
122 : :
123 : 1 : ds_init(&in);
124 : 1 : vlog_set_levels_from_string_assert("odp_util:console:dbg");
125 [ + + ]: 87 : while (!ds_get_test_line(&in, stdin)) {
126 : : struct ofpbuf odp_actions;
127 : : struct ds out;
128 : : int error;
129 : :
130 : : /* Convert string to OVS DP actions. */
131 : 86 : ofpbuf_init(&odp_actions, 0);
132 : 86 : error = odp_actions_from_string(ds_cstr(&in), NULL, &odp_actions);
133 [ - + ]: 86 : if (error) {
134 : 0 : printf("odp_actions_from_string: error\n");
135 : 0 : goto next;
136 : : }
137 : :
138 : : /* Convert odp_actions back to string. */
139 : 86 : ds_init(&out);
140 : 86 : format_odp_actions(&out, odp_actions.data, odp_actions.size);
141 : 86 : puts(ds_cstr(&out));
142 : 86 : ds_destroy(&out);
143 : :
144 : : next:
145 : 86 : ofpbuf_uninit(&odp_actions);
146 : : }
147 : 1 : ds_destroy(&in);
148 : :
149 : 1 : return 0;
150 : : }
151 : :
152 : : static int
153 : 10 : parse_filter(char *filter_parse)
154 : : {
155 : : struct ds in;
156 : : struct flow flow_filter;
157 : : struct flow_wildcards wc_filter;
158 : 10 : char *error, *filter = NULL;
159 : :
160 : 10 : vlog_set_levels_from_string_assert("odp_util:console:dbg");
161 [ + - ][ + - ]: 10 : if (filter_parse && !strncmp(filter_parse, "filter=", 7)) {
162 : 10 : filter = xstrdup(filter_parse + 7);
163 : 10 : memset(&flow_filter, 0, sizeof(flow_filter));
164 : 10 : memset(&wc_filter, 0, sizeof(wc_filter));
165 : :
166 : 10 : error = parse_ofp_exact_flow(&flow_filter, &wc_filter, filter,
167 : : NULL);
168 [ - + ]: 10 : if (error) {
169 : 0 : ovs_fatal(0, "Failed to parse filter (%s)", error);
170 : : }
171 : : } else {
172 : 0 : ovs_fatal(0, "No filter to parse.");
173 : : }
174 : :
175 : 10 : ds_init(&in);
176 [ + + ]: 90 : while (!ds_get_test_line(&in, stdin)) {
177 : : struct ofpbuf odp_key;
178 : : struct ofpbuf odp_mask;
179 : : struct ds out;
180 : : int error;
181 : :
182 : : /* Convert string to OVS DP key. */
183 : 80 : ofpbuf_init(&odp_key, 0);
184 : 80 : ofpbuf_init(&odp_mask, 0);
185 : 80 : error = odp_flow_from_string(ds_cstr(&in), NULL,
186 : : &odp_key, &odp_mask);
187 [ - + ]: 80 : if (error) {
188 : 0 : printf("odp_flow_from_string: error\n");
189 : 0 : goto next;
190 : : }
191 : :
192 [ + - ]: 80 : if (filter) {
193 : : struct flow flow;
194 : : struct flow_wildcards wc;
195 : : struct match match, match_filter;
196 : : struct minimatch minimatch;
197 : :
198 : 80 : odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow);
199 : 80 : odp_flow_key_to_mask(odp_mask.data, odp_mask.size, odp_key.data,
200 : 80 : odp_key.size, &wc, &flow);
201 : 80 : match_init(&match, &flow, &wc);
202 : :
203 : 80 : match_init(&match_filter, &flow_filter, &wc);
204 : 80 : match_init(&match_filter, &match_filter.flow, &wc_filter);
205 : 80 : minimatch_init(&minimatch, &match_filter);
206 : :
207 [ + + ]: 80 : if (!minimatch_matches_flow(&minimatch, &match.flow)) {
208 : 66 : minimatch_destroy(&minimatch);
209 : 66 : goto next;
210 : : }
211 : 14 : minimatch_destroy(&minimatch);
212 : : }
213 : : /* Convert odp_key to string. */
214 : 14 : ds_init(&out);
215 : 14 : odp_flow_format(odp_key.data, odp_key.size,
216 : 28 : odp_mask.data, odp_mask.size, NULL, &out, false);
217 : 14 : puts(ds_cstr(&out));
218 : 14 : ds_destroy(&out);
219 : :
220 : : next:
221 : 80 : ofpbuf_uninit(&odp_key);
222 : 80 : ofpbuf_uninit(&odp_mask);
223 : : }
224 : 10 : ds_destroy(&in);
225 : :
226 : 10 : free(filter);
227 : 10 : return 0;
228 : : }
229 : :
230 : : static void
231 : 13 : test_odp_main(int argc, char *argv[])
232 : : {
233 : 13 : int exit_code = 0;
234 : :
235 : 13 : set_program_name(argv[0]);
236 [ + + ][ + + ]: 13 : if (argc == 2 &&!strcmp(argv[1], "parse-keys")) {
237 : 1 : exit_code =parse_keys(false);
238 [ + + ][ + + ]: 12 : } else if (argc == 2 &&!strcmp(argv[1], "parse-wc-keys")) {
239 : 1 : exit_code =parse_keys(true);
240 [ + + ][ + - ]: 11 : } else if (argc == 2 && !strcmp(argv[1], "parse-actions")) {
241 : 1 : exit_code = parse_actions();
242 [ + - ][ + - ]: 10 : } else if (argc == 3 && !strcmp(argv[1], "parse-filter")) {
243 : 10 : exit_code =parse_filter(argv[2]);
244 : : } else {
245 : 0 : ovs_fatal(0, "usage: %s parse-keys | parse-wc-keys | parse-actions", argv[0]);
246 : : }
247 : :
248 : 13 : exit(exit_code);
249 : : }
250 : :
251 : 1187 : OVSTEST_REGISTER("test-odp", test_odp_main);
|