1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C)2003-2006 Helsinki University of Technology
4 * Copyright (C)2003-2006 USAGI/WIDE Project
8 * Noriaki TAKAMIYA @USAGI
9 * Masahide NAKAMURA @USAGI
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/module.h>
15 #include <linux/skbuff.h>
16 #include <linux/time.h>
17 #include <linux/ipv6.h>
18 #include <linux/icmpv6.h>
21 #include <net/ip6_checksum.h>
22 #include <net/rawv6.h>
26 static inline unsigned int calc_padlen(unsigned int len
, unsigned int n
)
28 return (n
- len
+ 16) & 0x7;
31 static inline void *mip6_padn(__u8
*data
, __u8 padlen
)
36 data
[0] = IPV6_TLV_PAD1
;
37 } else if (padlen
> 1) {
38 data
[0] = IPV6_TLV_PADN
;
41 memset(data
+2, 0, data
[1]);
46 static inline void mip6_param_prob(struct sk_buff
*skb
, u8 code
, int pos
)
48 icmpv6_send(skb
, ICMPV6_PARAMPROB
, code
, pos
);
51 static int mip6_mh_len(int type
)
59 case IP6_MH_TYPE_HOTI
:
60 case IP6_MH_TYPE_COTI
:
62 case IP6_MH_TYPE_BACK
:
67 case IP6_MH_TYPE_BERROR
:
74 static int mip6_mh_filter(struct sock
*sk
, struct sk_buff
*skb
)
77 const struct ip6_mh
*mh
;
79 mh
= skb_header_pointer(skb
, skb_transport_offset(skb
),
84 if (((mh
->ip6mh_hdrlen
+ 1) << 3) > skb
->len
)
87 if (mh
->ip6mh_hdrlen
< mip6_mh_len(mh
->ip6mh_type
)) {
88 net_dbg_ratelimited("mip6: MH message too short: %d vs >=%d\n",
90 mip6_mh_len(mh
->ip6mh_type
));
91 mip6_param_prob(skb
, 0, offsetof(struct ip6_mh
, ip6mh_hdrlen
) +
92 skb_network_header_len(skb
));
96 if (mh
->ip6mh_proto
!= IPPROTO_NONE
) {
97 net_dbg_ratelimited("mip6: MH invalid payload proto = %d\n",
99 mip6_param_prob(skb
, 0, offsetof(struct ip6_mh
, ip6mh_proto
) +
100 skb_network_header_len(skb
));
107 struct mip6_report_rate_limiter
{
115 static struct mip6_report_rate_limiter mip6_report_rl
= {
116 .lock
= __SPIN_LOCK_UNLOCKED(mip6_report_rl
.lock
)
119 static int mip6_destopt_input(struct xfrm_state
*x
, struct sk_buff
*skb
)
121 const struct ipv6hdr
*iph
= ipv6_hdr(skb
);
122 struct ipv6_destopt_hdr
*destopt
= (struct ipv6_destopt_hdr
*)skb
->data
;
123 int err
= destopt
->nexthdr
;
126 if (!ipv6_addr_equal(&iph
->saddr
, (struct in6_addr
*)x
->coaddr
) &&
127 !ipv6_addr_any((struct in6_addr
*)x
->coaddr
))
129 spin_unlock(&x
->lock
);
134 /* Destination Option Header is inserted.
135 * IP Header's src address is replaced with Home Address Option in
136 * Destination Option Header.
138 static int mip6_destopt_output(struct xfrm_state
*x
, struct sk_buff
*skb
)
141 struct ipv6_destopt_hdr
*dstopt
;
142 struct ipv6_destopt_hao
*hao
;
146 skb_push(skb
, -skb_network_offset(skb
));
149 nexthdr
= *skb_mac_header(skb
);
150 *skb_mac_header(skb
) = IPPROTO_DSTOPTS
;
152 dstopt
= (struct ipv6_destopt_hdr
*)skb_transport_header(skb
);
153 dstopt
->nexthdr
= nexthdr
;
155 hao
= mip6_padn((char *)(dstopt
+ 1),
156 calc_padlen(sizeof(*dstopt
), 6));
158 hao
->type
= IPV6_TLV_HAO
;
159 BUILD_BUG_ON(sizeof(*hao
) != 18);
160 hao
->length
= sizeof(*hao
) - 2;
162 len
= ((char *)hao
- (char *)dstopt
) + sizeof(*hao
);
164 memcpy(&hao
->addr
, &iph
->saddr
, sizeof(hao
->addr
));
165 spin_lock_bh(&x
->lock
);
166 memcpy(&iph
->saddr
, x
->coaddr
, sizeof(iph
->saddr
));
167 spin_unlock_bh(&x
->lock
);
169 WARN_ON(len
!= x
->props
.header_len
);
170 dstopt
->hdrlen
= (x
->props
.header_len
>> 3) - 1;
175 static inline int mip6_report_rl_allow(ktime_t stamp
,
176 const struct in6_addr
*dst
,
177 const struct in6_addr
*src
, int iif
)
181 spin_lock_bh(&mip6_report_rl
.lock
);
182 if (mip6_report_rl
.stamp
!= stamp
||
183 mip6_report_rl
.iif
!= iif
||
184 !ipv6_addr_equal(&mip6_report_rl
.src
, src
) ||
185 !ipv6_addr_equal(&mip6_report_rl
.dst
, dst
)) {
186 mip6_report_rl
.stamp
= stamp
;
187 mip6_report_rl
.iif
= iif
;
188 mip6_report_rl
.src
= *src
;
189 mip6_report_rl
.dst
= *dst
;
192 spin_unlock_bh(&mip6_report_rl
.lock
);
196 static int mip6_destopt_reject(struct xfrm_state
*x
, struct sk_buff
*skb
,
197 const struct flowi
*fl
)
199 struct net
*net
= xs_net(x
);
200 struct inet6_skb_parm
*opt
= (struct inet6_skb_parm
*)skb
->cb
;
201 const struct flowi6
*fl6
= &fl
->u
.ip6
;
202 struct ipv6_destopt_hao
*hao
= NULL
;
203 struct xfrm_selector sel
;
208 if (unlikely(fl6
->flowi6_proto
== IPPROTO_MH
&&
209 fl6
->fl6_mh_type
<= IP6_MH_TYPE_MAX
))
212 if (likely(opt
->dsthao
)) {
213 offset
= ipv6_find_tlv(skb
, opt
->dsthao
, IPV6_TLV_HAO
);
214 if (likely(offset
>= 0))
215 hao
= (struct ipv6_destopt_hao
*)
216 (skb_network_header(skb
) + offset
);
219 stamp
= skb_get_ktime(skb
);
221 if (!mip6_report_rl_allow(stamp
, &ipv6_hdr(skb
)->daddr
,
222 hao
? &hao
->addr
: &ipv6_hdr(skb
)->saddr
,
226 memset(&sel
, 0, sizeof(sel
));
227 memcpy(&sel
.daddr
, (xfrm_address_t
*)&ipv6_hdr(skb
)->daddr
,
229 sel
.prefixlen_d
= 128;
230 memcpy(&sel
.saddr
, (xfrm_address_t
*)&ipv6_hdr(skb
)->saddr
,
232 sel
.prefixlen_s
= 128;
233 sel
.family
= AF_INET6
;
234 sel
.proto
= fl6
->flowi6_proto
;
235 sel
.dport
= xfrm_flowi_dport(fl
, &fl6
->uli
);
237 sel
.dport_mask
= htons(~0);
238 sel
.sport
= xfrm_flowi_sport(fl
, &fl6
->uli
);
240 sel
.sport_mask
= htons(~0);
241 sel
.ifindex
= fl6
->flowi6_oif
;
243 err
= km_report(net
, IPPROTO_DSTOPTS
, &sel
,
244 (hao
? (xfrm_address_t
*)&hao
->addr
: NULL
));
250 static int mip6_destopt_offset(struct xfrm_state
*x
, struct sk_buff
*skb
,
253 u16 offset
= sizeof(struct ipv6hdr
);
254 struct ipv6_opt_hdr
*exthdr
=
255 (struct ipv6_opt_hdr
*)(ipv6_hdr(skb
) + 1);
256 const unsigned char *nh
= skb_network_header(skb
);
257 unsigned int packet_len
= skb_tail_pointer(skb
) -
258 skb_network_header(skb
);
261 *nexthdr
= &ipv6_hdr(skb
)->nexthdr
;
263 while (offset
+ 1 <= packet_len
) {
268 case NEXTHDR_ROUTING
:
273 * HAO MUST NOT appear more than once.
274 * XXX: It is better to try to find by the end of
275 * XXX: packet if HAO exists.
277 if (ipv6_find_tlv(skb
, offset
, IPV6_TLV_HAO
) >= 0) {
278 net_dbg_ratelimited("mip6: hao exists already, override\n");
290 offset
+= ipv6_optlen(exthdr
);
291 *nexthdr
= &exthdr
->nexthdr
;
292 exthdr
= (struct ipv6_opt_hdr
*)(nh
+ offset
);
298 static int mip6_destopt_init_state(struct xfrm_state
*x
)
301 pr_info("%s: spi is not 0: %u\n", __func__
, x
->id
.spi
);
304 if (x
->props
.mode
!= XFRM_MODE_ROUTEOPTIMIZATION
) {
305 pr_info("%s: state's mode is not %u: %u\n",
306 __func__
, XFRM_MODE_ROUTEOPTIMIZATION
, x
->props
.mode
);
310 x
->props
.header_len
= sizeof(struct ipv6_destopt_hdr
) +
311 calc_padlen(sizeof(struct ipv6_destopt_hdr
), 6) +
312 sizeof(struct ipv6_destopt_hao
);
313 WARN_ON(x
->props
.header_len
!= 24);
319 * Do nothing about destroying since it has no specific operation for
320 * destination options header unlike IPsec protocols.
322 static void mip6_destopt_destroy(struct xfrm_state
*x
)
326 static const struct xfrm_type mip6_destopt_type
= {
327 .description
= "MIP6DESTOPT",
328 .owner
= THIS_MODULE
,
329 .proto
= IPPROTO_DSTOPTS
,
330 .flags
= XFRM_TYPE_NON_FRAGMENT
| XFRM_TYPE_LOCAL_COADDR
,
331 .init_state
= mip6_destopt_init_state
,
332 .destructor
= mip6_destopt_destroy
,
333 .input
= mip6_destopt_input
,
334 .output
= mip6_destopt_output
,
335 .reject
= mip6_destopt_reject
,
336 .hdr_offset
= mip6_destopt_offset
,
339 static int mip6_rthdr_input(struct xfrm_state
*x
, struct sk_buff
*skb
)
341 const struct ipv6hdr
*iph
= ipv6_hdr(skb
);
342 struct rt2_hdr
*rt2
= (struct rt2_hdr
*)skb
->data
;
343 int err
= rt2
->rt_hdr
.nexthdr
;
346 if (!ipv6_addr_equal(&iph
->daddr
, (struct in6_addr
*)x
->coaddr
) &&
347 !ipv6_addr_any((struct in6_addr
*)x
->coaddr
))
349 spin_unlock(&x
->lock
);
354 /* Routing Header type 2 is inserted.
355 * IP Header's dst address is replaced with Routing Header's Home Address.
357 static int mip6_rthdr_output(struct xfrm_state
*x
, struct sk_buff
*skb
)
363 skb_push(skb
, -skb_network_offset(skb
));
366 nexthdr
= *skb_mac_header(skb
);
367 *skb_mac_header(skb
) = IPPROTO_ROUTING
;
369 rt2
= (struct rt2_hdr
*)skb_transport_header(skb
);
370 rt2
->rt_hdr
.nexthdr
= nexthdr
;
371 rt2
->rt_hdr
.hdrlen
= (x
->props
.header_len
>> 3) - 1;
372 rt2
->rt_hdr
.type
= IPV6_SRCRT_TYPE_2
;
373 rt2
->rt_hdr
.segments_left
= 1;
374 memset(&rt2
->reserved
, 0, sizeof(rt2
->reserved
));
376 WARN_ON(rt2
->rt_hdr
.hdrlen
!= 2);
378 memcpy(&rt2
->addr
, &iph
->daddr
, sizeof(rt2
->addr
));
379 spin_lock_bh(&x
->lock
);
380 memcpy(&iph
->daddr
, x
->coaddr
, sizeof(iph
->daddr
));
381 spin_unlock_bh(&x
->lock
);
386 static int mip6_rthdr_offset(struct xfrm_state
*x
, struct sk_buff
*skb
,
389 u16 offset
= sizeof(struct ipv6hdr
);
390 struct ipv6_opt_hdr
*exthdr
=
391 (struct ipv6_opt_hdr
*)(ipv6_hdr(skb
) + 1);
392 const unsigned char *nh
= skb_network_header(skb
);
393 unsigned int packet_len
= skb_tail_pointer(skb
) -
394 skb_network_header(skb
);
397 *nexthdr
= &ipv6_hdr(skb
)->nexthdr
;
399 while (offset
+ 1 <= packet_len
) {
404 case NEXTHDR_ROUTING
:
405 if (offset
+ 3 <= packet_len
) {
406 struct ipv6_rt_hdr
*rt
;
407 rt
= (struct ipv6_rt_hdr
*)(nh
+ offset
);
414 if (ipv6_find_tlv(skb
, offset
, IPV6_TLV_HAO
) >= 0)
425 offset
+= ipv6_optlen(exthdr
);
426 *nexthdr
= &exthdr
->nexthdr
;
427 exthdr
= (struct ipv6_opt_hdr
*)(nh
+ offset
);
433 static int mip6_rthdr_init_state(struct xfrm_state
*x
)
436 pr_info("%s: spi is not 0: %u\n", __func__
, x
->id
.spi
);
439 if (x
->props
.mode
!= XFRM_MODE_ROUTEOPTIMIZATION
) {
440 pr_info("%s: state's mode is not %u: %u\n",
441 __func__
, XFRM_MODE_ROUTEOPTIMIZATION
, x
->props
.mode
);
445 x
->props
.header_len
= sizeof(struct rt2_hdr
);
451 * Do nothing about destroying since it has no specific operation for routing
452 * header type 2 unlike IPsec protocols.
454 static void mip6_rthdr_destroy(struct xfrm_state
*x
)
458 static const struct xfrm_type mip6_rthdr_type
= {
459 .description
= "MIP6RT",
460 .owner
= THIS_MODULE
,
461 .proto
= IPPROTO_ROUTING
,
462 .flags
= XFRM_TYPE_NON_FRAGMENT
| XFRM_TYPE_REMOTE_COADDR
,
463 .init_state
= mip6_rthdr_init_state
,
464 .destructor
= mip6_rthdr_destroy
,
465 .input
= mip6_rthdr_input
,
466 .output
= mip6_rthdr_output
,
467 .hdr_offset
= mip6_rthdr_offset
,
470 static int __init
mip6_init(void)
472 pr_info("Mobile IPv6\n");
474 if (xfrm_register_type(&mip6_destopt_type
, AF_INET6
) < 0) {
475 pr_info("%s: can't add xfrm type(destopt)\n", __func__
);
476 goto mip6_destopt_xfrm_fail
;
478 if (xfrm_register_type(&mip6_rthdr_type
, AF_INET6
) < 0) {
479 pr_info("%s: can't add xfrm type(rthdr)\n", __func__
);
480 goto mip6_rthdr_xfrm_fail
;
482 if (rawv6_mh_filter_register(mip6_mh_filter
) < 0) {
483 pr_info("%s: can't add rawv6 mh filter\n", __func__
);
484 goto mip6_rawv6_mh_fail
;
491 xfrm_unregister_type(&mip6_rthdr_type
, AF_INET6
);
492 mip6_rthdr_xfrm_fail
:
493 xfrm_unregister_type(&mip6_destopt_type
, AF_INET6
);
494 mip6_destopt_xfrm_fail
:
498 static void __exit
mip6_fini(void)
500 if (rawv6_mh_filter_unregister(mip6_mh_filter
) < 0)
501 pr_info("%s: can't remove rawv6 mh filter\n", __func__
);
502 xfrm_unregister_type(&mip6_rthdr_type
, AF_INET6
);
503 xfrm_unregister_type(&mip6_destopt_type
, AF_INET6
);
506 module_init(mip6_init
);
507 module_exit(mip6_fini
);
509 MODULE_LICENSE("GPL");
510 MODULE_ALIAS_XFRM_TYPE(AF_INET6
, XFRM_PROTO_DSTOPTS
);
511 MODULE_ALIAS_XFRM_TYPE(AF_INET6
, XFRM_PROTO_ROUTING
);