xref: /xnu-8020.121.3/bsd/net/packet_mangler.c (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2015-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. Please obtain a copy of the License at
10  * http: www.opensource.apple.com/apsl/ and read it before using this
11  * file.
12  *
13  * The Original Code and all software distributed under the License are
14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18  * Please see the License for the specific language governing rights and
19  * limitations under the License.
20  *
21  * @APPLE_LICENSE_HEADER_END@
22  */
23 
24 /*
25  * THEORY OF OPERATION
26  *
27  * The packet mangler subsystem provides a limited way for user space
28  * applications to apply certain actions on certain flows.
29  *
30  * A user space applications opens a kernel control socket with the name
31  * PACKET_MANGLER_CONTROL_NAME to attach to the packet mangler subsystem.
32  * When connected, a "struct packet_mangler" is created and set as the
33  * "unitinfo" of the corresponding kernel control socket instance.
34  * Connect call for packet mangler's kernel control socket also registers
35  * ip filers with cookie set to the packet_mangler instance.
36  * The ip filters are removed when control socket is disconnected.
37  */
38 #include <sys/types.h>
39 #include <sys/kern_control.h>
40 #include <sys/domain.h>
41 #include <sys/protosw.h>
42 #include <sys/syslog.h>
43 
44 #include <kern/locks.h>
45 #include <kern/zalloc.h>
46 #include <kern/debug.h>
47 
48 #include <net/packet_mangler.h>
49 
50 #include <netinet/tcp.h>
51 #include <netinet/tcp_var.h>
52 #include <netinet/ip.h>
53 #include <netinet/ip6.h>
54 #include <netinet/kpi_ipfilter.h>
55 #include <string.h>
56 #include <libkern/libkern.h>
57 
58 #define MAX_PACKET_MANGLER                      1
59 
60 #define PKT_MNGLR_FLG_IPFILTER_ATTACHED         0x00000001
61 
62 SYSCTL_NODE(_net, OID_AUTO, pktmnglr, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "pktmnglr");
63 SYSCTL_INT(_net_pktmnglr, OID_AUTO, log, CTLFLAG_RW | CTLFLAG_LOCKED,
64     &pkt_mnglr_log_level, 0, "");
65 /*
66  * The structure packet_mangler represents a user space packet filter
67  * It's created and associated with a kernel control socket instance
68  */
69 struct packet_mangler {
70 	kern_ctl_ref                    pkt_mnglr_kcref;
71 	uint32_t                        pkt_mnglr_kcunit;
72 	uint32_t                        pkt_mnglr_flags;
73 	/* IP filter related params */
74 	ipfilter_t                      pkt_mnglr_ipfref;
75 	ipfilter_t                      pkt_mnglr_ipfrefv6;
76 	struct ipf_filter               pkt_mnglr_ipfilter;
77 
78 	/* Options */
79 	uint8_t                         activate;
80 	Pkt_Mnglr_Flow                  dir;
81 	struct sockaddr_storage         lsaddr;
82 	struct sockaddr_storage         rsaddr;
83 	struct sockaddr_storage         swap_lsaddr;
84 	struct sockaddr_storage         swap_rsaddr;
85 	uint32_t                        ip_action_mask;
86 	uint16_t                        lport;
87 	uint16_t                        rport;
88 	uint32_t                        proto;
89 	uint32_t                        proto_action_mask;
90 };
91 
92 /* Array of all the packet mangler instancesi */
93 struct packet_mangler *packet_manglers[MAX_PACKET_MANGLER];
94 
95 uint32_t pkt_mnglr_active_count = 0;    /* Number of active packet filters */
96 uint32_t pkt_mnglr_close_wait_timeout = 1000; /* in milliseconds */
97 
98 static kern_ctl_ref pkt_mnglr_kctlref = NULL;
99 
100 /* The lock below protects packet_manglers DS, packet_mangler DS */
101 static LCK_GRP_DECLARE(pkt_mnglr_lck_grp, "packet mangler");
102 static LCK_RW_DECLARE(pkt_mnglr_lck_rw, &pkt_mnglr_lck_grp);
103 
104 #define PKT_MNGLR_RW_LCK_MAX    8
105 
106 int pkt_mnglr_rw_nxt_lck = 0;
107 void* pkt_mnglr_rw_lock_history[PKT_MNGLR_RW_LCK_MAX];
108 
109 int pkt_mnglr_rw_nxt_unlck = 0;
110 void* pkt_mnglr_rw_unlock_history[PKT_MNGLR_RW_LCK_MAX];
111 
112 static ZONE_DEFINE(packet_mangler_zone, "packet_mangler",
113     sizeof(struct packet_mangler), ZC_NONE);
114 
115 /*
116  * For troubleshooting
117  */
118 int pkt_mnglr_log_level = LOG_ERR;
119 int pkt_mnglr_debug = 1;
120 
121 /*
122  * Forward declaration to appease the compiler
123  */
124 static void pkt_mnglr_rw_lock_exclusive(lck_rw_t *);
125 static void pkt_mnglr_rw_unlock_exclusive(lck_rw_t *);
126 static void pkt_mnglr_rw_lock_shared(lck_rw_t *);
127 static void pkt_mnglr_rw_unlock_shared(lck_rw_t *);
128 
129 static errno_t pktmnglr_ipfilter_output(void *cookie, mbuf_t *data,
130     ipf_pktopts_t options);
131 static errno_t pktmnglr_ipfilter_input(void *cookie, mbuf_t *data,
132     int offset, u_int8_t protocol);
133 static void pktmnglr_ipfilter_detach(void *cookie);
134 
135 static void chksm_update(mbuf_t data);
136 
137 #define TCP_OPT_MULTIPATH_TCP   30
138 #define MPTCP_SBT_VER_OFFSET    2
139 
140 #define MPTCP_SUBTYPE_MPCAPABLE         0x0
141 #define MPTCP_SUBTYPE_MPJOIN            0x1
142 #define MPTCP_SUBTYPE_DSS               0x2
143 #define MPTCP_SUBTYPE_ADD_ADDR          0x3
144 #define MPTCP_SUBTYPE_REM_ADDR          0x4
145 #define MPTCP_SUBTYPE_MP_PRIO           0x5
146 #define MPTCP_SUBTYPE_MP_FAIL           0x6
147 #define MPTCP_SUBTYPE_MP_FASTCLOSE      0x7
148 
149 /*
150  * packet filter global read write lock
151  */
152 
153 static void
pkt_mnglr_rw_lock_exclusive(lck_rw_t * lck)154 pkt_mnglr_rw_lock_exclusive(lck_rw_t *lck)
155 {
156 	void *lr_saved;
157 
158 	lr_saved = __builtin_return_address(0);
159 
160 	lck_rw_lock_exclusive(lck);
161 
162 	pkt_mnglr_rw_lock_history[pkt_mnglr_rw_nxt_lck] = lr_saved;
163 	pkt_mnglr_rw_nxt_lck =
164 	    (pkt_mnglr_rw_nxt_lck + 1) % PKT_MNGLR_RW_LCK_MAX;
165 }
166 
167 static void
pkt_mnglr_rw_unlock_exclusive(lck_rw_t * lck)168 pkt_mnglr_rw_unlock_exclusive(lck_rw_t *lck)
169 {
170 	void *lr_saved;
171 
172 	lr_saved = __builtin_return_address(0);
173 
174 	lck_rw_unlock_exclusive(lck);
175 
176 	pkt_mnglr_rw_unlock_history[pkt_mnglr_rw_nxt_unlck] =
177 	    lr_saved;
178 	pkt_mnglr_rw_nxt_unlck = (pkt_mnglr_rw_nxt_unlck + 1) % PKT_MNGLR_RW_LCK_MAX;
179 }
180 
181 static void
pkt_mnglr_rw_lock_shared(lck_rw_t * lck)182 pkt_mnglr_rw_lock_shared(lck_rw_t *lck)
183 {
184 	void *lr_saved;
185 
186 	lr_saved = __builtin_return_address(0);
187 
188 	lck_rw_lock_shared(lck);
189 
190 	pkt_mnglr_rw_lock_history[pkt_mnglr_rw_nxt_lck] = lr_saved;
191 	pkt_mnglr_rw_nxt_lck = (pkt_mnglr_rw_nxt_lck + 1) % PKT_MNGLR_RW_LCK_MAX;
192 }
193 
194 static void
pkt_mnglr_rw_unlock_shared(lck_rw_t * lck)195 pkt_mnglr_rw_unlock_shared(lck_rw_t *lck)
196 {
197 	void *lr_saved;
198 
199 	lr_saved = __builtin_return_address(0);
200 
201 	lck_rw_unlock_shared(lck);
202 
203 	pkt_mnglr_rw_unlock_history[pkt_mnglr_rw_nxt_unlck] = lr_saved;
204 	pkt_mnglr_rw_nxt_unlck = (pkt_mnglr_rw_nxt_unlck + 1) % PKT_MNGLR_RW_LCK_MAX;
205 }
206 
207 /*
208  * Packet Mangler's Kernel control socket callbacks
209  */
210 static errno_t
pkt_mnglr_ctl_connect(kern_ctl_ref kctlref,struct sockaddr_ctl * sac,void ** unitinfo)211 pkt_mnglr_ctl_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac,
212     void **unitinfo)
213 {
214 	errno_t error = 0;
215 	struct packet_mangler *p_pkt_mnglr = NULL;
216 
217 	PKT_MNGLR_LOG(LOG_NOTICE, "Connecting packet mangler filter.");
218 
219 	if (sac->sc_unit == 0 || sac->sc_unit > MAX_PACKET_MANGLER) {
220 		PKT_MNGLR_LOG(LOG_ERR, "bad sc_unit %u", sac->sc_unit);
221 		error = EINVAL;
222 		goto fail;
223 	}
224 
225 	p_pkt_mnglr = zalloc_flags(packet_mangler_zone,
226 	    Z_WAITOK | Z_ZERO | Z_NOFAIL);
227 
228 	pkt_mnglr_rw_lock_exclusive(&pkt_mnglr_lck_rw);
229 
230 	if (packet_manglers[sac->sc_unit - 1] != NULL) {
231 		PKT_MNGLR_LOG(LOG_ERR, "sc_unit %u in use", sac->sc_unit);
232 		error = EADDRINUSE;
233 		pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
234 		goto fail_free;
235 	} else {
236 		/*
237 		 * kernel control socket kcunit numbers start at 1
238 		 */
239 		packet_manglers[sac->sc_unit - 1] = p_pkt_mnglr;
240 
241 		p_pkt_mnglr->pkt_mnglr_kcref = kctlref;
242 		p_pkt_mnglr->pkt_mnglr_kcunit = sac->sc_unit;
243 
244 		pkt_mnglr_active_count++;
245 	}
246 
247 	p_pkt_mnglr->pkt_mnglr_ipfilter.cookie = p_pkt_mnglr;
248 	p_pkt_mnglr->pkt_mnglr_ipfilter.name = "com.apple.pktmnglripfilter";
249 	p_pkt_mnglr->pkt_mnglr_ipfilter.ipf_input = pktmnglr_ipfilter_input;
250 	p_pkt_mnglr->pkt_mnglr_ipfilter.ipf_output = pktmnglr_ipfilter_output;
251 	p_pkt_mnglr->pkt_mnglr_ipfilter.ipf_detach = pktmnglr_ipfilter_detach;
252 	error = ipf_addv4(&(p_pkt_mnglr->pkt_mnglr_ipfilter), &(p_pkt_mnglr->pkt_mnglr_ipfref));
253 	if (error) {
254 		PKT_MNGLR_LOG(LOG_ERR, "Could not register packet mangler's IPv4 Filter");
255 		goto fail_locked;
256 	}
257 	error = ipf_addv6(&(p_pkt_mnglr->pkt_mnglr_ipfilter), &(p_pkt_mnglr->pkt_mnglr_ipfrefv6));
258 	if (error) {
259 		ipf_remove(p_pkt_mnglr->pkt_mnglr_ipfref);
260 		PKT_MNGLR_LOG(LOG_ERR, "Could not register packet mangler's IPv6 Filter");
261 		goto fail_locked;
262 	}
263 
264 	PKT_MNGLR_LOG(LOG_INFO, "Registered packet mangler's IP Filters");
265 	p_pkt_mnglr->pkt_mnglr_flags |= PKT_MNGLR_FLG_IPFILTER_ATTACHED;
266 	pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
267 
268 	if (error) {
269 fail_locked:
270 		pkt_mnglr_active_count--;
271 
272 		packet_manglers[sac->sc_unit - 1] = NULL;
273 		*unitinfo = NULL;
274 
275 		pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
276 
277 fail_free:
278 		zfree(packet_mangler_zone, p_pkt_mnglr);
279 	}
280 
281 fail:
282 	*unitinfo = p_pkt_mnglr;
283 
284 	PKT_MNGLR_LOG(LOG_INFO, "return %d pkt_mnglr_active_count %u kcunit %u",
285 	    error, pkt_mnglr_active_count, sac->sc_unit);
286 
287 	return error;
288 }
289 
290 static errno_t
pkt_mnglr_ctl_disconnect(kern_ctl_ref kctlref,u_int32_t kcunit,void * unitinfo)291 pkt_mnglr_ctl_disconnect(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo)
292 {
293 #pragma unused(kctlref)
294 	errno_t error = 0;
295 	struct packet_mangler *p_pkt_mnglr;
296 
297 	PKT_MNGLR_LOG(LOG_INFO, "Disconnecting packet mangler kernel control");
298 
299 	if (unitinfo == NULL) {
300 		goto done;
301 	}
302 
303 	if (kcunit > MAX_PACKET_MANGLER) {
304 		PKT_MNGLR_LOG(LOG_ERR, "kcunit %u > MAX_PACKET_MANGLER (%d)",
305 		    kcunit, MAX_PACKET_MANGLER);
306 		error = EINVAL;
307 		goto done;
308 	}
309 
310 	p_pkt_mnglr = (struct packet_mangler *)unitinfo;
311 
312 	pkt_mnglr_rw_lock_exclusive(&pkt_mnglr_lck_rw);
313 	if (packet_manglers[kcunit - 1] != p_pkt_mnglr || p_pkt_mnglr->pkt_mnglr_kcunit != kcunit) {
314 		PKT_MNGLR_LOG(LOG_ERR, "bad unit info %u",
315 		    kcunit);
316 		pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
317 		goto done;
318 	}
319 
320 	/*
321 	 * Make filter inactive
322 	 */
323 	packet_manglers[kcunit - 1] = NULL;
324 	pkt_mnglr_active_count--;
325 	if (p_pkt_mnglr->pkt_mnglr_flags & PKT_MNGLR_FLG_IPFILTER_ATTACHED) {
326 		(void) ipf_remove(p_pkt_mnglr->pkt_mnglr_ipfref);
327 		(void) ipf_remove(p_pkt_mnglr->pkt_mnglr_ipfrefv6);
328 	}
329 	pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
330 	zfree(packet_mangler_zone, p_pkt_mnglr);
331 done:
332 	PKT_MNGLR_LOG(LOG_INFO, "return %d pkt_mnglr_active_count %u kcunit %u",
333 	    error, pkt_mnglr_active_count, kcunit);
334 
335 	return error;
336 }
337 
338 static errno_t
pkt_mnglr_ctl_getopt(kern_ctl_ref kctlref,u_int32_t kcunit,void * unitinfo,int opt,void * data,size_t * len)339 pkt_mnglr_ctl_getopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo,
340     int opt, void *data, size_t *len)
341 {
342 #pragma unused(kctlref, opt)
343 	errno_t error = 0;
344 	struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)unitinfo;
345 
346 	PKT_MNGLR_LOG(LOG_NOTICE, "");
347 
348 	pkt_mnglr_rw_lock_shared(&pkt_mnglr_lck_rw);
349 
350 	if (kcunit > MAX_PACKET_MANGLER) {
351 		PKT_MNGLR_LOG(LOG_ERR, "kcunit %u > MAX_PACKET_MANGLER (%d)",
352 		    kcunit, MAX_PACKET_MANGLER);
353 		error = EINVAL;
354 		goto done;
355 	}
356 	if (p_pkt_mnglr != (void *)packet_manglers[kcunit - 1]) {
357 		PKT_MNGLR_LOG(LOG_ERR, "unitinfo does not match for kcunit %u",
358 		    kcunit);
359 		error = EINVAL;
360 		goto done;
361 	}
362 	switch (opt) {
363 	case PKT_MNGLR_OPT_PROTO_ACT_MASK:
364 		if (*len < sizeof(uint32_t)) {
365 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK "
366 			    "len too small %lu", *len);
367 			error = EINVAL;
368 			goto done;
369 		}
370 
371 		if (data != NULL) {
372 			*(uint32_t *)data = p_pkt_mnglr->proto_action_mask;
373 		}
374 		break;
375 	case PKT_MNGLR_OPT_IP_ACT_MASK:
376 		if (*len < sizeof(uint32_t)) {
377 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK "
378 			    "len too small %lu", *len);
379 			error = EINVAL;
380 			goto done;
381 		}
382 
383 		if (data != NULL) {
384 			*(uint32_t *)data = p_pkt_mnglr->ip_action_mask;
385 		}
386 		break;
387 	case PKT_MNGLR_OPT_LOCAL_IP:
388 		if (*len < sizeof(struct sockaddr_storage)) {
389 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP "
390 			    "len too small %lu", *len);
391 			error = EINVAL;
392 			goto done;
393 		}
394 
395 		if (data != NULL) {
396 			*(struct sockaddr_storage *)data = p_pkt_mnglr->lsaddr;
397 		}
398 		break;
399 	case PKT_MNGLR_OPT_REMOTE_IP:
400 		if (*len < sizeof(struct sockaddr_storage)) {
401 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP "
402 			    "len too small %lu", *len);
403 			error = EINVAL;
404 			goto done;
405 		}
406 
407 		if (data != NULL) {
408 			*(struct sockaddr_storage *)data = p_pkt_mnglr->rsaddr;
409 		}
410 		break;
411 	case PKT_MNGLR_OPT_LOCAL_PORT:
412 		if (*len < sizeof(uint16_t)) {
413 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT "
414 			    "len too small %lu", *len);
415 			error = EINVAL;
416 			goto done;
417 		}
418 
419 		if (data != NULL) {
420 			*(uint16_t *)data = p_pkt_mnglr->lport;
421 		}
422 		break;
423 	case PKT_MNGLR_OPT_REMOTE_PORT:
424 		if (*len < sizeof(uint16_t)) {
425 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT "
426 			    "len too small %lu", *len);
427 			error = EINVAL;
428 			goto done;
429 		}
430 
431 		if (data != NULL) {
432 			*(uint16_t *)data = p_pkt_mnglr->rport;
433 		}
434 		break;
435 	case PKT_MNGLR_OPT_DIRECTION:
436 		if (*len < sizeof(uint32_t)) {
437 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION "
438 			    "len too small %lu", *len);
439 			error = EINVAL;
440 			goto done;
441 		}
442 		if (data != NULL) {
443 			*(uint32_t *)data = p_pkt_mnglr->dir;
444 		}
445 		break;
446 	case PKT_MNGLR_OPT_PROTOCOL:
447 		if (*len < sizeof(uint32_t)) {
448 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL "
449 			    "len too small %lu", *len);
450 			error = EINVAL;
451 			goto done;
452 		}
453 		if (data != NULL) {
454 			*(uint32_t *)data = p_pkt_mnglr->proto;
455 		}
456 		break;
457 	case PKT_MNGLR_OPT_ACTIVATE:
458 		if (*len < sizeof(uint8_t)) {
459 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE "
460 			    "len too small %lu", *len);
461 			error = EINVAL;
462 			goto done;
463 		}
464 
465 		if (data != NULL) {
466 			*(uint8_t *)data = p_pkt_mnglr->activate;
467 		}
468 		break;
469 	default:
470 		error = ENOPROTOOPT;
471 		break;
472 	}
473 done:
474 	pkt_mnglr_rw_unlock_shared(&pkt_mnglr_lck_rw);
475 
476 	return error;
477 }
478 
479 static errno_t
pkt_mnglr_ctl_setopt(kern_ctl_ref kctlref,u_int32_t kcunit,void * unitinfo,int opt,void * data,size_t len)480 pkt_mnglr_ctl_setopt(kern_ctl_ref kctlref, u_int32_t kcunit, void *unitinfo,
481     int opt, void *data, size_t len)
482 {
483 #pragma unused(kctlref, opt)
484 	errno_t error = 0;
485 	struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)unitinfo;
486 
487 	PKT_MNGLR_LOG(LOG_NOTICE, "");
488 
489 	pkt_mnglr_rw_lock_exclusive(&pkt_mnglr_lck_rw);
490 
491 	if (kcunit > MAX_PACKET_MANGLER) {
492 		PKT_MNGLR_LOG(LOG_ERR, "kcunit %u > MAX_PACKET_MANGLER (%d)",
493 		    kcunit, MAX_PACKET_MANGLER);
494 		error = EINVAL;
495 		goto done;
496 	}
497 	if (p_pkt_mnglr != (void *)packet_manglers[kcunit - 1]) {
498 		PKT_MNGLR_LOG(LOG_ERR, "unitinfo does not match for kcunit %u",
499 		    kcunit);
500 		error = EINVAL;
501 		goto done;
502 	}
503 	switch (opt) {
504 	case PKT_MNGLR_OPT_PROTO_ACT_MASK:
505 		if (len < sizeof(uint32_t)) {
506 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK "
507 			    "len too small %lu", len);
508 			error = EINVAL;
509 			goto done;
510 		}
511 		if (p_pkt_mnglr->proto_action_mask != 0) {
512 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTO_ACT_MASK "
513 			    "already set %u",
514 			    p_pkt_mnglr->proto_action_mask);
515 			error = EINVAL;
516 			goto done;
517 		}
518 		p_pkt_mnglr->proto_action_mask = *(uint32_t *)data;
519 		PKT_MNGLR_LOG(LOG_INFO, "p_pkt_mnglr->proto_action_mask set to :%d", p_pkt_mnglr->proto_action_mask);
520 		break;
521 	case PKT_MNGLR_OPT_IP_ACT_MASK:
522 		if (len < sizeof(uint32_t)) {
523 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK "
524 			    "len too small %lu", len);
525 			error = EINVAL;
526 			goto done;
527 		}
528 		if (p_pkt_mnglr->ip_action_mask != 0) {
529 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_IP_ACT_MASK "
530 			    "already set %u",
531 			    p_pkt_mnglr->ip_action_mask);
532 			error = EINVAL;
533 			goto done;
534 		}
535 		p_pkt_mnglr->ip_action_mask = *(uint32_t *)data;
536 		break;
537 	case PKT_MNGLR_OPT_LOCAL_IP:
538 		if (len < sizeof(struct sockaddr_storage)) {
539 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP "
540 			    "len too small %lu", len);
541 			error = EINVAL;
542 			goto done;
543 		}
544 		if (p_pkt_mnglr->lsaddr.ss_family) {
545 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_IP "
546 			    "already set");
547 			error = EINVAL;
548 			goto done;
549 		}
550 		p_pkt_mnglr->lsaddr = *(struct sockaddr_storage *)data;
551 		break;
552 	case PKT_MNGLR_OPT_REMOTE_IP:
553 		if (len < sizeof(struct sockaddr_storage)) {
554 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP "
555 			    "len too small %lu", len);
556 			error = EINVAL;
557 			goto done;
558 		}
559 		if (p_pkt_mnglr->rsaddr.ss_family) {
560 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_IP "
561 			    "already set");
562 			error = EINVAL;
563 			goto done;
564 		}
565 
566 		p_pkt_mnglr->rsaddr = *(struct sockaddr_storage *)data;
567 		PKT_MNGLR_LOG(LOG_INFO,
568 		    "Remote IP registered for address family: %d",
569 		    p_pkt_mnglr->rsaddr.ss_family);
570 		break;
571 	case PKT_MNGLR_OPT_LOCAL_PORT:
572 		if (len < sizeof(uint16_t)) {
573 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT "
574 			    "len too small %lu", len);
575 			error = EINVAL;
576 			goto done;
577 		}
578 		if (p_pkt_mnglr->lport != 0) {
579 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_LOCAL_PORT "
580 			    "already set %d",
581 			    p_pkt_mnglr->lport);
582 			error = EINVAL;
583 			goto done;
584 		}
585 		p_pkt_mnglr->lport = *(uint16_t *)data;
586 		break;
587 	case PKT_MNGLR_OPT_REMOTE_PORT:
588 		if (len < sizeof(uint16_t)) {
589 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT "
590 			    "len too small %lu", len);
591 			error = EINVAL;
592 			goto done;
593 		}
594 		if (p_pkt_mnglr->rport != 0) {
595 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_REMOTE_PORT "
596 			    "already set %d",
597 			    p_pkt_mnglr->rport);
598 			error = EINVAL;
599 			goto done;
600 		}
601 		p_pkt_mnglr->rport = *(uint16_t *)data;
602 		break;
603 	case PKT_MNGLR_OPT_DIRECTION:
604 		if (len < sizeof(uint32_t)) {
605 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION "
606 			    "len too small %lu", len);
607 			error = EINVAL;
608 			goto done;
609 		}
610 		if (p_pkt_mnglr->dir != 0) {
611 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_DIRECTION "
612 			    "already set %u",
613 			    p_pkt_mnglr->dir);
614 			error = EINVAL;
615 			goto done;
616 		}
617 		p_pkt_mnglr->dir = *(uint32_t *)data;
618 		break;
619 	case PKT_MNGLR_OPT_PROTOCOL:
620 		if (len < sizeof(uint32_t)) {
621 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL "
622 			    "len too small %lu", len);
623 			error = EINVAL;
624 			goto done;
625 		}
626 		if (p_pkt_mnglr->proto != 0) {
627 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_PROTOCOL "
628 			    "already set %u",
629 			    p_pkt_mnglr->proto);
630 			error = EINVAL;
631 			goto done;
632 		}
633 		p_pkt_mnglr->proto = *(uint32_t *)data;
634 		break;
635 	case PKT_MNGLR_OPT_ACTIVATE:
636 		if (len < sizeof(uint8_t)) {
637 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE "
638 			    "len too small %lu", len);
639 			error = EINVAL;
640 			goto done;
641 		}
642 		if (p_pkt_mnglr->activate != 0) {
643 			PKT_MNGLR_LOG(LOG_ERR, "PKT_MNGLR_OPT_ACTIVATE "
644 			    "already set %u",
645 			    p_pkt_mnglr->activate);
646 			error = EINVAL;
647 			goto done;
648 		}
649 		p_pkt_mnglr->activate = *(uint8_t *)data;
650 		PKT_MNGLR_LOG(LOG_ERR, "p_pkt_mnglr->activate set to :%d",
651 		    p_pkt_mnglr->activate);
652 		break;
653 	default:
654 		error = ENOPROTOOPT;
655 		break;
656 	}
657 done:
658 	pkt_mnglr_rw_unlock_exclusive(&pkt_mnglr_lck_rw);
659 
660 	return error;
661 }
662 
663 void
pkt_mnglr_init(void)664 pkt_mnglr_init(void)
665 {
666 	struct kern_ctl_reg kern_ctl;
667 	errno_t error = 0;
668 
669 	PKT_MNGLR_LOG(LOG_NOTICE, "");
670 
671 	/*
672 	 * Compile time verifications
673 	 */
674 	_CASSERT(PKT_MNGLR_MAX_FILTER_COUNT == MAX_PACKET_MANGLER);
675 
676 	/*
677 	 * Register kernel control
678 	 */
679 	bzero(&kern_ctl, sizeof(kern_ctl));
680 	strlcpy(kern_ctl.ctl_name, PACKET_MANGLER_CONTROL_NAME,
681 	    sizeof(kern_ctl.ctl_name));
682 	kern_ctl.ctl_flags = CTL_FLAG_PRIVILEGED | CTL_FLAG_REG_EXTENDED;
683 	kern_ctl.ctl_connect = pkt_mnglr_ctl_connect;
684 	kern_ctl.ctl_disconnect = pkt_mnglr_ctl_disconnect;
685 	kern_ctl.ctl_getopt = pkt_mnglr_ctl_getopt;
686 	kern_ctl.ctl_setopt = pkt_mnglr_ctl_setopt;
687 	error = ctl_register(&kern_ctl, &pkt_mnglr_kctlref);
688 	if (error != 0) {
689 		PKT_MNGLR_LOG(LOG_ERR, "ctl_register failed: %d", error);
690 	} else {
691 		PKT_MNGLR_LOG(LOG_INFO, "Registered packet mangler kernel control.");
692 	}
693 }
694 
695 static errno_t
pktmnglr_ipfilter_output(void * cookie,mbuf_t * data,ipf_pktopts_t options)696 pktmnglr_ipfilter_output(void *cookie, mbuf_t *data, ipf_pktopts_t options)
697 {
698 	struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)cookie;
699 	struct ip ip;
700 	struct tcphdr tcp;
701 	int optlen = 0;
702 	errno_t error = 0;
703 
704 #pragma unused(tcp, optlen, options)
705 	if (p_pkt_mnglr == NULL) {
706 		goto output_done;
707 	}
708 
709 	if (!p_pkt_mnglr->activate) {
710 		goto output_done;
711 	}
712 
713 	if (p_pkt_mnglr->dir == IN) {
714 		goto output_done;
715 	}
716 
717 	if (data == NULL) {
718 		PKT_MNGLR_LOG(LOG_ERR, "Data pointer is NULL");
719 		goto output_done;
720 	}
721 
722 	/* Check for IP filter options */
723 	error = mbuf_copydata(*data, 0, sizeof(ip), &ip);
724 	if (error) {
725 		PKT_MNGLR_LOG(LOG_ERR, "Could not make local IP header copy");
726 		goto output_done;
727 	}
728 
729 	if ((p_pkt_mnglr->lsaddr.ss_family == AF_INET6) && (ip.ip_v == 4)) {
730 		goto output_done;
731 	}
732 
733 	if ((p_pkt_mnglr->lsaddr.ss_family == AF_INET) && (ip.ip_v == 6)) {
734 		goto output_done;
735 	}
736 
737 	if (p_pkt_mnglr->lsaddr.ss_family == AF_INET) {
738 		struct sockaddr_in laddr = *(struct sockaddr_in *)(&(p_pkt_mnglr->lsaddr));
739 		if (ip.ip_src.s_addr != laddr.sin_addr.s_addr) {
740 			goto output_done;
741 		}
742 	}
743 
744 	if (p_pkt_mnglr->rsaddr.ss_family == AF_INET) {
745 		struct sockaddr_in raddr = *(struct sockaddr_in *)(&(p_pkt_mnglr->rsaddr));
746 		if (ip.ip_dst.s_addr != raddr.sin_addr.s_addr) {
747 			goto output_done;
748 		}
749 	}
750 
751 	if (ip.ip_v != 4) {
752 		PKT_MNGLR_LOG(LOG_INFO,
753 		    "%s:%d Not handling IP version %d\n",
754 		    __func__, __LINE__, ip.ip_v);
755 		goto output_done;
756 	}
757 
758 output_done:
759 	/* Not handling output flow */
760 	return 0;
761 }
762 
763 #define TCP_MAX_OPTLEN  40
764 
765 static errno_t
pktmnglr_ipfilter_input(void * cookie,mbuf_t * data,int offset,u_int8_t protocol)766 pktmnglr_ipfilter_input(void *cookie, mbuf_t *data, int offset, u_int8_t protocol)
767 {
768 	struct packet_mangler *p_pkt_mnglr = (struct packet_mangler *)cookie;
769 	struct ip6_hdr ip6;
770 	struct ip ip;
771 	struct tcphdr tcp;
772 	size_t ip_pld_len;
773 	errno_t error = 0;
774 
775 	if (p_pkt_mnglr == NULL) {
776 		PKT_MNGLR_LOG(LOG_ERR, "p_pkt_mnglr is NULL");
777 		goto input_done;
778 	}
779 
780 	if (p_pkt_mnglr->activate == 0) {
781 		PKT_MNGLR_LOG(LOG_INFO, "p_pkt_mnglr not yet activated");
782 		goto input_done;
783 	}
784 
785 	if (p_pkt_mnglr->dir == OUT) {
786 		goto input_done;
787 	}
788 
789 	if (data == NULL) {
790 		PKT_MNGLR_LOG(LOG_ERR, "Data pointer is NULL");
791 		goto input_done;
792 	}
793 
794 	/* Check for IP filter options */
795 	error = mbuf_copydata(*data, 0, sizeof(ip), &ip);
796 	if (error) {
797 		PKT_MNGLR_LOG(LOG_ERR, "Could not make local IP header copy");
798 		goto input_done;
799 	}
800 
801 	if (ip.ip_v == 6) {
802 		error = mbuf_copydata(*data, 0, sizeof(ip6), &ip6);
803 		if (error) {
804 			PKT_MNGLR_LOG(LOG_ERR, "Could not make local IPv6 header copy");
805 			goto input_done;
806 		}
807 	}
808 
809 	if ((p_pkt_mnglr->lsaddr.ss_family == AF_INET6) && (ip.ip_v == 4)) {
810 		PKT_MNGLR_LOG(LOG_INFO, "Skipping filtering as address family of packet is IPv4 but local "
811 		    "address is set to IPv6");
812 		goto input_done;
813 	}
814 
815 	if ((p_pkt_mnglr->lsaddr.ss_family == AF_INET) && (ip.ip_v == 6)) {
816 		PKT_MNGLR_LOG(LOG_INFO, "Skipping filtering as address family "
817 		    "of packet is IPv6 but local address is set to IPv4");
818 		goto input_done;
819 	}
820 
821 	if (p_pkt_mnglr->lsaddr.ss_family == AF_INET) {
822 		struct sockaddr_in laddr = *(struct sockaddr_in *)(&(p_pkt_mnglr->lsaddr));
823 		if (ip.ip_dst.s_addr != laddr.sin_addr.s_addr) {
824 			goto input_done;
825 		}
826 	} else if (p_pkt_mnglr->lsaddr.ss_family == AF_INET6) {
827 		struct sockaddr_in6 laddr = *(struct sockaddr_in6 *)(&(p_pkt_mnglr->lsaddr));
828 		if (!IN6_ARE_ADDR_EQUAL(&ip6.ip6_dst, &laddr.sin6_addr)) {
829 			goto input_done;
830 		}
831 	}
832 
833 	if (p_pkt_mnglr->rsaddr.ss_family == AF_INET) {
834 		struct sockaddr_in raddr = *(struct sockaddr_in *)(&(p_pkt_mnglr->rsaddr));
835 		if (ip.ip_src.s_addr != raddr.sin_addr.s_addr) {
836 			goto input_done;
837 		}
838 		PKT_MNGLR_LOG(LOG_INFO, "Remote IP: %x Source IP: %x in input path",
839 		    raddr.sin_addr.s_addr,
840 		    ip.ip_src.s_addr);
841 	} else if (p_pkt_mnglr->rsaddr.ss_family == AF_INET6) {
842 		struct sockaddr_in6 raddr = *(struct sockaddr_in6 *)(&(p_pkt_mnglr->rsaddr));
843 		if (!IN6_ARE_ADDR_EQUAL(&ip6.ip6_src, &raddr.sin6_addr)) {
844 			goto input_done;
845 		}
846 	}
847 
848 	if (ip.ip_v == 4) {
849 		ip_pld_len = ntohs(ip.ip_len) - (ip.ip_hl << 2);
850 	} else if (ip.ip_v == 6) {
851 		if (ip6.ip6_nxt != p_pkt_mnglr->proto) {
852 			/* Don't support IPv6 extension headers */
853 			goto input_done;
854 		}
855 		ip_pld_len = ntohs(ip6.ip6_plen);
856 	} else {
857 		goto input_done;
858 	}
859 
860 
861 	if (protocol != p_pkt_mnglr->proto) {
862 		PKT_MNGLR_LOG(LOG_INFO, "Skip: Protocol mismatch");
863 		goto input_done;
864 	}
865 
866 	switch (protocol) {
867 	case IPPROTO_TCP:
868 		if (ip_pld_len < sizeof(tcp)) {
869 			PKT_MNGLR_LOG(LOG_ERR, "IP total len not big enough for TCP: %zu", ip_pld_len);
870 			goto drop_it;
871 		}
872 
873 		error = mbuf_copydata(*data, (size_t)offset, sizeof(tcp), &tcp);
874 		if (error) {
875 			PKT_MNGLR_LOG(LOG_ERR, "Could not make local TCP header copy");
876 			goto input_done;
877 		}
878 
879 		if (p_pkt_mnglr->lport && (p_pkt_mnglr->lport != tcp.th_dport)) {
880 			PKT_MNGLR_LOG(LOG_INFO, "Local port and IP des port do not match");
881 			goto input_done;
882 		}
883 
884 		if (p_pkt_mnglr->rport && (p_pkt_mnglr->rport != tcp.th_sport)) {
885 			PKT_MNGLR_LOG(LOG_INFO, "Remote port and IP src port do not match");
886 			goto input_done;
887 		}
888 		break;
889 	case IPPROTO_UDP:
890 		goto input_done;
891 	case IPPROTO_ICMP:
892 		goto input_done;
893 	case IPPROTO_ICMPV6:
894 		goto input_done;
895 	default:
896 		goto input_done;
897 	}
898 
899 	/* XXX Do IP actions here */
900 	PKT_MNGLR_LOG(LOG_INFO, "Proceeding with packet mangler actions on the packet");
901 
902 	/* Protocol actions */
903 	switch (protocol) {
904 	case IPPROTO_TCP:
905 		if (p_pkt_mnglr->proto_action_mask) {
906 			unsigned char tcp_opt_buf[TCP_MAX_OPTLEN] = {0};
907 			size_t orig_tcp_optlen;
908 			size_t tcp_optlen = 0;
909 			size_t i = 0, off;
910 
911 			off = (tcp.th_off << 2);
912 
913 			if (off < sizeof(struct tcphdr) || off > ip_pld_len) {
914 				PKT_MNGLR_LOG(LOG_ERR, "TCP header offset is wrong: %zu", off);
915 				goto drop_it;
916 			}
917 
918 			tcp_optlen = off - sizeof(struct tcphdr);
919 
920 			PKT_MNGLR_LOG(LOG_INFO, "Packet from F5 is TCP\n");
921 			PKT_MNGLR_LOG(LOG_INFO, "Optlen: %zu\n", tcp_optlen);
922 			orig_tcp_optlen = tcp_optlen;
923 			if (orig_tcp_optlen) {
924 				error = mbuf_copydata(*data, (size_t)offset + sizeof(struct tcphdr), orig_tcp_optlen, tcp_opt_buf);
925 				if (error) {
926 					PKT_MNGLR_LOG(LOG_ERR, "Failed to copy tcp options: error %d offset %d optlen %zu", error, offset, orig_tcp_optlen);
927 					goto input_done;
928 				}
929 			}
930 
931 			while (tcp_optlen > 0) {
932 				if (tcp_opt_buf[i] == 0x1) {
933 					PKT_MNGLR_LOG(LOG_INFO, "Skipping NOP\n");
934 					tcp_optlen--;
935 					i++;
936 					continue;
937 				} else if ((tcp_opt_buf[i] != 0) && (tcp_opt_buf[i] != TCP_OPT_MULTIPATH_TCP)) {
938 					unsigned char optlen;
939 
940 					PKT_MNGLR_LOG(LOG_INFO, "Skipping option %x\n", tcp_opt_buf[i]);
941 
942 					if (tcp_optlen < 2) {
943 						PKT_MNGLR_LOG(LOG_ERR, "Received short TCP option");
944 						goto drop_it;
945 					}
946 
947 					/* Minimum TCP option size is 2 */
948 					optlen = tcp_opt_buf[i + 1];
949 					if (optlen < 2 || optlen > tcp_optlen) {
950 						PKT_MNGLR_LOG(LOG_ERR, "Received suspicious TCP option");
951 						goto drop_it;
952 					}
953 					tcp_optlen -= optlen;
954 					i += optlen;
955 					continue;
956 				} else if (tcp_opt_buf[i] == TCP_OPT_MULTIPATH_TCP) {
957 					size_t j = 0;
958 					unsigned char mptcpoptlen;
959 					uint8_t sbtver;
960 					uint8_t subtype;
961 
962 					if (tcp_optlen < 3) {
963 						PKT_MNGLR_LOG(LOG_ERR, "Received short MPTCP option");
964 						goto drop_it;
965 					}
966 
967 					/* Minimum MPTCP option size is 3 */
968 					mptcpoptlen = tcp_opt_buf[i + 1];
969 					if (mptcpoptlen < 3 || mptcpoptlen > tcp_optlen) {
970 						PKT_MNGLR_LOG(LOG_ERR, "Received suspicious MPTCP option");
971 						goto drop_it;
972 					}
973 
974 					sbtver = tcp_opt_buf[i + MPTCP_SBT_VER_OFFSET];
975 					subtype = sbtver >> 4;
976 
977 					PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]);
978 					PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP subtype %x\n", subtype);
979 					if (subtype == MPTCP_SUBTYPE_DSS) {
980 						PKT_MNGLR_LOG(LOG_INFO, "Got DSS option\n");
981 						PKT_MNGLR_LOG(LOG_INFO, "Protocol option mask: %d\n", p_pkt_mnglr->proto_action_mask);
982 						if (p_pkt_mnglr->proto_action_mask &
983 						    PKT_MNGLR_TCP_ACT_DSS_DROP) {
984 							goto drop_it;
985 						}
986 					}
987 
988 					PKT_MNGLR_LOG(LOG_INFO, "Got MPTCP option %x\n", tcp_opt_buf[i]);
989 					for (; j < mptcpoptlen && j < tcp_optlen; j++) {
990 						if (p_pkt_mnglr->proto_action_mask &
991 						    PKT_MNGLR_TCP_ACT_NOP_MPTCP) {
992 							tcp_opt_buf[i + j] = 0x1;
993 						}
994 					}
995 					tcp_optlen -= mptcpoptlen;
996 					i += mptcpoptlen;
997 				} else {
998 					tcp_optlen--;
999 					i++;
1000 				}
1001 			}
1002 
1003 			if (orig_tcp_optlen) {
1004 				error = mbuf_copyback(*data,
1005 				    (size_t)offset + sizeof(struct tcphdr),
1006 				    orig_tcp_optlen, tcp_opt_buf, MBUF_WAITOK);
1007 
1008 				if (error) {
1009 					PKT_MNGLR_LOG(LOG_ERR,
1010 					    "Failed to copy tcp options back: error %d offset %d optlen %zu",
1011 					    error, offset, orig_tcp_optlen);
1012 					goto input_done;
1013 				}
1014 			}
1015 		}
1016 		break;
1017 	case IPPROTO_UDP:
1018 		/* Don't handle UDP */
1019 		break;
1020 	case IPPROTO_ICMP:
1021 		break;
1022 	case IPPROTO_ICMPV6:
1023 		break;
1024 	default:
1025 		break;
1026 	}
1027 	chksm_update(*data);
1028 input_done:
1029 	return 0;
1030 
1031 drop_it:
1032 	PKT_MNGLR_LOG(LOG_INFO, "Dropping packet\n");
1033 	mbuf_freem(*data);
1034 	return EJUSTRETURN;
1035 }
1036 
1037 static void
pktmnglr_ipfilter_detach(void * cookie)1038 pktmnglr_ipfilter_detach(void *cookie)
1039 {
1040 #pragma unused(cookie)
1041 	return;
1042 }
1043 
1044 /* XXX Still need to modify this to use mbuf_copy* macros */
1045 static void
chksm_update(mbuf_t data)1046 chksm_update(mbuf_t data)
1047 {
1048 	u_int16_t ip_sum;
1049 	u_int16_t tsum;
1050 	struct tcphdr *tcp;
1051 	errno_t err;
1052 
1053 	unsigned char *ptr = (unsigned char *)mbuf_data(data);
1054 	struct ip *ip = (struct ip *)(void *)ptr;
1055 	if (ip->ip_v != 4) {
1056 		return;
1057 	}
1058 
1059 	ip->ip_sum = 0;
1060 	err = mbuf_inet_cksum(data, 0, 0, ip->ip_hl << 2, &ip_sum); // ip sum
1061 	if (err == 0) {
1062 		ip->ip_sum = ip_sum;
1063 	}
1064 	switch (ip->ip_p) {
1065 	case IPPROTO_TCP:
1066 		tcp = (struct tcphdr *)(void *)(ptr + (ip->ip_hl << 2));
1067 		tcp->th_sum = 0;
1068 		err = mbuf_inet_cksum(data, IPPROTO_TCP, ip->ip_hl << 2,
1069 		        ntohs(ip->ip_len) - (ip->ip_hl << 2), &tsum);
1070 		if (err == 0) {
1071 			tcp->th_sum = tsum;
1072 		}
1073 		break;
1074 	case IPPROTO_UDP:
1075 		/* Don't handle UDP */
1076 		break;
1077 	case IPPROTO_ICMP:
1078 		break;
1079 	case IPPROTO_ICMPV6:
1080 		break;
1081 	default:
1082 		break;
1083 	}
1084 
1085 	mbuf_clear_csum_performed(data);
1086 	return;
1087 }
1088