strongswan: add forecast plugin
[feed/packages.git] / net / strongswan / patches / 110-connmark-Fix-alignment-when-adding-rules.patch
1 From a4d7f5ee6f36decdcd18d70078e1f0a847fe9b24 Mon Sep 17 00:00:00 2001
2 From: Tobias Brunner <tobias@strongswan.org>
3 Date: Mon, 30 Nov 2015 16:04:35 +0100
4 Subject: [PATCH 1/2] connmark: Fix alignment when adding rules
5
6 The structs that make up a message sent to the kernel have all to be
7 aligned with XT_ALIGN. That was not necessarily the case when
8 initializing the complete message as struct.
9
10 #1212
11 ---
12 src/libcharon/plugins/connmark/connmark_listener.c | 332 +++++++++++----------
13 1 file changed, 172 insertions(+), 160 deletions(-)
14
15 diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c
16 index 23df690..cd53701 100644
17 --- a/src/libcharon/plugins/connmark/connmark_listener.c
18 +++ b/src/libcharon/plugins/connmark/connmark_listener.c
19 @@ -1,4 +1,7 @@
20 /*
21 + * Copyright (C) 2015 Tobias Brunner
22 + * Hochschule fuer Technik Rapperswil
23 + *
24 * Copyright (C) 2014 Martin Willi
25 * Copyright (C) 2014 revosec AG
26 *
27 @@ -25,6 +28,14 @@
28 #include <linux/netfilter/xt_policy.h>
29 #include <linux/netfilter/xt_CONNMARK.h>
30
31 +/**
32 + * Add a struct at the current position in the buffer
33 + */
34 +#define ADD_STRUCT(pos, st, ...) ({\
35 + typeof(pos) _cur = pos; pos += XT_ALIGN(sizeof(st));\
36 + *(st*)_cur = (st){ __VA_ARGS__ };\
37 + (st*)_cur;\
38 +})
39
40 typedef struct private_connmark_listener_t private_connmark_listener_t;
41
42 @@ -108,54 +119,54 @@ static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
43 u_int mark, u_int32_t spi,
44 host_t *dst, host_t *src)
45 {
46 - struct {
47 - struct ipt_entry e;
48 - struct ipt_entry_match m;
49 - struct xt_udp udp;
50 - struct ipt_entry_target t;
51 - struct xt_mark_tginfo2 tm;
52 - } ipt = {
53 - .e = {
54 - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
55 - sizeof(ipt.udp)),
56 - .next_offset = sizeof(ipt),
57 - .ip = {
58 - .proto = IPPROTO_UDP,
59 - },
60 + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) +
61 + XT_ALIGN(sizeof(struct xt_udp));
62 + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size;
63 + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) +
64 + XT_ALIGN(sizeof(struct xt_mark_tginfo2));
65 + u_int16_t entry_size = target_offset + target_size;
66 + u_char ipt[entry_size], *pos = ipt;
67 + struct ipt_entry *e;
68 +
69 + memset(ipt, 0, sizeof(ipt));
70 + e = ADD_STRUCT(pos, struct ipt_entry,
71 + .target_offset = target_offset,
72 + .next_offset = entry_size,
73 + .ip = {
74 + .proto = IPPROTO_UDP,
75 },
76 - .m = {
77 - .u = {
78 - .user = {
79 - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)),
80 - .name = "udp",
81 - },
82 + );
83 + if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) ||
84 + !host2in(src, &e->ip.src, &e->ip.smsk))
85 + {
86 + return FALSE;
87 + }
88 + ADD_STRUCT(pos, struct ipt_entry_match,
89 + .u = {
90 + .user = {
91 + .match_size = match_size,
92 + .name = "udp",
93 },
94 },
95 - .udp = {
96 - .spts = { src->get_port(src), src->get_port(src) },
97 - .dpts = { dst->get_port(dst), dst->get_port(dst) },
98 - },
99 - .t = {
100 - .u = {
101 - .user = {
102 - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
103 - .name = "MARK",
104 - .revision = 2,
105 - },
106 + );
107 + ADD_STRUCT(pos, struct xt_udp,
108 + .spts = { src->get_port(src), src->get_port(src) },
109 + .dpts = { dst->get_port(dst), dst->get_port(dst) },
110 + );
111 + ADD_STRUCT(pos, struct ipt_entry_target,
112 + .u = {
113 + .user = {
114 + .target_size = target_size,
115 + .name = "MARK",
116 + .revision = 2,
117 },
118 },
119 - .tm = {
120 - .mark = mark,
121 - .mask = ~0,
122 - },
123 - };
124 -
125 - if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
126 - !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
127 - {
128 - return FALSE;
129 - }
130 - return manage_rule(ipth, "PREROUTING", add, &ipt.e);
131 + );
132 + ADD_STRUCT(pos, struct xt_mark_tginfo2,
133 + .mark = mark,
134 + .mask = ~0,
135 + );
136 + return manage_rule(ipth, "PREROUTING", add, e);
137 }
138
139 /**
140 @@ -166,53 +177,53 @@ static bool manage_pre_esp(private_connmark_listener_t *this,
141 u_int mark, u_int32_t spi,
142 host_t *dst, host_t *src)
143 {
144 - struct {
145 - struct ipt_entry e;
146 - struct ipt_entry_match m;
147 - struct xt_esp esp;
148 - struct ipt_entry_target t;
149 - struct xt_mark_tginfo2 tm;
150 - } ipt = {
151 - .e = {
152 - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
153 - sizeof(ipt.esp)),
154 - .next_offset = sizeof(ipt),
155 - .ip = {
156 - .proto = IPPROTO_ESP,
157 - },
158 + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) +
159 + XT_ALIGN(sizeof(struct xt_esp));
160 + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size;
161 + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) +
162 + XT_ALIGN(sizeof(struct xt_mark_tginfo2));
163 + u_int16_t entry_size = target_offset + target_size;
164 + u_char ipt[entry_size], *pos = ipt;
165 + struct ipt_entry *e;
166 +
167 + memset(ipt, 0, sizeof(ipt));
168 + e = ADD_STRUCT(pos, struct ipt_entry,
169 + .target_offset = target_offset,
170 + .next_offset = entry_size,
171 + .ip = {
172 + .proto = IPPROTO_ESP,
173 },
174 - .m = {
175 - .u = {
176 - .user = {
177 - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)),
178 - .name = "esp",
179 - },
180 + );
181 + if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) ||
182 + !host2in(src, &e->ip.src, &e->ip.smsk))
183 + {
184 + return FALSE;
185 + }
186 + ADD_STRUCT(pos, struct ipt_entry_match,
187 + .u = {
188 + .user = {
189 + .match_size = match_size,
190 + .name = "esp",
191 },
192 },
193 - .esp = {
194 - .spis = { htonl(spi), htonl(spi) },
195 - },
196 - .t = {
197 - .u = {
198 - .user = {
199 - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
200 - .name = "MARK",
201 - .revision = 2,
202 - },
203 + );
204 + ADD_STRUCT(pos, struct xt_esp,
205 + .spis = { htonl(spi), htonl(spi) },
206 + );
207 + ADD_STRUCT(pos, struct ipt_entry_target,
208 + .u = {
209 + .user = {
210 + .target_size = target_size,
211 + .name = "MARK",
212 + .revision = 2,
213 },
214 },
215 - .tm = {
216 - .mark = mark,
217 - .mask = ~0,
218 - },
219 - };
220 -
221 - if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
222 - !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
223 - {
224 - return FALSE;
225 - }
226 - return manage_rule(ipth, "PREROUTING", add, &ipt.e);
227 + );
228 + ADD_STRUCT(pos, struct xt_mark_tginfo2,
229 + .mark = mark,
230 + .mask = ~0,
231 + );
232 + return manage_rule(ipth, "PREROUTING", add, e);
233 }
234
235 /**
236 @@ -238,59 +249,59 @@ static bool manage_in(private_connmark_listener_t *this,
237 u_int mark, u_int32_t spi,
238 traffic_selector_t *dst, traffic_selector_t *src)
239 {
240 - struct {
241 - struct ipt_entry e;
242 - struct ipt_entry_match m;
243 - struct xt_policy_info p;
244 - struct ipt_entry_target t;
245 - struct xt_connmark_tginfo1 cm;
246 - } ipt = {
247 - .e = {
248 - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
249 - sizeof(ipt.p)),
250 - .next_offset = sizeof(ipt),
251 - },
252 - .m = {
253 - .u = {
254 - .user = {
255 - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.p)),
256 - .name = "policy",
257 - },
258 + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) +
259 + XT_ALIGN(sizeof(struct xt_policy_info));
260 + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size;
261 + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) +
262 + XT_ALIGN(sizeof(struct xt_connmark_tginfo1));
263 + u_int16_t entry_size = target_offset + target_size;
264 + u_char ipt[entry_size], *pos = ipt;
265 + struct ipt_entry *e;
266 +
267 + memset(ipt, 0, sizeof(ipt));
268 + e = ADD_STRUCT(pos, struct ipt_entry,
269 + .target_offset = target_offset,
270 + .next_offset = entry_size,
271 + );
272 + if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) ||
273 + !ts2in(src, &e->ip.src, &e->ip.smsk))
274 + {
275 + return FALSE;
276 + }
277 + ADD_STRUCT(pos, struct ipt_entry_match,
278 + .u = {
279 + .user = {
280 + .match_size = match_size,
281 + .name = "policy",
282 },
283 },
284 - .p = {
285 - .pol = {
286 - {
287 - .spi = spi,
288 - .match.spi = 1,
289 - },
290 + );
291 + ADD_STRUCT(pos, struct xt_policy_info,
292 + .pol = {
293 + {
294 + .spi = spi,
295 + .match.spi = 1,
296 },
297 - .len = 1,
298 - .flags = XT_POLICY_MATCH_IN,
299 },
300 - .t = {
301 - .u = {
302 - .user = {
303 - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)),
304 - .name = "CONNMARK",
305 - .revision = 1,
306 - },
307 + .len = 1,
308 + .flags = XT_POLICY_MATCH_IN,
309 + );
310 + ADD_STRUCT(pos, struct ipt_entry_target,
311 + .u = {
312 + .user = {
313 + .target_size = target_size,
314 + .name = "CONNMARK",
315 + .revision = 1,
316 },
317 },
318 - .cm = {
319 - .ctmark = mark,
320 - .ctmask = ~0,
321 - .nfmask = ~0,
322 - .mode = XT_CONNMARK_SET,
323 - },
324 - };
325 -
326 - if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
327 - !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
328 - {
329 - return FALSE;
330 - }
331 - return manage_rule(ipth, "INPUT", add, &ipt.e);
332 + );
333 + ADD_STRUCT(pos, struct xt_connmark_tginfo1,
334 + .ctmark = mark,
335 + .ctmask = ~0,
336 + .nfmask = ~0,
337 + .mode = XT_CONNMARK_SET,
338 + );
339 + return manage_rule(ipth, "INPUT", add, e);
340 }
341
342 /**
343 @@ -300,37 +311,38 @@ static bool manage_out(private_connmark_listener_t *this,
344 struct iptc_handle *ipth, bool add,
345 traffic_selector_t *dst, traffic_selector_t *src)
346 {
347 - struct {
348 - struct ipt_entry e;
349 - struct ipt_entry_target t;
350 - struct xt_connmark_tginfo1 cm;
351 - } ipt = {
352 - .e = {
353 - .target_offset = XT_ALIGN(sizeof(ipt.e)),
354 - .next_offset = sizeof(ipt),
355 - },
356 - .t = {
357 - .u = {
358 - .user = {
359 - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)),
360 - .name = "CONNMARK",
361 - .revision = 1,
362 - },
363 - },
364 - },
365 - .cm = {
366 - .ctmask = ~0,
367 - .nfmask = ~0,
368 - .mode = XT_CONNMARK_RESTORE,
369 - },
370 - };
371 -
372 - if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
373 - !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
374 + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry));
375 + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) +
376 + XT_ALIGN(sizeof(struct xt_connmark_tginfo1));
377 + u_int16_t entry_size = target_offset + target_size;
378 + u_char ipt[entry_size], *pos = ipt;
379 + struct ipt_entry *e;
380 +
381 + memset(ipt, 0, sizeof(ipt));
382 + e = ADD_STRUCT(pos, struct ipt_entry,
383 + .target_offset = target_offset,
384 + .next_offset = entry_size,
385 + );
386 + if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) ||
387 + !ts2in(src, &e->ip.src, &e->ip.smsk))
388 {
389 return FALSE;
390 }
391 - return manage_rule(ipth, "OUTPUT", add, &ipt.e);
392 + ADD_STRUCT(pos, struct ipt_entry_target,
393 + .u = {
394 + .user = {
395 + .target_size = target_size,
396 + .name = "CONNMARK",
397 + .revision = 1,
398 + },
399 + },
400 + );
401 + ADD_STRUCT(pos, struct xt_connmark_tginfo1,
402 + .ctmask = ~0,
403 + .nfmask = ~0,
404 + .mode = XT_CONNMARK_RESTORE,
405 + );
406 + return manage_rule(ipth, "OUTPUT", add, e);
407 }
408
409 /**
410 --
411 2.4.10