1 /*
2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #include "internal/internal.h"
11 
copy_attr_orig_ipv4_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)12 static void copy_attr_orig_ipv4_src(struct nf_conntrack *dest,
13 				    const struct nf_conntrack *orig)
14 {
15 	dest->head.orig.src.v4 = orig->head.orig.src.v4;
16 }
17 
copy_attr_orig_ipv4_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)18 static void copy_attr_orig_ipv4_dst(struct nf_conntrack *dest,
19 				    const struct nf_conntrack *orig)
20 {
21 	dest->head.orig.dst.v4 = orig->head.orig.dst.v4;
22 }
23 
copy_attr_repl_ipv4_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)24 static void copy_attr_repl_ipv4_src(struct nf_conntrack *dest,
25 				    const struct nf_conntrack *orig)
26 {
27 	dest->repl.src.v4 = orig->repl.src.v4;
28 }
29 
copy_attr_repl_ipv4_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)30 static void copy_attr_repl_ipv4_dst(struct nf_conntrack *dest,
31 				    const struct nf_conntrack *orig)
32 {
33 	dest->repl.dst.v4 = orig->repl.dst.v4;
34 }
35 
copy_attr_orig_ipv6_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)36 static void copy_attr_orig_ipv6_src(struct nf_conntrack *dest,
37 				    const struct nf_conntrack *orig)
38 {
39 	memcpy(&dest->head.orig.src,
40 	       &orig->head.orig.src,
41 	       sizeof(union __nfct_address));
42 }
43 
copy_attr_orig_ipv6_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)44 static void copy_attr_orig_ipv6_dst(struct nf_conntrack *dest,
45 				    const struct nf_conntrack *orig)
46 {
47 	memcpy(&dest->head.orig.dst,
48 	       &orig->head.orig.dst,
49 	       sizeof(union __nfct_address));
50 }
51 
copy_attr_repl_ipv6_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)52 static void copy_attr_repl_ipv6_src(struct nf_conntrack *dest,
53 				    const struct nf_conntrack *orig)
54 {
55 	memcpy(&dest->repl.src,
56 	       &orig->repl.src,
57 	       sizeof(union __nfct_address));
58 }
59 
copy_attr_repl_ipv6_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)60 static void copy_attr_repl_ipv6_dst(struct nf_conntrack *dest,
61 				    const struct nf_conntrack *orig)
62 {
63 	memcpy(&dest->repl.dst,
64 	       &orig->repl.dst,
65 	       sizeof(union __nfct_address));
66 }
67 
copy_attr_orig_port_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)68 static void copy_attr_orig_port_src(struct nf_conntrack *dest,
69 				    const struct nf_conntrack *orig)
70 {
71 	dest->head.orig.l4src.all = orig->head.orig.l4src.all;
72 }
73 
copy_attr_orig_port_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)74 static void copy_attr_orig_port_dst(struct nf_conntrack *dest,
75 				    const struct nf_conntrack *orig)
76 {
77 	dest->head.orig.l4dst.all = orig->head.orig.l4dst.all;
78 }
79 
copy_attr_repl_port_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)80 static void copy_attr_repl_port_src(struct nf_conntrack *dest,
81 				    const struct nf_conntrack *orig)
82 {
83 	dest->repl.l4src.all = orig->repl.l4src.all;
84 }
85 
copy_attr_repl_port_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)86 static void copy_attr_repl_port_dst(struct nf_conntrack *dest,
87 				    const struct nf_conntrack *orig)
88 {
89 	dest->repl.l4dst.all = orig->repl.l4dst.all;
90 }
91 
copy_attr_orig_zone(struct nf_conntrack * dest,const struct nf_conntrack * orig)92 static void copy_attr_orig_zone(struct nf_conntrack *dest,
93 				const struct nf_conntrack *orig)
94 {
95 	dest->head.orig.zone = orig->head.orig.zone;
96 }
97 
copy_attr_repl_zone(struct nf_conntrack * dest,const struct nf_conntrack * orig)98 static void copy_attr_repl_zone(struct nf_conntrack *dest,
99 				const struct nf_conntrack *orig)
100 {
101 	dest->repl.zone = orig->repl.zone;
102 }
103 
copy_attr_icmp_type(struct nf_conntrack * dest,const struct nf_conntrack * orig)104 static void copy_attr_icmp_type(struct nf_conntrack *dest,
105 				const struct nf_conntrack *orig)
106 {
107 	dest->head.orig.l4dst.icmp.type =
108 		orig->head.orig.l4dst.icmp.type;
109 
110 }
111 
copy_attr_icmp_code(struct nf_conntrack * dest,const struct nf_conntrack * orig)112 static void copy_attr_icmp_code(struct nf_conntrack *dest,
113 				const struct nf_conntrack *orig)
114 {
115 	dest->head.orig.l4dst.icmp.code =
116 		orig->head.orig.l4dst.icmp.code;
117 
118 }
119 
copy_attr_icmp_id(struct nf_conntrack * dest,const struct nf_conntrack * orig)120 static void copy_attr_icmp_id(struct nf_conntrack *dest,
121 			      const struct nf_conntrack *orig)
122 {
123 	dest->head.orig.l4src.icmp.id =
124 		orig->head.orig.l4src.icmp.id;
125 }
126 
copy_attr_orig_l3proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)127 static void copy_attr_orig_l3proto(struct nf_conntrack *dest,
128 				   const struct nf_conntrack *orig)
129 {
130 	dest->head.orig.l3protonum = orig->head.orig.l3protonum;
131 }
132 
copy_attr_repl_l3proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)133 static void copy_attr_repl_l3proto(struct nf_conntrack *dest,
134 				   const struct nf_conntrack *orig)
135 {
136 	dest->repl.l3protonum = orig->repl.l3protonum;
137 }
138 
copy_attr_orig_l4proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)139 static void copy_attr_orig_l4proto(struct nf_conntrack *dest,
140 				   const struct nf_conntrack *orig)
141 {
142 	dest->head.orig.protonum = orig->head.orig.protonum;
143 }
144 
copy_attr_repl_l4proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)145 static void copy_attr_repl_l4proto(struct nf_conntrack *dest,
146 				   const struct nf_conntrack *orig)
147 {
148 	dest->repl.protonum = orig->repl.protonum;
149 }
150 
copy_attr_master_ipv4_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)151 static void copy_attr_master_ipv4_src(struct nf_conntrack *dest,
152 				      const struct nf_conntrack *orig)
153 {
154 	dest->master.src.v4 = orig->master.src.v4;
155 }
156 
copy_attr_master_ipv4_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)157 static void copy_attr_master_ipv4_dst(struct nf_conntrack *dest,
158 				      const struct nf_conntrack *orig)
159 {
160 	dest->master.dst.v4 = orig->master.dst.v4;
161 }
162 
copy_attr_master_ipv6_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)163 static void copy_attr_master_ipv6_src(struct nf_conntrack *dest,
164 				      const struct nf_conntrack *orig)
165 {
166 	memcpy(&dest->master.src, &orig->master.src,
167 	       sizeof(union __nfct_address));
168 }
169 
copy_attr_master_ipv6_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)170 static void copy_attr_master_ipv6_dst(struct nf_conntrack *dest,
171 				      const struct nf_conntrack *orig)
172 {
173 	memcpy(&dest->master.dst, &orig->master.dst,
174 	       sizeof(union __nfct_address));
175 }
176 
copy_attr_master_port_src(struct nf_conntrack * dest,const struct nf_conntrack * orig)177 static void copy_attr_master_port_src(struct nf_conntrack *dest,
178 				      const struct nf_conntrack *orig)
179 {
180 	dest->master.l4src.all = orig->master.l4src.all;
181 }
182 
copy_attr_master_port_dst(struct nf_conntrack * dest,const struct nf_conntrack * orig)183 static void copy_attr_master_port_dst(struct nf_conntrack *dest,
184 				      const struct nf_conntrack *orig)
185 {
186 	dest->master.l4dst.all = orig->master.l4dst.all;
187 }
188 
copy_attr_master_l3proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)189 static void copy_attr_master_l3proto(struct nf_conntrack *dest,
190 				     const struct nf_conntrack *orig)
191 {
192 	dest->master.l3protonum = orig->master.l3protonum;
193 }
194 
copy_attr_master_l4proto(struct nf_conntrack * dest,const struct nf_conntrack * orig)195 static void copy_attr_master_l4proto(struct nf_conntrack *dest,
196 				     const struct nf_conntrack *orig)
197 {
198 	dest->master.protonum = orig->master.protonum;
199 }
200 
copy_attr_tcp_state(struct nf_conntrack * dest,const struct nf_conntrack * orig)201 static void copy_attr_tcp_state(struct nf_conntrack *dest,
202 				const struct nf_conntrack *orig)
203 {
204 	dest->protoinfo.tcp.state = orig->protoinfo.tcp.state;
205 }
206 
copy_attr_tcp_flags_orig(struct nf_conntrack * dest,const struct nf_conntrack * orig)207 static void copy_attr_tcp_flags_orig(struct nf_conntrack *dest,
208 				     const struct nf_conntrack *orig)
209 {
210 	dest->protoinfo.tcp.flags[__DIR_ORIG].value =
211 		orig->protoinfo.tcp.flags[__DIR_ORIG].value;
212 }
213 
copy_attr_tcp_flags_repl(struct nf_conntrack * dest,const struct nf_conntrack * orig)214 static void copy_attr_tcp_flags_repl(struct nf_conntrack *dest,
215 				     const struct nf_conntrack *orig)
216 {
217 	dest->protoinfo.tcp.flags[__DIR_REPL].value =
218 		orig->protoinfo.tcp.flags[__DIR_REPL].value;
219 }
220 
copy_attr_tcp_mask_orig(struct nf_conntrack * dest,const struct nf_conntrack * orig)221 static void copy_attr_tcp_mask_orig(struct nf_conntrack *dest,
222 				    const struct nf_conntrack *orig)
223 {
224 	dest->protoinfo.tcp.flags[__DIR_ORIG].mask =
225 		orig->protoinfo.tcp.flags[__DIR_ORIG].mask;
226 }
227 
copy_attr_tcp_mask_repl(struct nf_conntrack * dest,const struct nf_conntrack * orig)228 static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest,
229 				    const struct nf_conntrack *orig)
230 {
231 	dest->protoinfo.tcp.flags[__DIR_REPL].mask =
232 		orig->protoinfo.tcp.flags[__DIR_REPL].mask;
233 }
234 
copy_attr_tcp_wscale_orig(struct nf_conntrack * dest,const struct nf_conntrack * orig)235 static void copy_attr_tcp_wscale_orig(struct nf_conntrack *dest,
236 				      const struct nf_conntrack *orig)
237 {
238 	dest->protoinfo.tcp.wscale[__DIR_ORIG] =
239 		orig->protoinfo.tcp.wscale[__DIR_ORIG];
240 }
241 
copy_attr_tcp_wscale_repl(struct nf_conntrack * dest,const struct nf_conntrack * orig)242 static void copy_attr_tcp_wscale_repl(struct nf_conntrack *dest,
243 				      const struct nf_conntrack *orig)
244 {
245 	dest->protoinfo.tcp.wscale[__DIR_REPL] =
246 		orig->protoinfo.tcp.wscale[__DIR_REPL];
247 }
248 
copy_attr_sctp_state(struct nf_conntrack * dest,const struct nf_conntrack * orig)249 static void copy_attr_sctp_state(struct nf_conntrack *dest,
250 				 const struct nf_conntrack *orig)
251 {
252 	dest->protoinfo.sctp.state = orig->protoinfo.sctp.state;
253 }
254 
copy_attr_sctp_vtag_orig(struct nf_conntrack * dest,const struct nf_conntrack * orig)255 static void copy_attr_sctp_vtag_orig(struct nf_conntrack *dest,
256 				     const struct nf_conntrack *orig)
257 {
258 	dest->protoinfo.sctp.vtag[__DIR_ORIG] =
259 		orig->protoinfo.sctp.vtag[__DIR_ORIG];
260 }
261 
copy_attr_sctp_vtag_repl(struct nf_conntrack * dest,const struct nf_conntrack * orig)262 static void copy_attr_sctp_vtag_repl(struct nf_conntrack *dest,
263 				     const struct nf_conntrack *orig)
264 {
265 	dest->protoinfo.sctp.vtag[__DIR_REPL] =
266 		orig->protoinfo.sctp.vtag[__DIR_REPL];
267 }
268 
copy_attr_dccp_state(struct nf_conntrack * dest,const struct nf_conntrack * orig)269 static void copy_attr_dccp_state(struct nf_conntrack *dest,
270 				 const struct nf_conntrack *orig)
271 {
272 	dest->protoinfo.dccp.state = orig->protoinfo.dccp.state;
273 }
274 
copy_attr_dccp_role(struct nf_conntrack * dest,const struct nf_conntrack * orig)275 static void copy_attr_dccp_role(struct nf_conntrack *dest,
276 				const struct nf_conntrack *orig)
277 {
278 	dest->protoinfo.dccp.role = orig->protoinfo.dccp.role;
279 }
280 
copy_attr_dccp_handshake_seq(struct nf_conntrack * dest,const struct nf_conntrack * orig)281 static void copy_attr_dccp_handshake_seq(struct nf_conntrack *dest,
282 					 const struct nf_conntrack *orig)
283 {
284 	dest->protoinfo.dccp.handshake_seq = orig->protoinfo.dccp.handshake_seq;
285 }
286 
copy_attr_snat_ipv4(struct nf_conntrack * dest,const struct nf_conntrack * orig)287 static void copy_attr_snat_ipv4(struct nf_conntrack *dest,
288 				const struct nf_conntrack *orig)
289 {
290 	dest->snat.min_ip.v4 = orig->snat.min_ip.v4;
291 }
292 
copy_attr_dnat_ipv4(struct nf_conntrack * dest,const struct nf_conntrack * orig)293 static void copy_attr_dnat_ipv4(struct nf_conntrack *dest,
294 				const struct nf_conntrack *orig)
295 {
296 	dest->dnat.min_ip.v4 = orig->dnat.min_ip.v4;
297 }
298 
copy_attr_snat_ipv6(struct nf_conntrack * dest,const struct nf_conntrack * orig)299 static void copy_attr_snat_ipv6(struct nf_conntrack *dest,
300 				const struct nf_conntrack *orig)
301 {
302 	memcpy(&dest->snat.min_ip.v6, &orig->snat.min_ip.v6,
303 	       sizeof(struct in6_addr));
304 }
305 
copy_attr_dnat_ipv6(struct nf_conntrack * dest,const struct nf_conntrack * orig)306 static void copy_attr_dnat_ipv6(struct nf_conntrack *dest,
307 				const struct nf_conntrack *orig)
308 {
309 	memcpy(&dest->dnat.min_ip.v6, &orig->dnat.min_ip.v6,
310 	       sizeof(struct in6_addr));
311 }
312 
copy_attr_snat_port(struct nf_conntrack * dest,const struct nf_conntrack * orig)313 static void copy_attr_snat_port(struct nf_conntrack *dest,
314 				const struct nf_conntrack *orig)
315 {
316 	dest->snat.l4min.all = orig->snat.l4min.all;
317 }
318 
copy_attr_dnat_port(struct nf_conntrack * dest,const struct nf_conntrack * orig)319 static void copy_attr_dnat_port(struct nf_conntrack *dest,
320 				const struct nf_conntrack *orig)
321 {
322 	dest->dnat.l4min.all = orig->dnat.l4min.all;
323 }
324 
copy_attr_timeout(struct nf_conntrack * dest,const struct nf_conntrack * orig)325 static void copy_attr_timeout(struct nf_conntrack *dest,
326 			      const struct nf_conntrack *orig)
327 {
328 	dest->timeout = orig->timeout;
329 }
330 
copy_attr_mark(struct nf_conntrack * dest,const struct nf_conntrack * orig)331 static void copy_attr_mark(struct nf_conntrack *dest,
332 			   const struct nf_conntrack *orig)
333 {
334 	dest->mark = orig->mark;
335 }
336 
copy_attr_secmark(struct nf_conntrack * dest,const struct nf_conntrack * orig)337 static void copy_attr_secmark(struct nf_conntrack *dest,
338 			      const struct nf_conntrack *orig)
339 {
340 	dest->secmark = orig->secmark;
341 }
342 
copy_attr_orig_counter_packets(struct nf_conntrack * dest,const struct nf_conntrack * orig)343 static void copy_attr_orig_counter_packets(struct nf_conntrack *dest,
344 					   const struct nf_conntrack *orig)
345 {
346 	dest->counters[__DIR_ORIG].packets = orig->counters[__DIR_ORIG].packets;
347 }
348 
copy_attr_repl_counter_packets(struct nf_conntrack * dest,const struct nf_conntrack * orig)349 static void copy_attr_repl_counter_packets(struct nf_conntrack *dest,
350 					   const struct nf_conntrack *orig)
351 {
352 	dest->counters[__DIR_REPL].packets = orig->counters[__DIR_REPL].packets;
353 }
354 
copy_attr_orig_counter_bytes(struct nf_conntrack * dest,const struct nf_conntrack * orig)355 static void copy_attr_orig_counter_bytes(struct nf_conntrack *dest,
356 					 const struct nf_conntrack *orig)
357 {
358 	dest->counters[__DIR_ORIG].bytes = orig->counters[__DIR_ORIG].bytes;
359 }
360 
copy_attr_repl_counter_bytes(struct nf_conntrack * dest,const struct nf_conntrack * orig)361 static void copy_attr_repl_counter_bytes(struct nf_conntrack *dest,
362 					 const struct nf_conntrack *orig)
363 {
364 	dest->counters[__DIR_REPL].bytes = orig->counters[__DIR_REPL].bytes;
365 }
366 
copy_attr_status(struct nf_conntrack * dest,const struct nf_conntrack * orig)367 static void copy_attr_status(struct nf_conntrack *dest,
368 			     const struct nf_conntrack *orig)
369 {
370 	dest->status = orig->status;
371 }
372 
copy_attr_use(struct nf_conntrack * dest,const struct nf_conntrack * orig)373 static void copy_attr_use(struct nf_conntrack *dest,
374 			  const struct nf_conntrack *orig)
375 {
376 	dest->use = orig->use;
377 }
378 
copy_attr_id(struct nf_conntrack * dest,const struct nf_conntrack * orig)379 static void copy_attr_id(struct nf_conntrack *dest,
380 			 const struct nf_conntrack *orig)
381 {
382 	dest->id = orig->id;
383 }
384 
copy_attr_orig_cor_pos(struct nf_conntrack * dest,const struct nf_conntrack * orig)385 static void copy_attr_orig_cor_pos(struct nf_conntrack *dest,
386 				   const struct nf_conntrack *orig)
387 {
388 	dest->natseq[__DIR_ORIG].correction_pos =
389 		orig->natseq[__DIR_ORIG].correction_pos;
390 }
391 
copy_attr_orig_off_bfr(struct nf_conntrack * dest,const struct nf_conntrack * orig)392 static void copy_attr_orig_off_bfr(struct nf_conntrack *dest,
393 				   const struct nf_conntrack *orig)
394 {
395 	dest->natseq[__DIR_ORIG].offset_before =
396 		orig->natseq[__DIR_ORIG].offset_before;
397 }
398 
copy_attr_orig_off_aft(struct nf_conntrack * dest,const struct nf_conntrack * orig)399 static void copy_attr_orig_off_aft(struct nf_conntrack *dest,
400 				   const struct nf_conntrack *orig)
401 {
402 	dest->natseq[__DIR_ORIG].offset_after =
403 		orig->natseq[__DIR_ORIG].offset_after;
404 }
405 
copy_attr_repl_cor_pos(struct nf_conntrack * dest,const struct nf_conntrack * orig)406 static void copy_attr_repl_cor_pos(struct nf_conntrack *dest,
407 				   const struct nf_conntrack *orig)
408 {
409 	dest->natseq[__DIR_REPL].correction_pos =
410 		orig->natseq[__DIR_REPL].correction_pos;
411 }
412 
copy_attr_repl_off_bfr(struct nf_conntrack * dest,const struct nf_conntrack * orig)413 static void copy_attr_repl_off_bfr(struct nf_conntrack *dest,
414 				   const struct nf_conntrack *orig)
415 {
416 	dest->natseq[__DIR_REPL].offset_before =
417 		orig->natseq[__DIR_REPL].offset_before;
418 }
419 
copy_attr_repl_off_aft(struct nf_conntrack * dest,const struct nf_conntrack * orig)420 static void copy_attr_repl_off_aft(struct nf_conntrack *dest,
421 				   const struct nf_conntrack *orig)
422 {
423 	dest->natseq[__DIR_REPL].offset_after =
424 		orig->natseq[__DIR_REPL].offset_after;
425 }
426 
copy_attr_helper_name(struct nf_conntrack * dest,const struct nf_conntrack * orig)427 static void copy_attr_helper_name(struct nf_conntrack *dest,
428 				  const struct nf_conntrack *orig)
429 {
430 	strncpy(dest->helper_name, orig->helper_name, NFCT_HELPER_NAME_MAX);
431 	dest->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0';
432 }
433 
copy_attr_zone(struct nf_conntrack * dest,const struct nf_conntrack * orig)434 static void copy_attr_zone(struct nf_conntrack *dest,
435 			   const struct nf_conntrack *orig)
436 {
437 	dest->zone = orig->zone;
438 }
439 
copy_attr_secctx(struct nf_conntrack * dest,const struct nf_conntrack * orig)440 static void copy_attr_secctx(struct nf_conntrack *dest,
441 			     const struct nf_conntrack *orig)
442 {
443 	if (dest->secctx) {
444 		free(dest->secctx);
445 		dest->secctx = NULL;
446 	}
447 	if (orig->secctx)
448 		dest->secctx = strdup(orig->secctx);
449 }
450 
copy_attr_timestamp_start(struct nf_conntrack * dest,const struct nf_conntrack * orig)451 static void copy_attr_timestamp_start(struct nf_conntrack *dest,
452 				      const struct nf_conntrack *orig)
453 {
454 	dest->timestamp.start = orig->timestamp.start;
455 }
456 
copy_attr_timestamp_stop(struct nf_conntrack * dest,const struct nf_conntrack * orig)457 static void copy_attr_timestamp_stop(struct nf_conntrack *dest,
458 				     const struct nf_conntrack *orig)
459 {
460 	dest->timestamp.stop = orig->timestamp.stop;
461 }
462 
copy_attr_help_info(struct nf_conntrack * dest,const struct nf_conntrack * orig)463 static void copy_attr_help_info(struct nf_conntrack *dest,
464 				const struct nf_conntrack *orig)
465 {
466 	if (orig->helper_info == NULL)
467 		return;
468 
469 	if (dest->helper_info != NULL)
470 		free(dest->helper_info);
471 
472 	dest->helper_info = calloc(1, orig->helper_info_len);
473 	if (dest->helper_info == NULL)
474 		return;
475 
476 	memcpy(dest->helper_info, orig->helper_info, orig->helper_info_len);
477 }
478 
do_copy_attr_connlabels(struct nfct_bitmask * dest,const struct nfct_bitmask * orig)479 static void* do_copy_attr_connlabels(struct nfct_bitmask *dest,
480 				     const struct nfct_bitmask *orig)
481 {
482 	if (orig == NULL)
483 		return dest;
484 	if (dest)
485 		nfct_bitmask_destroy(dest);
486 	return nfct_bitmask_clone(orig);
487 }
488 
copy_attr_connlabels(struct nf_conntrack * dest,const struct nf_conntrack * orig)489 static void copy_attr_connlabels(struct nf_conntrack *dest,
490 				 const struct nf_conntrack *orig)
491 {
492 	dest->connlabels = do_copy_attr_connlabels(dest->connlabels, orig->connlabels);
493 }
494 
copy_attr_connlabels_mask(struct nf_conntrack * dest,const struct nf_conntrack * orig)495 static void copy_attr_connlabels_mask(struct nf_conntrack *dest,
496 				 const struct nf_conntrack *orig)
497 {
498 	dest->connlabels_mask = do_copy_attr_connlabels(dest->connlabels_mask, orig->connlabels_mask);
499 }
500 
501 const copy_attr copy_attr_array[ATTR_MAX] = {
502 	[ATTR_ORIG_IPV4_SRC]		= copy_attr_orig_ipv4_src,
503 	[ATTR_ORIG_IPV4_DST] 		= copy_attr_orig_ipv4_dst,
504 	[ATTR_REPL_IPV4_SRC]		= copy_attr_repl_ipv4_src,
505 	[ATTR_REPL_IPV4_DST]		= copy_attr_repl_ipv4_dst,
506 	[ATTR_ORIG_IPV6_SRC]		= copy_attr_orig_ipv6_src,
507 	[ATTR_ORIG_IPV6_DST]		= copy_attr_orig_ipv6_dst,
508 	[ATTR_REPL_IPV6_SRC]		= copy_attr_repl_ipv6_src,
509 	[ATTR_REPL_IPV6_DST]		= copy_attr_repl_ipv6_dst,
510 	[ATTR_ORIG_PORT_SRC]		= copy_attr_orig_port_src,
511 	[ATTR_ORIG_PORT_DST]		= copy_attr_orig_port_dst,
512 	[ATTR_REPL_PORT_SRC]		= copy_attr_repl_port_src,
513 	[ATTR_REPL_PORT_DST]		= copy_attr_repl_port_dst,
514 	[ATTR_ICMP_TYPE]		= copy_attr_icmp_type,
515 	[ATTR_ICMP_CODE]		= copy_attr_icmp_code,
516 	[ATTR_ICMP_ID]			= copy_attr_icmp_id,
517 	[ATTR_ORIG_L3PROTO]		= copy_attr_orig_l3proto,
518 	[ATTR_REPL_L3PROTO]		= copy_attr_repl_l3proto,
519 	[ATTR_ORIG_L4PROTO]		= copy_attr_orig_l4proto,
520 	[ATTR_REPL_L4PROTO]		= copy_attr_repl_l4proto,
521 	[ATTR_TCP_STATE]		= copy_attr_tcp_state,
522 	[ATTR_SNAT_IPV4]		= copy_attr_snat_ipv4,
523 	[ATTR_DNAT_IPV4]		= copy_attr_dnat_ipv4,
524 	[ATTR_SNAT_PORT]		= copy_attr_snat_port,
525 	[ATTR_DNAT_PORT]		= copy_attr_dnat_port,
526 	[ATTR_TIMEOUT]			= copy_attr_timeout,
527 	[ATTR_MARK]			= copy_attr_mark,
528 	[ATTR_ORIG_COUNTER_PACKETS] 	= copy_attr_orig_counter_packets,
529 	[ATTR_ORIG_COUNTER_BYTES]	= copy_attr_orig_counter_bytes,
530 	[ATTR_REPL_COUNTER_PACKETS]	= copy_attr_repl_counter_packets,
531 	[ATTR_REPL_COUNTER_BYTES]	= copy_attr_repl_counter_bytes,
532 	[ATTR_USE]			= copy_attr_use,
533 	[ATTR_ID]			= copy_attr_id,
534 	[ATTR_STATUS]			= copy_attr_status,
535 	[ATTR_TCP_FLAGS_ORIG]		= copy_attr_tcp_flags_orig,
536 	[ATTR_TCP_FLAGS_REPL]		= copy_attr_tcp_flags_repl,
537 	[ATTR_TCP_MASK_ORIG]		= copy_attr_tcp_mask_orig,
538 	[ATTR_TCP_MASK_REPL]		= copy_attr_tcp_mask_repl,
539 	[ATTR_MASTER_IPV4_SRC]		= copy_attr_master_ipv4_src,
540 	[ATTR_MASTER_IPV4_DST] 		= copy_attr_master_ipv4_dst,
541 	[ATTR_MASTER_IPV6_SRC]		= copy_attr_master_ipv6_src,
542 	[ATTR_MASTER_IPV6_DST]		= copy_attr_master_ipv6_dst,
543 	[ATTR_MASTER_PORT_SRC]		= copy_attr_master_port_src,
544 	[ATTR_MASTER_PORT_DST]		= copy_attr_master_port_dst,
545 	[ATTR_MASTER_L3PROTO]		= copy_attr_master_l3proto,
546 	[ATTR_MASTER_L4PROTO]		= copy_attr_master_l4proto,
547 	[ATTR_SECMARK]			= copy_attr_secmark,
548 	[ATTR_ORIG_NAT_SEQ_CORRECTION_POS]	= copy_attr_orig_cor_pos,
549 	[ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE]	= copy_attr_orig_off_bfr,
550 	[ATTR_ORIG_NAT_SEQ_OFFSET_AFTER]	= copy_attr_orig_off_aft,
551 	[ATTR_REPL_NAT_SEQ_CORRECTION_POS]	= copy_attr_repl_cor_pos,
552 	[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE]	= copy_attr_repl_off_bfr,
553 	[ATTR_REPL_NAT_SEQ_OFFSET_AFTER]	= copy_attr_repl_off_aft,
554 	[ATTR_SCTP_STATE]		= copy_attr_sctp_state,
555 	[ATTR_SCTP_VTAG_ORIG]		= copy_attr_sctp_vtag_orig,
556 	[ATTR_SCTP_VTAG_REPL]		= copy_attr_sctp_vtag_repl,
557 	[ATTR_HELPER_NAME]		= copy_attr_helper_name,
558 	[ATTR_DCCP_STATE]		= copy_attr_dccp_state,
559 	[ATTR_DCCP_ROLE]		= copy_attr_dccp_role,
560 	[ATTR_DCCP_HANDSHAKE_SEQ]	= copy_attr_dccp_handshake_seq,
561 	[ATTR_TCP_WSCALE_ORIG]		= copy_attr_tcp_wscale_orig,
562 	[ATTR_TCP_WSCALE_REPL]		= copy_attr_tcp_wscale_repl,
563 	[ATTR_ZONE]			= copy_attr_zone,
564 	[ATTR_ORIG_ZONE]		= copy_attr_orig_zone,
565 	[ATTR_REPL_ZONE]		= copy_attr_repl_zone,
566 	[ATTR_SECCTX]			= copy_attr_secctx,
567 	[ATTR_TIMESTAMP_START]		= copy_attr_timestamp_start,
568 	[ATTR_TIMESTAMP_STOP]		= copy_attr_timestamp_stop,
569 	[ATTR_HELPER_INFO]		= copy_attr_help_info,
570 	[ATTR_CONNLABELS]		= copy_attr_connlabels,
571 	[ATTR_CONNLABELS_MASK]		= copy_attr_connlabels_mask,
572 	[ATTR_SNAT_IPV6]		= copy_attr_snat_ipv6,
573 	[ATTR_DNAT_IPV6]		= copy_attr_dnat_ipv6,
574 };
575 
576 /* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */
__copy_fast(struct nf_conntrack * ct1,const struct nf_conntrack * ct2)577 void __copy_fast(struct nf_conntrack *ct1, const struct nf_conntrack *ct2)
578 {
579 	memcpy(ct1, ct2, sizeof(*ct1));
580 	/* malloc'd attributes: don't free, do copy */
581 	ct1->secctx = NULL;
582 	ct1->helper_info = NULL;
583 	ct1->connlabels = NULL;
584 	ct1->connlabels_mask = NULL;
585 
586 	copy_attr_secctx(ct1, ct2);
587 	copy_attr_help_info(ct1, ct2);
588 	copy_attr_connlabels(ct1, ct2);
589 	copy_attr_connlabels_mask(ct1, ct2);
590 }
591