1 /*
2 * networkxml2firewalltest.c: Test iptables rule generation
3 *
4 * Copyright (C) 2014 Red Hat, Inc.
5 *
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.
10 *
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.
15 *
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/>.
19 *
20 */
21
22 #include <config.h>
23
24 #include "testutils.h"
25 #include "viralloc.h"
26
27 #if defined (__linux__)
28
29 # include <gio/gio.h>
30
31 # include "network/bridge_driver_platform.h"
32 # include "virbuffer.h"
33 # include "virmock.h"
34
35 # define LIBVIRT_VIRFIREWALLPRIV_H_ALLOW
36 # include "virfirewallpriv.h"
37
38 # define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
39 # include "vircommandpriv.h"
40
41 # define VIR_FROM_THIS VIR_FROM_NONE
42
43 # ifdef __linux__
44 # define RULESTYPE "linux"
45 # else
46 # error "test case not ported to this platform"
47 # endif
48
VIR_MOCK_WRAP_RET_ARGS(g_dbus_connection_call_sync,GVariant *,GDBusConnection *,connection,const gchar *,bus_name,const gchar *,object_path,const gchar *,interface_name,const gchar *,method_name,GVariant *,parameters,const GVariantType *,reply_type,GDBusCallFlags,flags,gint,timeout_msec,GCancellable *,cancellable,GError **,error)49 VIR_MOCK_WRAP_RET_ARGS(g_dbus_connection_call_sync,
50 GVariant *,
51 GDBusConnection *, connection,
52 const gchar *, bus_name,
53 const gchar *, object_path,
54 const gchar *, interface_name,
55 const gchar *, method_name,
56 GVariant *, parameters,
57 const GVariantType *, reply_type,
58 GDBusCallFlags, flags,
59 gint, timeout_msec,
60 GCancellable *, cancellable,
61 GError **, error)
62 {
63 if (parameters) {
64 g_variant_ref_sink(parameters);
65 g_variant_unref(parameters);
66 }
67
68 VIR_MOCK_REAL_INIT(g_dbus_connection_call_sync);
69
70 *error = g_dbus_error_new_for_dbus_error("org.freedesktop.error",
71 "dbus is disabled");
72
73 return NULL;
74 }
75
76 static void
testCommandDryRun(const char * const * args G_GNUC_UNUSED,const char * const * env G_GNUC_UNUSED,const char * input G_GNUC_UNUSED,char ** output,char ** error,int * status,void * opaque G_GNUC_UNUSED)77 testCommandDryRun(const char *const*args G_GNUC_UNUSED,
78 const char *const*env G_GNUC_UNUSED,
79 const char *input G_GNUC_UNUSED,
80 char **output,
81 char **error,
82 int *status,
83 void *opaque G_GNUC_UNUSED)
84 {
85 *status = 0;
86 *output = g_strdup("");
87 *error = g_strdup("");
88 }
89
testCompareXMLToArgvFiles(const char * xml,const char * cmdline,const char * baseargs)90 static int testCompareXMLToArgvFiles(const char *xml,
91 const char *cmdline,
92 const char *baseargs)
93 {
94 g_autofree char *actualargv = NULL;
95 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
96 virNetworkDef *def = NULL;
97 int ret = -1;
98 char *actual;
99 g_autoptr(virCommandDryRunToken) dryRunToken = virCommandDryRunTokenNew();
100
101 virCommandSetDryRun(dryRunToken, &buf, true, true, testCommandDryRun, NULL);
102
103 if (!(def = virNetworkDefParseFile(xml, NULL)))
104 goto cleanup;
105
106 if (networkAddFirewallRules(def) < 0)
107 goto cleanup;
108
109 actual = actualargv = virBufferContentAndReset(&buf);
110
111 /* The first network to be created populates the
112 * libvirt global chains. We must skip args for
113 * that if present
114 */
115 if (STRPREFIX(actual, baseargs))
116 actual += strlen(baseargs);
117
118 if (virTestCompareToFileFull(actual, cmdline, false) < 0)
119 goto cleanup;
120
121 ret = 0;
122
123 cleanup:
124 virNetworkDefFree(def);
125 return ret;
126 }
127
128 struct testInfo {
129 const char *name;
130 const char *baseargs;
131 };
132
133
134 static int
testCompareXMLToIPTablesHelper(const void * data)135 testCompareXMLToIPTablesHelper(const void *data)
136 {
137 int result = -1;
138 const struct testInfo *info = data;
139 g_autofree char *xml = NULL;
140 g_autofree char *args = NULL;
141
142 xml = g_strdup_printf("%s/networkxml2firewalldata/%s.xml",
143 abs_srcdir, info->name);
144 args = g_strdup_printf("%s/networkxml2firewalldata/%s-%s.args",
145 abs_srcdir, info->name, RULESTYPE);
146
147 result = testCompareXMLToArgvFiles(xml, args, info->baseargs);
148
149 return result;
150 }
151
152
153 static int
mymain(void)154 mymain(void)
155 {
156 int ret = 0;
157 g_autofree char *basefile = NULL;
158 g_autofree char *baseargs = NULL;
159
160 # define DO_TEST(name) \
161 do { \
162 struct testInfo info = { \
163 name, baseargs, \
164 }; \
165 if (virTestRun("Network XML-2-iptables " name, \
166 testCompareXMLToIPTablesHelper, &info) < 0) \
167 ret = -1; \
168 } while (0)
169
170 if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) {
171 return EXIT_FAILURE;
172 }
173
174 basefile = g_strdup_printf("%s/networkxml2firewalldata/base.args", abs_srcdir);
175
176 if (virFileReadAll(basefile, INT_MAX, &baseargs) < 0)
177 return EXIT_FAILURE;
178
179 DO_TEST("nat-default");
180 DO_TEST("nat-tftp");
181 DO_TEST("nat-many-ips");
182 DO_TEST("nat-no-dhcp");
183 DO_TEST("nat-ipv6");
184 DO_TEST("nat-ipv6-masquerade");
185 DO_TEST("route-default");
186
187 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
188 }
189
190 VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virgdbus"),
191 VIR_TEST_MOCK("virfirewall"))
192
193 #else /* ! defined (__linux__) */
194
195 int main(void)
196 {
197 return EXIT_AM_SKIP;
198 }
199
200 #endif /* ! defined (__linux__) */
201