25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27 #include <linux/module.h>
29 #include <linux/time.h>
30 #include <linux/ipv6.h>
31 #include <linux/icmpv6.h>
39 static inline unsigned int calc_padlen(
unsigned int len,
unsigned int n)
41 return (n - len + 16) & 0x7;
50 }
else if (padlen > 1) {
54 memset(data+2, 0, data[1]);
64 static int mip6_mh_len(
int type)
92 mh = skb_header_pointer(skb, skb_transport_offset(skb),
104 skb_network_header_len(skb));
112 skb_network_header_len(skb));
133 const struct ipv6hdr *iph = ipv6_hdr(skb);
135 int err = destopt->nexthdr;
141 spin_unlock(&x->
lock);
158 skb_push(skb, -skb_network_offset(skb));
161 nexthdr = *skb_mac_header(skb);
167 hao = mip6_padn((
char *)(dstopt + 1),
168 calc_padlen(
sizeof(*dstopt), 6));
172 hao->
length =
sizeof(*hao) - 2;
174 len = ((
char *)hao - (
char *)dstopt) +
sizeof(*hao);
177 spin_lock_bh(&x->
lock);
179 spin_unlock_bh(&x->
lock);
182 dstopt->hdrlen = (x->
props.header_len >> 3) - 1;
187 static inline int mip6_report_rl_allow(
struct timeval *
stamp,
193 spin_lock_bh(&mip6_report_rl.
lock);
194 if (mip6_report_rl.
stamp.tv_sec != stamp->
tv_sec ||
196 mip6_report_rl.
iif != iif ||
197 !ipv6_addr_equal(&mip6_report_rl.
src, src) ||
198 !ipv6_addr_equal(&mip6_report_rl.
dst, dst)) {
201 mip6_report_rl.
iif = iif;
202 mip6_report_rl.
src = *
src;
203 mip6_report_rl.
dst = *
dst;
206 spin_unlock_bh(&mip6_report_rl.
lock);
213 struct net *
net = xs_net(x);
226 if (
likely(opt->dsthao)) {
230 (skb_network_header(skb) +
offset);
233 skb_get_timestamp(skb, &stamp);
235 if (!mip6_report_rl_allow(&stamp, &ipv6_hdr(skb)->
daddr,
236 hao ? &hao->
addr : &ipv6_hdr(skb)->
saddr,
243 sel.prefixlen_d = 128;
246 sel.prefixlen_s = 128;
248 sel.proto = fl6->flowi6_proto;
249 sel.dport = xfrm_flowi_dport(fl, &fl6->uli);
252 sel.sport = xfrm_flowi_sport(fl, &fl6->uli);
255 sel.ifindex = fl6->flowi6_oif;
270 const unsigned char *nh = skb_network_header(skb);
274 *nexthdr = &ipv6_hdr(skb)->nexthdr;
276 while (offset + 1 <= packet_len) {
311 static int mip6_destopt_init_state(
struct xfrm_state *x)
314 pr_info(
"%s: spi is not 0: %u\n", __func__, x->
id.spi);
318 pr_info(
"%s: state's mode is not %u: %u\n",
335 static void mip6_destopt_destroy(
struct xfrm_state *x)
339 static const struct xfrm_type mip6_destopt_type =
341 .description =
"MIP6DESTOPT",
345 .init_state = mip6_destopt_init_state,
346 .destructor = mip6_destopt_destroy,
347 .input = mip6_destopt_input,
348 .output = mip6_destopt_output,
349 .reject = mip6_destopt_reject,
350 .hdr_offset = mip6_destopt_offset,
355 const struct ipv6hdr *iph = ipv6_hdr(skb);
363 spin_unlock(&x->
lock);
377 skb_push(skb, -skb_network_offset(skb));
380 nexthdr = *skb_mac_header(skb);
383 rt2 = (
struct rt2_hdr *)skb_transport_header(skb);
385 rt2->
rt_hdr.hdrlen = (x->
props.header_len >> 3) - 1;
387 rt2->
rt_hdr.segments_left = 1;
393 spin_lock_bh(&x->
lock);
395 spin_unlock_bh(&x->
lock);
406 const unsigned char *nh = skb_network_header(skb);
410 *nexthdr = &ipv6_hdr(skb)->nexthdr;
412 while (offset + 1 <= packet_len) {
418 if (offset + 3 <= packet_len) {
446 static int mip6_rthdr_init_state(
struct xfrm_state *x)
449 pr_info(
"%s: spi is not 0: %u\n", __func__, x->
id.spi);
453 pr_info(
"%s: state's mode is not %u: %u\n",
467 static void mip6_rthdr_destroy(
struct xfrm_state *x)
471 static const struct xfrm_type mip6_rthdr_type =
473 .description =
"MIP6RT",
477 .init_state = mip6_rthdr_init_state,
478 .destructor = mip6_rthdr_destroy,
479 .input = mip6_rthdr_input,
480 .output = mip6_rthdr_output,
481 .hdr_offset = mip6_rthdr_offset,
484 static int __init mip6_init(
void)
489 pr_info(
"%s: can't add xfrm type(destopt)\n", __func__);
490 goto mip6_destopt_xfrm_fail;
493 pr_info(
"%s: can't add xfrm type(rthdr)\n", __func__);
494 goto mip6_rthdr_xfrm_fail;
496 if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
497 pr_info(
"%s: can't add rawv6 mh filter\n", __func__);
498 goto mip6_rawv6_mh_fail;
506 mip6_rthdr_xfrm_fail:
508 mip6_destopt_xfrm_fail:
512 static void __exit mip6_fini(
void)
514 if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
515 pr_info(
"%s: can't remove rawv6 mh filter\n", __func__);
517 pr_info(
"%s: can't remove xfrm type(rthdr)\n", __func__);
519 pr_info(
"%s: can't remove xfrm type(destopt)\n", __func__);