Blame view
net/ipv6/xfrm6_state.c
4.58 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 |
/* * xfrm6_state.c: based on xfrm4_state.c * * Authors: * Mitsuru KANDA @USAGI * Kazunori MIYAZAWA @USAGI * Kunihiro Ishiguro <kunihiro@ipinfusion.com> * IPv6 support * YOSHIFUJI Hideaki @USAGI * Split up af-specific portion |
1ab1457c4 [NET] IPV6: Fix w... |
11 |
* |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 15 16 |
*/ #include <net/xfrm.h> #include <linux/pfkeyv2.h> #include <linux/ipsec.h> |
862b82c6f [IPSEC]: Merge mo... |
17 |
#include <linux/netfilter_ipv6.h> |
bc3b2d7fb net: Add export.h... |
18 |
#include <linux/export.h> |
36cf9acf9 [IPSEC]: Separate... |
19 |
#include <net/dsfield.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include <net/ipv6.h> |
ee51b1b6c [XFRM]: IPsec tun... |
21 |
#include <net/addrconf.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
1da177e4c Linux-2.6.12-rc2 |
23 |
static void |
73e5ebb20 xfrm: Mark flowi ... |
24 |
__xfrm6_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl) |
1da177e4c Linux-2.6.12-rc2 |
25 |
{ |
7e1dc7b6f net: Use flowi4 a... |
26 |
const struct flowi6 *fl6 = &fl->u.ip6; |
1da177e4c Linux-2.6.12-rc2 |
27 28 |
/* Initialize temporary selector matching only * to current session. */ |
4e3fd7a06 net: remove ipv6_... |
29 30 |
*(struct in6_addr *)&sel->daddr = fl6->daddr; *(struct in6_addr *)&sel->saddr = fl6->saddr; |
7e1dc7b6f net: Use flowi4 a... |
31 |
sel->dport = xfrm_flowi_dport(fl, &fl6->uli); |
8444cf712 xfrm: Allow diffe... |
32 |
sel->dport_mask = htons(0xffff); |
7e1dc7b6f net: Use flowi4 a... |
33 |
sel->sport = xfrm_flowi_sport(fl, &fl6->uli); |
8444cf712 xfrm: Allow diffe... |
34 35 36 37 |
sel->sport_mask = htons(0xffff); sel->family = AF_INET6; sel->prefixlen_d = 128; sel->prefixlen_s = 128; |
7e1dc7b6f net: Use flowi4 a... |
38 39 |
sel->proto = fl6->flowi6_proto; sel->ifindex = fl6->flowi6_oif; |
8444cf712 xfrm: Allow diffe... |
40 41 42 |
} static void |
19bd62441 xfrm: Const'ify t... |
43 44 |
xfrm6_init_temprop(struct xfrm_state *x, const struct xfrm_tmpl *tmpl, const xfrm_address_t *daddr, const xfrm_address_t *saddr) |
8444cf712 xfrm: Allow diffe... |
45 |
{ |
1da177e4c Linux-2.6.12-rc2 |
46 47 48 49 50 51 52 53 54 55 |
x->id = tmpl->id; if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr)); if (ipv6_addr_any((struct in6_addr*)&x->props.saddr)) memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr)); x->props.mode = tmpl->mode; x->props.reqid = tmpl->reqid; x->props.family = AF_INET6; } |
3b6cdf94c [XFRM] IPV6: Use ... |
56 |
/* distribution counting sort function for xfrm_state and xfrm_tmpl */ |
58c949d1b [XFRM] IPV6: Add ... |
57 |
static int |
3b6cdf94c [XFRM] IPV6: Use ... |
58 |
__xfrm6_sort(void **dst, void **src, int n, int (*cmp)(void *p), int maxclass) |
58c949d1b [XFRM] IPV6: Add ... |
59 60 |
{ int i; |
3b6cdf94c [XFRM] IPV6: Use ... |
61 62 |
int class[XFRM_MAX_DEPTH]; int count[maxclass]; |
58c949d1b [XFRM] IPV6: Add ... |
63 |
|
3b6cdf94c [XFRM] IPV6: Use ... |
64 |
memset(count, 0, sizeof(count)); |
58c949d1b [XFRM] IPV6: Add ... |
65 |
|
64d9fdda8 [XFRM] IPV6: Supp... |
66 |
for (i = 0; i < n; i++) { |
3b6cdf94c [XFRM] IPV6: Use ... |
67 68 69 |
int c; class[i] = c = cmp(src[i]); count[c]++; |
64d9fdda8 [XFRM] IPV6: Supp... |
70 |
} |
58c949d1b [XFRM] IPV6: Add ... |
71 |
|
3b6cdf94c [XFRM] IPV6: Use ... |
72 73 |
for (i = 2; i < maxclass; i++) count[i] += count[i - 1]; |
58c949d1b [XFRM] IPV6: Add ... |
74 |
|
58c949d1b [XFRM] IPV6: Add ... |
75 |
for (i = 0; i < n; i++) { |
3b6cdf94c [XFRM] IPV6: Use ... |
76 |
dst[count[class[i] - 1]++] = src[i]; |
66da8c529 ipv6: fix sparse ... |
77 |
src[i] = NULL; |
58c949d1b [XFRM] IPV6: Add ... |
78 |
} |
58c949d1b [XFRM] IPV6: Add ... |
79 |
|
58c949d1b [XFRM] IPV6: Add ... |
80 81 |
return 0; } |
3b6cdf94c [XFRM] IPV6: Use ... |
82 83 84 85 86 87 88 89 90 91 |
/* * Rule for xfrm_state: * * rule 1: select IPsec transport except AH * rule 2: select MIPv6 RO or inbound trigger * rule 3: select IPsec transport AH * rule 4: select IPsec tunnel * rule 5: others */ static int __xfrm6_state_sort_cmp(void *p) |
58c949d1b [XFRM] IPV6: Add ... |
92 |
{ |
3b6cdf94c [XFRM] IPV6: Use ... |
93 94 95 96 97 98 99 100 |
struct xfrm_state *v = p; switch (v->props.mode) { case XFRM_MODE_TRANSPORT: if (v->id.proto != IPPROTO_AH) return 1; else return 3; |
07a936260 ipv6: use IS_ENAB... |
101 |
#if IS_ENABLED(CONFIG_IPV6_MIP6) |
3b6cdf94c [XFRM] IPV6: Use ... |
102 103 104 |
case XFRM_MODE_ROUTEOPTIMIZATION: case XFRM_MODE_IN_TRIGGER: return 2; |
64d9fdda8 [XFRM] IPV6: Supp... |
105 |
#endif |
3b6cdf94c [XFRM] IPV6: Use ... |
106 107 108 |
case XFRM_MODE_TUNNEL: case XFRM_MODE_BEET: return 4; |
58c949d1b [XFRM] IPV6: Add ... |
109 |
} |
3b6cdf94c [XFRM] IPV6: Use ... |
110 111 |
return 5; } |
58c949d1b [XFRM] IPV6: Add ... |
112 |
|
3b6cdf94c [XFRM] IPV6: Use ... |
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
static int __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n) { return __xfrm6_sort((void **)dst, (void **)src, n, __xfrm6_state_sort_cmp, 6); } /* * Rule for xfrm_tmpl: * * rule 1: select IPsec transport * rule 2: select MIPv6 RO or inbound trigger * rule 3: select IPsec tunnel * rule 4: others */ static int __xfrm6_tmpl_sort_cmp(void *p) { struct xfrm_tmpl *v = p; switch (v->mode) { case XFRM_MODE_TRANSPORT: return 1; |
07a936260 ipv6: use IS_ENAB... |
134 |
#if IS_ENABLED(CONFIG_IPV6_MIP6) |
3b6cdf94c [XFRM] IPV6: Use ... |
135 136 137 138 139 140 141 |
case XFRM_MODE_ROUTEOPTIMIZATION: case XFRM_MODE_IN_TRIGGER: return 2; #endif case XFRM_MODE_TUNNEL: case XFRM_MODE_BEET: return 3; |
58c949d1b [XFRM] IPV6: Add ... |
142 |
} |
3b6cdf94c [XFRM] IPV6: Use ... |
143 144 |
return 4; } |
58c949d1b [XFRM] IPV6: Add ... |
145 |
|
3b6cdf94c [XFRM] IPV6: Use ... |
146 147 148 149 150 |
static int __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n) { return __xfrm6_sort((void **)dst, (void **)src, n, __xfrm6_tmpl_sort_cmp, 5); |
58c949d1b [XFRM] IPV6: Add ... |
151 |
} |
36cf9acf9 [IPSEC]: Separate... |
152 153 154 |
int xfrm6_extract_header(struct sk_buff *skb) { struct ipv6hdr *iph = ipv6_hdr(skb); |
732c8bd59 [IPSEC]: Fix BEET... |
155 |
XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); |
36cf9acf9 [IPSEC]: Separate... |
156 157 158 159 |
XFRM_MODE_SKB_CB(skb)->id = 0; XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; |
732c8bd59 [IPSEC]: Fix BEET... |
160 |
XFRM_MODE_SKB_CB(skb)->optlen = 0; |
36cf9acf9 [IPSEC]: Separate... |
161 162 163 164 165 |
memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
166 167 |
static struct xfrm_state_afinfo xfrm6_state_afinfo = { .family = AF_INET6, |
36cf9acf9 [IPSEC]: Separate... |
168 |
.proto = IPPROTO_IPV6, |
227620e29 [IPSEC]: Separate... |
169 |
.eth_proto = htons(ETH_P_IPV6), |
17c2a42a2 [IPSEC]: Store af... |
170 |
.owner = THIS_MODULE, |
1da177e4c Linux-2.6.12-rc2 |
171 |
.init_tempsel = __xfrm6_init_tempsel, |
8444cf712 xfrm: Allow diffe... |
172 |
.init_temprop = xfrm6_init_temprop, |
58c949d1b [XFRM] IPV6: Add ... |
173 174 |
.tmpl_sort = __xfrm6_tmpl_sort, .state_sort = __xfrm6_state_sort, |
cdca72652 [IPSEC]: exportin... |
175 |
.output = xfrm6_output, |
43a4dea4c xfrm: Assign the ... |
176 |
.output_finish = xfrm6_output_finish, |
227620e29 [IPSEC]: Separate... |
177 |
.extract_input = xfrm6_extract_input, |
36cf9acf9 [IPSEC]: Separate... |
178 |
.extract_output = xfrm6_extract_output, |
716062fd4 [IPSEC]: Merge mo... |
179 |
.transport_finish = xfrm6_transport_finish, |
1da177e4c Linux-2.6.12-rc2 |
180 |
}; |
0013cabab [IPV6]: Make xfrm... |
181 |
int __init xfrm6_state_init(void) |
1da177e4c Linux-2.6.12-rc2 |
182 |
{ |
0013cabab [IPV6]: Make xfrm... |
183 |
return xfrm_state_register_afinfo(&xfrm6_state_afinfo); |
1da177e4c Linux-2.6.12-rc2 |
184 185 186 187 188 189 |
} void xfrm6_state_fini(void) { xfrm_state_unregister_afinfo(&xfrm6_state_afinfo); } |