| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: npf_inet.c,v 1.40 2018/03/13 09:04:02 maxv Exp $ */ | | 1 | /* $NetBSD: npf_inet.c,v 1.41 2018/03/13 16:23:40 maxv Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2009-2014 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2009-2014 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This material is based upon work partially supported by The | | 7 | * This material is based upon work partially supported by The |
8 | * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. | | 8 | * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -30,27 +30,27 @@ | | | @@ -30,27 +30,27 @@ |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Various protocol related helper routines. | | 33 | * Various protocol related helper routines. |
34 | * | | 34 | * |
35 | * This layer manipulates npf_cache_t structure i.e. caches requested headers | | 35 | * This layer manipulates npf_cache_t structure i.e. caches requested headers |
36 | * and stores which information was cached in the information bit field. | | 36 | * and stores which information was cached in the information bit field. |
37 | * It is also responsibility of this layer to update or invalidate the cache | | 37 | * It is also responsibility of this layer to update or invalidate the cache |
38 | * on rewrites (e.g. by translation routines). | | 38 | * on rewrites (e.g. by translation routines). |
39 | */ | | 39 | */ |
40 | | | 40 | |
41 | #ifdef _KERNEL | | 41 | #ifdef _KERNEL |
42 | #include <sys/cdefs.h> | | 42 | #include <sys/cdefs.h> |
43 | __KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.40 2018/03/13 09:04:02 maxv Exp $"); | | 43 | __KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.41 2018/03/13 16:23:40 maxv Exp $"); |
44 | | | 44 | |
45 | #include <sys/param.h> | | 45 | #include <sys/param.h> |
46 | #include <sys/types.h> | | 46 | #include <sys/types.h> |
47 | | | 47 | |
48 | #include <net/pfil.h> | | 48 | #include <net/pfil.h> |
49 | #include <net/if.h> | | 49 | #include <net/if.h> |
50 | #include <net/ethertypes.h> | | 50 | #include <net/ethertypes.h> |
51 | #include <net/if_ether.h> | | 51 | #include <net/if_ether.h> |
52 | | | 52 | |
53 | #include <netinet/in_systm.h> | | 53 | #include <netinet/in_systm.h> |
54 | #include <netinet/in.h> | | 54 | #include <netinet/in.h> |
55 | #include <netinet6/in6_var.h> | | 55 | #include <netinet6/in6_var.h> |
56 | #include <netinet/ip.h> | | 56 | #include <netinet/ip.h> |
| @@ -382,26 +382,33 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *n | | | @@ -382,26 +382,33 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *n |
382 | switch (npc->npc_proto) { | | 382 | switch (npc->npc_proto) { |
383 | case IPPROTO_HOPOPTS: | | 383 | case IPPROTO_HOPOPTS: |
384 | case IPPROTO_DSTOPTS: | | 384 | case IPPROTO_DSTOPTS: |
385 | case IPPROTO_ROUTING: | | 385 | case IPPROTO_ROUTING: |
386 | hlen = (ip6e->ip6e_len + 1) << 3; | | 386 | hlen = (ip6e->ip6e_len + 1) << 3; |
387 | break; | | 387 | break; |
388 | case IPPROTO_FRAGMENT: | | 388 | case IPPROTO_FRAGMENT: |
389 | if (frag_present++) | | 389 | if (frag_present++) |
390 | return NPC_FMTERR; | | 390 | return NPC_FMTERR; |
391 | ip6f = nbuf_ensure_contig(nbuf, sizeof(*ip6f)); | | 391 | ip6f = nbuf_ensure_contig(nbuf, sizeof(*ip6f)); |
392 | if (ip6f == NULL) | | 392 | if (ip6f == NULL) |
393 | return NPC_FMTERR; | | 393 | return NPC_FMTERR; |
394 | | | 394 | |
| | | 395 | /* RFC6946: Skip dummy fragments. */ |
| | | 396 | if (!ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK) && |
| | | 397 | !(ip6f->ip6f_offlg & IP6F_MORE_FRAG)) { |
| | | 398 | hlen = sizeof(struct ip6_frag); |
| | | 399 | break; |
| | | 400 | } |
| | | 401 | |
395 | hlen = 0; | | 402 | hlen = 0; |
396 | flags |= NPC_IPFRAG; | | 403 | flags |= NPC_IPFRAG; |
397 | | | 404 | |
398 | break; | | 405 | break; |
399 | case IPPROTO_AH: | | 406 | case IPPROTO_AH: |
400 | hlen = (ip6e->ip6e_len + 2) << 2; | | 407 | hlen = (ip6e->ip6e_len + 2) << 2; |
401 | break; | | 408 | break; |
402 | default: | | 409 | default: |
403 | hlen = 0; | | 410 | hlen = 0; |
404 | break; | | 411 | break; |
405 | } | | 412 | } |
406 | | | 413 | |
407 | if (!hlen) { | | 414 | if (!hlen) { |