docs: Reword virDomainGetEmulatorPinInfo description
[libvirt.git] / tests / nwfilterxml2firewalltest.c
blobb78b1b7947f53bba4e478d8c778b7040d8de19a7
1 /*
2 * nwfilterxml2firewalltest.c: Test iptables rule generation
4 * Copyright (C) 2014 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
22 #include <config.h>
24 #if defined (__linux__)
26 # include "testutils.h"
27 # include "nwfilter/nwfilter_ebiptables_driver.h"
28 # include "virbuffer.h"
30 # define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
31 # include "vircommandpriv.h"
33 # define VIR_FROM_THIS VIR_FROM_NONE
35 # ifdef __linux__
36 # define RULESTYPE "linux"
37 # else
38 # error "test case not ported to this platform"
39 # endif
41 typedef struct _virNWFilterInst virNWFilterInst;
42 struct _virNWFilterInst {
43 virNWFilterDef **filters;
44 size_t nfilters;
45 virNWFilterRuleInst **rules;
46 size_t nrules;
50 * Some sets of rules that will be common to all test files,
51 * so we don't bother including them in the test data files
52 * as that would just bloat them
55 static const char *commonRules[] = {
56 /* Dropping ebtables rules */
57 "ebtables \\\n--concurrent \\\n-t nat \\\n-D PREROUTING \\\n-i vnet0 \\\n-j libvirt-J-vnet0\n"
58 "ebtables \\\n--concurrent \\\n-t nat \\\n-D POSTROUTING \\\n-o vnet0 \\\n-j libvirt-P-vnet0\n"
59 "ebtables \\\n--concurrent \\\n-t nat \\\n-L libvirt-J-vnet0\n"
60 "ebtables \\\n--concurrent \\\n-t nat \\\n-L libvirt-P-vnet0\n"
61 "ebtables \\\n--concurrent \\\n-t nat \\\n-F libvirt-J-vnet0\n"
62 "ebtables \\\n--concurrent \\\n-t nat \\\n-X libvirt-J-vnet0\n"
63 "ebtables \\\n--concurrent \\\n-t nat \\\n-F libvirt-P-vnet0\n"
64 "ebtables \\\n--concurrent \\\n-t nat \\\n-X libvirt-P-vnet0\n",
66 /* Creating ebtables chains */
67 "ebtables \\\n--concurrent \\\n-t nat \\\n-N libvirt-J-vnet0\n"
68 "ebtables \\\n--concurrent \\\n-t nat \\\n-N libvirt-P-vnet0\n",
70 /* Dropping iptables rules */
71 "iptables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-is-bridged \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
72 "iptables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
73 "iptables \\\n-w \\\n-D libvirt-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g FJ-vnet0\n"
74 "iptables \\\n-w \\\n-D libvirt-host-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g HJ-vnet0\n"
75 "iptables \\\n-w \\\n-F FP-vnet0\n"
76 "iptables \\\n-w \\\n-X FP-vnet0\n"
77 "iptables \\\n-w \\\n-F FJ-vnet0\n"
78 "iptables \\\n-w \\\n-X FJ-vnet0\n"
79 "iptables \\\n-w \\\n-F HJ-vnet0\n"
80 "iptables \\\n-w \\\n-X HJ-vnet0\n",
82 /* Creating iptables chains */
83 "iptables \\\n-w \\\n-N libvirt-in\n"
84 "iptables \\\n-w \\\n-N libvirt-out\n"
85 "iptables \\\n-w \\\n-N libvirt-in-post\n"
86 "iptables \\\n-w \\\n-N libvirt-host-in\n"
87 "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in\n"
88 "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n"
89 "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n"
90 "iptables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n"
91 "iptables \\\n-w \\\n-I FORWARD 1 \\\n-j libvirt-in\n"
92 "iptables \\\n-w \\\n-I FORWARD 2 \\\n-j libvirt-out\n"
93 "iptables \\\n-w \\\n-I FORWARD 3 \\\n-j libvirt-in-post\n"
94 "iptables \\\n-w \\\n-I INPUT 1 \\\n-j libvirt-host-in\n"
95 "iptables \\\n-w \\\n-N FP-vnet0\n"
96 "iptables \\\n-w \\\n-N FJ-vnet0\n"
97 "iptables \\\n-w \\\n-N HJ-vnet0\n"
98 "iptables \\\n-w \\\n-A libvirt-out \\\n-m physdev \\\n--physdev-is-bridged \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
99 "iptables \\\n-w \\\n-A libvirt-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g FJ-vnet0\n"
100 "iptables \\\n-w \\\n-A libvirt-host-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g HJ-vnet0\n"
101 "iptables \\\n-w \\\n-D libvirt-in-post \\\n-m physdev \\\n--physdev-in vnet0 \\\n-j ACCEPT\n"
102 "iptables \\\n-w \\\n-A libvirt-in-post \\\n-m physdev \\\n--physdev-in vnet0 \\\n-j ACCEPT\n",
104 /* Dropping ip6tables rules */
105 "ip6tables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-is-bridged \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
106 "ip6tables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
107 "ip6tables \\\n-w \\\n-D libvirt-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g FJ-vnet0\n"
108 "ip6tables \\\n-w \\\n-D libvirt-host-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g HJ-vnet0\n"
109 "ip6tables \\\n-w \\\n-F FP-vnet0\n"
110 "ip6tables \\\n-w \\\n-X FP-vnet0\n"
111 "ip6tables \\\n-w \\\n-F FJ-vnet0\n"
112 "ip6tables \\\n-w \\\n-X FJ-vnet0\n"
113 "ip6tables \\\n-w \\\n-F HJ-vnet0\n"
114 "ip6tables \\\n-w \\\n-X HJ-vnet0\n",
116 /* Creating ip6tables chains */
117 "ip6tables \\\n-w \\\n-N libvirt-in\n"
118 "ip6tables \\\n-w \\\n-N libvirt-out\n"
119 "ip6tables \\\n-w \\\n-N libvirt-in-post\n"
120 "ip6tables \\\n-w \\\n-N libvirt-host-in\n"
121 "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in\n"
122 "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n"
123 "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n"
124 "ip6tables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n"
125 "ip6tables \\\n-w \\\n-I FORWARD 1 \\\n-j libvirt-in\n"
126 "ip6tables \\\n-w \\\n-I FORWARD 2 \\\n-j libvirt-out\n"
127 "ip6tables \\\n-w \\\n-I FORWARD 3 \\\n-j libvirt-in-post\n"
128 "ip6tables \\\n-w \\\n-I INPUT 1 \\\n-j libvirt-host-in\n"
129 "ip6tables \\\n-w \\\n-N FP-vnet0\n"
130 "ip6tables \\\n-w \\\n-N FJ-vnet0\n"
131 "ip6tables \\\n-w \\\n-N HJ-vnet0\n"
132 "ip6tables \\\n-w \\\n-A libvirt-out \\\n-m physdev \\\n--physdev-is-bridged \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n"
133 "ip6tables \\\n-w \\\n-A libvirt-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g FJ-vnet0\n"
134 "ip6tables \\\n-w \\\n-A libvirt-host-in \\\n-m physdev \\\n--physdev-in vnet0 \\\n-g HJ-vnet0\n"
135 "ip6tables \\\n-w \\\n-D libvirt-in-post \\\n-m physdev \\\n--physdev-in vnet0 \\\n-j ACCEPT\n"
136 "ip6tables \\\n-w \\\n-A libvirt-in-post \\\n-m physdev \\\n--physdev-in vnet0 \\\n-j ACCEPT\n",
138 /* Inserting ebtables rules */
139 "ebtables \\\n--concurrent \\\n-t nat \\\n-A PREROUTING \\\n-i vnet0 \\\n-j libvirt-J-vnet0\n"
140 "ebtables \\\n--concurrent \\\n-t nat \\\n-A POSTROUTING \\\n-o vnet0 \\\n-j libvirt-P-vnet0\n",
144 static GHashTable *
145 virNWFilterCreateVarsFrom(GHashTable *vars1,
146 GHashTable *vars2)
148 g_autoptr(GHashTable) res = virHashNew(virNWFilterVarValueHashFree);
150 if (virNWFilterHashTablePutAll(vars1, res) < 0)
151 return NULL;
153 if (virNWFilterHashTablePutAll(vars2, res) < 0)
154 return NULL;
156 return g_steal_pointer(&res);
160 static void
161 virNWFilterRuleInstFree(virNWFilterRuleInst *inst)
163 if (!inst)
164 return;
166 g_clear_pointer(&inst->vars, g_hash_table_unref);
167 g_free(inst);
171 static void
172 virNWFilterInstReset(virNWFilterInst *inst)
174 size_t i;
176 for (i = 0; i < inst->nfilters; i++)
177 virNWFilterDefFree(inst->filters[i]);
178 VIR_FREE(inst->filters);
179 inst->nfilters = 0;
181 for (i = 0; i < inst->nrules; i++)
182 virNWFilterRuleInstFree(inst->rules[i]);
183 VIR_FREE(inst->rules);
184 inst->nrules = 0;
188 static int
189 virNWFilterDefToInst(const char *xml,
190 GHashTable *vars,
191 virNWFilterInst *inst);
193 static int
194 virNWFilterRuleDefToRuleInst(virNWFilterDef *def,
195 virNWFilterRuleDef *rule,
196 GHashTable *vars,
197 virNWFilterInst *inst)
199 virNWFilterRuleInst *ruleinst;
200 int ret = -1;
202 ruleinst = g_new0(virNWFilterRuleInst, 1);
204 ruleinst->chainSuffix = def->chainsuffix;
205 ruleinst->chainPriority = def->chainPriority;
206 ruleinst->def = rule;
207 ruleinst->priority = rule->priority;
208 ruleinst->vars = virHashNew(virNWFilterVarValueHashFree);
210 if (virNWFilterHashTablePutAll(vars, ruleinst->vars) < 0)
211 goto cleanup;
213 VIR_APPEND_ELEMENT(inst->rules, inst->nrules, ruleinst);
215 ret = 0;
216 cleanup:
217 virNWFilterRuleInstFree(ruleinst);
218 return ret;
222 static int
223 virNWFilterIncludeDefToRuleInst(virNWFilterIncludeDef *inc,
224 GHashTable *vars,
225 virNWFilterInst *inst)
227 g_autoptr(GHashTable) tmpvars = NULL;
228 int ret = -1;
229 g_autofree char *xml = NULL;
231 xml = g_strdup_printf("%s/nwfilterxml2firewalldata/%s.xml", abs_srcdir,
232 inc->filterref);
234 /* create a temporary hashmap for depth-first tree traversal */
235 if (!(tmpvars = virNWFilterCreateVarsFrom(inc->params,
236 vars)))
237 goto cleanup;
239 if (virNWFilterDefToInst(xml,
240 tmpvars,
241 inst) < 0)
242 goto cleanup;
244 ret = 0;
245 cleanup:
246 if (ret < 0)
247 virNWFilterInstReset(inst);
248 return ret;
251 static int
252 virNWFilterDefToInst(const char *xml,
253 GHashTable *vars,
254 virNWFilterInst *inst)
256 size_t i;
257 int ret = -1;
258 virNWFilterDef *def = virNWFilterDefParse(NULL, xml, 0);
260 if (!def)
261 return -1;
263 VIR_APPEND_ELEMENT_COPY(inst->filters, inst->nfilters, def);
265 for (i = 0; i < def->nentries; i++) {
266 if (def->filterEntries[i]->rule) {
267 if (virNWFilterRuleDefToRuleInst(def,
268 def->filterEntries[i]->rule,
269 vars,
270 inst) < 0)
271 goto cleanup;
272 } else if (def->filterEntries[i]->include) {
273 if (virNWFilterIncludeDefToRuleInst(def->filterEntries[i]->include,
274 vars,
275 inst) < 0)
276 goto cleanup;
280 ret = 0;
281 cleanup:
282 if (ret < 0)
283 virNWFilterInstReset(inst);
284 return ret;
288 static void testRemoveCommonRules(char *rules)
290 size_t i;
291 char *offset = rules;
293 for (i = 0; i < G_N_ELEMENTS(commonRules); i++) {
294 char *tmp = strstr(offset, commonRules[i]);
295 size_t len = strlen(commonRules[i]);
296 if (tmp) {
297 memmove(tmp, tmp + len, (strlen(tmp) + 1) - len);
298 offset = tmp;
304 static int testSetOneParameter(GHashTable *vars,
305 const char *name,
306 const char *value)
308 virNWFilterVarValue *val;
310 if ((val = virHashLookup(vars, name)) == NULL) {
311 val = virNWFilterVarValueCreateSimpleCopyValue(value);
312 if (!val)
313 return -1;
314 if (virHashUpdateEntry(vars, name, val) < 0) {
315 virNWFilterVarValueFree(val);
316 return -1;
318 } else {
319 if (virNWFilterVarValueAddValueCopy(val, value) < 0)
320 return -1;
323 return 0;
326 static int testSetDefaultParameters(GHashTable *vars)
328 if (testSetOneParameter(vars, "IPSETNAME", "tck_test") < 0 ||
329 testSetOneParameter(vars, "A", "1.1.1.1") ||
330 testSetOneParameter(vars, "A", "2.2.2.2") ||
331 testSetOneParameter(vars, "A", "3.3.3.3") ||
332 testSetOneParameter(vars, "A", "3.3.3.3") ||
333 testSetOneParameter(vars, "B", "80") ||
334 testSetOneParameter(vars, "B", "90") ||
335 testSetOneParameter(vars, "B", "80") ||
336 testSetOneParameter(vars, "B", "80") ||
337 testSetOneParameter(vars, "C", "1080") ||
338 testSetOneParameter(vars, "C", "1090") ||
339 testSetOneParameter(vars, "C", "1100") ||
340 testSetOneParameter(vars, "C", "1110"))
341 return -1;
342 return 0;
345 static int testCompareXMLToArgvFiles(const char *xml,
346 const char *cmdline)
348 g_autofree char *actualargv = NULL;
349 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
350 g_autoptr(GHashTable) vars = virHashNew(virNWFilterVarValueHashFree);
351 virNWFilterInst inst = { 0 };
352 int ret = -1;
353 g_autoptr(virCommandDryRunToken) dryRunToken = virCommandDryRunTokenNew();
355 virCommandSetDryRun(dryRunToken, &buf, true, true, NULL, NULL);
357 if (testSetDefaultParameters(vars) < 0)
358 goto cleanup;
360 if (virNWFilterDefToInst(xml,
361 vars,
362 &inst) < 0)
363 goto cleanup;
365 if (ebiptables_driver.applyNewRules("vnet0", inst.rules, inst.nrules) < 0)
366 goto cleanup;
368 actualargv = virBufferContentAndReset(&buf);
370 testRemoveCommonRules(actualargv);
372 if (virTestCompareToFileFull(actualargv, cmdline, false) < 0)
373 goto cleanup;
375 ret = 0;
377 cleanup:
378 virNWFilterInstReset(&inst);
379 return ret;
382 struct testInfo {
383 const char *name;
387 static int
388 testCompareXMLToIPTablesHelper(const void *data)
390 int result = -1;
391 const struct testInfo *info = data;
392 g_autofree char *xml = NULL;
393 g_autofree char *args = NULL;
395 xml = g_strdup_printf("%s/nwfilterxml2firewalldata/%s.xml",
396 abs_srcdir, info->name);
397 args = g_strdup_printf("%s/nwfilterxml2firewalldata/%s-%s.args",
398 abs_srcdir, info->name, RULESTYPE);
400 result = testCompareXMLToArgvFiles(xml, args);
402 return result;
406 static int
407 mymain(void)
409 int ret = 0;
411 # define DO_TEST(name) \
412 do { \
413 static struct testInfo info = { \
414 name, \
415 }; \
416 if (virTestRun("NWFilter XML-2-firewall " name, \
417 testCompareXMLToIPTablesHelper, &info) < 0) \
418 ret = -1; \
419 } while (0)
421 DO_TEST("ah");
422 DO_TEST("ah-ipv6");
423 DO_TEST("all");
424 DO_TEST("all-ipv6");
425 DO_TEST("arp");
426 DO_TEST("comment");
427 DO_TEST("conntrack");
428 DO_TEST("esp");
429 DO_TEST("esp-ipv6");
430 DO_TEST("example-1");
431 DO_TEST("example-2");
432 DO_TEST("hex-data");
433 DO_TEST("icmp-direction2");
434 DO_TEST("icmp-direction3");
435 DO_TEST("icmp-direction");
436 DO_TEST("icmp");
437 DO_TEST("icmpv6");
438 DO_TEST("igmp");
439 DO_TEST("ip");
440 DO_TEST("ipset");
441 DO_TEST("ipt-no-macspoof");
442 DO_TEST("ipv6");
443 DO_TEST("iter1");
444 DO_TEST("iter2");
445 DO_TEST("iter3");
446 DO_TEST("mac");
447 DO_TEST("rarp");
448 DO_TEST("sctp");
449 DO_TEST("sctp-ipv6");
450 DO_TEST("stp");
451 DO_TEST("target2");
452 DO_TEST("target");
453 DO_TEST("tcp");
454 DO_TEST("tcp-ipv6");
455 DO_TEST("udp");
456 DO_TEST("udp-ipv6");
457 DO_TEST("udplite");
458 DO_TEST("udplite-ipv6");
459 DO_TEST("vlan");
461 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
464 VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virfirewall"))
466 #else /* ! defined (__linux__) */
468 int main(void)
470 return EXIT_AM_SKIP;
473 #endif /* ! defined (__linux__) */