| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ip_encap.c,v 1.63 2017/04/07 03:31:50 ozaki-r Exp $ */ | | 1 | /* $NetBSD: ip_encap.c,v 1.64 2017/04/15 17:06:45 riastradh Exp $ */ |
2 | /* $KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $ */ | | 2 | /* $KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | /* XXX is M_NETADDR correct? */ | | 58 | /* XXX is M_NETADDR correct? */ |
59 | | | 59 | |
60 | /* | | 60 | /* |
61 | * With USE_RADIX the code will use radix table for tunnel lookup, for | | 61 | * With USE_RADIX the code will use radix table for tunnel lookup, for |
62 | * tunnels registered with encap_attach() with a addr/mask pair. | | 62 | * tunnels registered with encap_attach() with a addr/mask pair. |
63 | * Faster on machines with thousands of tunnel registerations (= interfaces). | | 63 | * Faster on machines with thousands of tunnel registerations (= interfaces). |
64 | * | | 64 | * |
65 | * The code assumes that radix table code can handle non-continuous netmask, | | 65 | * The code assumes that radix table code can handle non-continuous netmask, |
66 | * as it will pass radix table memory region with (src + dst) sockaddr pair. | | 66 | * as it will pass radix table memory region with (src + dst) sockaddr pair. |
67 | */ | | 67 | */ |
68 | #define USE_RADIX | | 68 | #define USE_RADIX |
69 | | | 69 | |
70 | #include <sys/cdefs.h> | | 70 | #include <sys/cdefs.h> |
71 | __KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.63 2017/04/07 03:31:50 ozaki-r Exp $"); | | 71 | __KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.64 2017/04/15 17:06:45 riastradh Exp $"); |
72 | | | 72 | |
73 | #ifdef _KERNEL_OPT | | 73 | #ifdef _KERNEL_OPT |
74 | #include "opt_mrouting.h" | | 74 | #include "opt_mrouting.h" |
75 | #include "opt_inet.h" | | 75 | #include "opt_inet.h" |
76 | #include "opt_net_mpsafe.h" | | 76 | #include "opt_net_mpsafe.h" |
77 | #endif | | 77 | #endif |
78 | | | 78 | |
79 | #include <sys/param.h> | | 79 | #include <sys/param.h> |
80 | #include <sys/systm.h> | | 80 | #include <sys/systm.h> |
81 | #include <sys/socket.h> | | 81 | #include <sys/socket.h> |
82 | #include <sys/sockio.h> | | 82 | #include <sys/sockio.h> |
83 | #include <sys/mbuf.h> | | 83 | #include <sys/mbuf.h> |
84 | #include <sys/errno.h> | | 84 | #include <sys/errno.h> |
| @@ -264,28 +264,26 @@ encap4_lookup(struct mbuf *m, int off, i | | | @@ -264,28 +264,26 @@ encap4_lookup(struct mbuf *m, int off, i |
264 | if (rn && (rn->rn_flags & RNF_ROOT) == 0) { | | 264 | if (rn && (rn->rn_flags & RNF_ROOT) == 0) { |
265 | struct encaptab *encapp = (struct encaptab *)rn; | | 265 | struct encaptab *encapp = (struct encaptab *)rn; |
266 | | | 266 | |
267 | psref_acquire(match_psref, &encapp->psref, | | 267 | psref_acquire(match_psref, &encapp->psref, |
268 | encaptab.elem_class); | | 268 | encaptab.elem_class); |
269 | match = encapp; | | 269 | match = encapp; |
270 | matchprio = mask_matchlen(match->srcmask) + | | 270 | matchprio = mask_matchlen(match->srcmask) + |
271 | mask_matchlen(match->dstmask); | | 271 | mask_matchlen(match->dstmask); |
272 | } | | 272 | } |
273 | #endif | | 273 | #endif |
274 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { | | 274 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { |
275 | struct psref elem_psref; | | 275 | struct psref elem_psref; |
276 | | | 276 | |
277 | membar_datadep_consumer(); | | | |
278 | | | | |
279 | if (ep->af != AF_INET) | | 277 | if (ep->af != AF_INET) |
280 | continue; | | 278 | continue; |
281 | if (ep->proto >= 0 && ep->proto != proto) | | 279 | if (ep->proto >= 0 && ep->proto != proto) |
282 | continue; | | 280 | continue; |
283 | | | 281 | |
284 | psref_acquire(&elem_psref, &ep->psref, | | 282 | psref_acquire(&elem_psref, &ep->psref, |
285 | encaptab.elem_class); | | 283 | encaptab.elem_class); |
286 | if (ep->func) { | | 284 | if (ep->func) { |
287 | pserialize_read_exit(s); | | 285 | pserialize_read_exit(s); |
288 | /* ep->func is sleepable. e.g. rtalloc1 */ | | 286 | /* ep->func is sleepable. e.g. rtalloc1 */ |
289 | prio = (*ep->func)(m, off, proto, ep->arg); | | 287 | prio = (*ep->func)(m, off, proto, ep->arg); |
290 | s = pserialize_read_enter(); | | 288 | s = pserialize_read_enter(); |
291 | } else { | | 289 | } else { |
| @@ -432,28 +430,26 @@ encap6_lookup(struct mbuf *m, int off, i | | | @@ -432,28 +430,26 @@ encap6_lookup(struct mbuf *m, int off, i |
432 | if (rn && (rn->rn_flags & RNF_ROOT) == 0) { | | 430 | if (rn && (rn->rn_flags & RNF_ROOT) == 0) { |
433 | struct encaptab *encapp = (struct encaptab *)rn; | | 431 | struct encaptab *encapp = (struct encaptab *)rn; |
434 | | | 432 | |
435 | psref_acquire(match_psref, &encapp->psref, | | 433 | psref_acquire(match_psref, &encapp->psref, |
436 | encaptab.elem_class); | | 434 | encaptab.elem_class); |
437 | match = encapp; | | 435 | match = encapp; |
438 | matchprio = mask_matchlen(match->srcmask) + | | 436 | matchprio = mask_matchlen(match->srcmask) + |
439 | mask_matchlen(match->dstmask); | | 437 | mask_matchlen(match->dstmask); |
440 | } | | 438 | } |
441 | #endif | | 439 | #endif |
442 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { | | 440 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { |
443 | struct psref elem_psref; | | 441 | struct psref elem_psref; |
444 | | | 442 | |
445 | membar_datadep_consumer(); | | | |
446 | | | | |
447 | if (ep->af != AF_INET6) | | 443 | if (ep->af != AF_INET6) |
448 | continue; | | 444 | continue; |
449 | if (ep->proto >= 0 && ep->proto != proto) | | 445 | if (ep->proto >= 0 && ep->proto != proto) |
450 | continue; | | 446 | continue; |
451 | | | 447 | |
452 | psref_acquire(&elem_psref, &ep->psref, | | 448 | psref_acquire(&elem_psref, &ep->psref, |
453 | encaptab.elem_class); | | 449 | encaptab.elem_class); |
454 | | | 450 | |
455 | if (ep->func) { | | 451 | if (ep->func) { |
456 | pserialize_read_exit(s); | | 452 | pserialize_read_exit(s); |
457 | /* ep->func is sleepable. e.g. rtalloc1 */ | | 453 | /* ep->func is sleepable. e.g. rtalloc1 */ |
458 | prio = (*ep->func)(m, off, proto, ep->arg); | | 454 | prio = (*ep->func)(m, off, proto, ep->arg); |
459 | s = pserialize_read_enter(); | | 455 | s = pserialize_read_enter(); |
| @@ -668,28 +664,26 @@ encap_attach(int af, int proto, | | | @@ -668,28 +664,26 @@ encap_attach(int af, int proto, |
668 | #ifndef ENCAP_MPSAFE | | 664 | #ifndef ENCAP_MPSAFE |
669 | int s; | | 665 | int s; |
670 | | | 666 | |
671 | s = splsoftnet(); | | 667 | s = splsoftnet(); |
672 | #endif | | 668 | #endif |
673 | /* sanity check on args */ | | 669 | /* sanity check on args */ |
674 | error = encap_afcheck(af, sp, dp); | | 670 | error = encap_afcheck(af, sp, dp); |
675 | if (error) | | 671 | if (error) |
676 | goto fail; | | 672 | goto fail; |
677 | | | 673 | |
678 | /* check if anyone have already attached with exactly same config */ | | 674 | /* check if anyone have already attached with exactly same config */ |
679 | pss = pserialize_read_enter(); | | 675 | pss = pserialize_read_enter(); |
680 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { | | 676 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { |
681 | membar_datadep_consumer(); | | | |
682 | | | | |
683 | if (ep->af != af) | | 677 | if (ep->af != af) |
684 | continue; | | 678 | continue; |
685 | if (ep->proto != proto) | | 679 | if (ep->proto != proto) |
686 | continue; | | 680 | continue; |
687 | if (ep->func) | | 681 | if (ep->func) |
688 | continue; | | 682 | continue; |
689 | | | 683 | |
690 | KASSERT(ep->src != NULL); | | 684 | KASSERT(ep->src != NULL); |
691 | KASSERT(ep->dst != NULL); | | 685 | KASSERT(ep->dst != NULL); |
692 | KASSERT(ep->srcmask != NULL); | | 686 | KASSERT(ep->srcmask != NULL); |
693 | KASSERT(ep->dstmask != NULL); | | 687 | KASSERT(ep->dstmask != NULL); |
694 | | | 688 | |
695 | if (ep->src->sa_len != sp->sa_len || | | 689 | if (ep->src->sa_len != sp->sa_len || |
| @@ -910,28 +904,26 @@ encap6_ctlinput(int cmd, const struct so | | | @@ -910,28 +904,26 @@ encap6_ctlinput(int cmd, const struct so |
910 | } | | 904 | } |
911 | } else { | | 905 | } else { |
912 | m = NULL; | | 906 | m = NULL; |
913 | ip6 = NULL; | | 907 | ip6 = NULL; |
914 | nxt = -1; | | 908 | nxt = -1; |
915 | } | | 909 | } |
916 | | | 910 | |
917 | /* inform all listeners */ | | 911 | /* inform all listeners */ |
918 | | | 912 | |
919 | s = pserialize_read_enter(); | | 913 | s = pserialize_read_enter(); |
920 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { | | 914 | PSLIST_READER_FOREACH(ep, &encap_table, struct encaptab, chain) { |
921 | struct psref elem_psref; | | 915 | struct psref elem_psref; |
922 | | | 916 | |
923 | membar_datadep_consumer(); | | | |
924 | | | | |
925 | if (ep->af != AF_INET6) | | 917 | if (ep->af != AF_INET6) |
926 | continue; | | 918 | continue; |
927 | if (ep->proto >= 0 && ep->proto != nxt) | | 919 | if (ep->proto >= 0 && ep->proto != nxt) |
928 | continue; | | 920 | continue; |
929 | | | 921 | |
930 | /* should optimize by looking at address pairs */ | | 922 | /* should optimize by looking at address pairs */ |
931 | | | 923 | |
932 | /* XXX need to pass ep->arg or ep itself to listeners */ | | 924 | /* XXX need to pass ep->arg or ep itself to listeners */ |
933 | psref_acquire(&elem_psref, &ep->psref, | | 925 | psref_acquire(&elem_psref, &ep->psref, |
934 | encaptab.elem_class); | | 926 | encaptab.elem_class); |
935 | esw = ep->esw; | | 927 | esw = ep->esw; |
936 | if (esw && esw->encapsw6.pr_ctlinput) { | | 928 | if (esw && esw->encapsw6.pr_ctlinput) { |
937 | pserialize_read_exit(s); | | 929 | pserialize_read_exit(s); |
| @@ -949,28 +941,26 @@ encap6_ctlinput(int cmd, const struct so | | | @@ -949,28 +941,26 @@ encap6_ctlinput(int cmd, const struct so |
949 | } | | 941 | } |
950 | #endif | | 942 | #endif |
951 | | | 943 | |
952 | int | | 944 | int |
953 | encap_detach(const struct encaptab *cookie) | | 945 | encap_detach(const struct encaptab *cookie) |
954 | { | | 946 | { |
955 | const struct encaptab *ep = cookie; | | 947 | const struct encaptab *ep = cookie; |
956 | struct encaptab *p; | | 948 | struct encaptab *p; |
957 | int error; | | 949 | int error; |
958 | | | 950 | |
959 | KASSERT(encap_lock_held()); | | 951 | KASSERT(encap_lock_held()); |
960 | | | 952 | |
961 | PSLIST_WRITER_FOREACH(p, &encap_table, struct encaptab, chain) { | | 953 | PSLIST_WRITER_FOREACH(p, &encap_table, struct encaptab, chain) { |
962 | membar_datadep_consumer(); | | | |
963 | | | | |
964 | if (p == ep) { | | 954 | if (p == ep) { |
965 | error = encap_remove(p); | | 955 | error = encap_remove(p); |
966 | if (error) | | 956 | if (error) |
967 | return error; | | 957 | return error; |
968 | else | | 958 | else |
969 | break; | | 959 | break; |
970 | } | | 960 | } |
971 | } | | 961 | } |
972 | if (p == NULL) | | 962 | if (p == NULL) |
973 | return ENOENT; | | 963 | return ENOENT; |
974 | | | 964 | |
975 | pserialize_perform(encaptab.psz); | | 965 | pserialize_perform(encaptab.psz); |
976 | psref_target_destroy(&p->psref, | | 966 | psref_target_destroy(&p->psref, |