Lines Matching +full:offset +full:- +full:x
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
28 return (n - len + 16) & 0x7; in calc_padlen()
39 data[1] = padlen - 2; in mip6_padn()
82 return -1; in mip6_mh_filter()
84 if (((mh->ip6mh_hdrlen + 1) << 3) > skb->len) in mip6_mh_filter()
85 return -1; in mip6_mh_filter()
87 if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) { in mip6_mh_filter()
89 mh->ip6mh_hdrlen, in mip6_mh_filter()
90 mip6_mh_len(mh->ip6mh_type)); in mip6_mh_filter()
93 return -1; in mip6_mh_filter()
96 if (mh->ip6mh_proto != IPPROTO_NONE) { in mip6_mh_filter()
98 mh->ip6mh_proto); in mip6_mh_filter()
101 return -1; in mip6_mh_filter()
119 static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb) in mip6_destopt_input() argument
122 struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data; in mip6_destopt_input()
123 int err = destopt->nexthdr; in mip6_destopt_input()
125 spin_lock(&x->lock); in mip6_destopt_input()
126 if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) && in mip6_destopt_input()
127 !ipv6_addr_any((struct in6_addr *)x->coaddr)) in mip6_destopt_input()
128 err = -ENOENT; in mip6_destopt_input()
129 spin_unlock(&x->lock); in mip6_destopt_input()
138 static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) in mip6_destopt_output() argument
146 skb_push(skb, -skb_network_offset(skb)); in mip6_destopt_output()
153 dstopt->nexthdr = nexthdr; in mip6_destopt_output()
158 hao->type = IPV6_TLV_HAO; in mip6_destopt_output()
160 hao->length = sizeof(*hao) - 2; in mip6_destopt_output()
162 len = ((char *)hao - (char *)dstopt) + sizeof(*hao); in mip6_destopt_output()
164 memcpy(&hao->addr, &iph->saddr, sizeof(hao->addr)); in mip6_destopt_output()
165 spin_lock_bh(&x->lock); in mip6_destopt_output()
166 memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); in mip6_destopt_output()
167 spin_unlock_bh(&x->lock); in mip6_destopt_output()
169 WARN_ON(len != x->props.header_len); in mip6_destopt_output()
170 dstopt->hdrlen = (x->props.header_len >> 3) - 1; in mip6_destopt_output()
196 static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, in mip6_destopt_reject() argument
199 struct net *net = xs_net(x); in mip6_destopt_reject()
200 struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; in mip6_destopt_reject()
201 const struct flowi6 *fl6 = &fl->u.ip6; in mip6_destopt_reject()
204 int offset; in mip6_destopt_reject() local
208 if (unlikely(fl6->flowi6_proto == IPPROTO_MH && in mip6_destopt_reject()
209 fl6->fl6_mh_type <= IP6_MH_TYPE_MAX)) in mip6_destopt_reject()
212 if (likely(opt->dsthao)) { in mip6_destopt_reject()
213 offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); in mip6_destopt_reject()
214 if (likely(offset >= 0)) in mip6_destopt_reject()
216 (skb_network_header(skb) + offset); in mip6_destopt_reject()
221 if (!mip6_report_rl_allow(stamp, &ipv6_hdr(skb)->daddr, in mip6_destopt_reject()
222 hao ? &hao->addr : &ipv6_hdr(skb)->saddr, in mip6_destopt_reject()
223 opt->iif)) in mip6_destopt_reject()
227 memcpy(&sel.daddr, (xfrm_address_t *)&ipv6_hdr(skb)->daddr, in mip6_destopt_reject()
230 memcpy(&sel.saddr, (xfrm_address_t *)&ipv6_hdr(skb)->saddr, in mip6_destopt_reject()
234 sel.proto = fl6->flowi6_proto; in mip6_destopt_reject()
235 sel.dport = xfrm_flowi_dport(fl, &fl6->uli); in mip6_destopt_reject()
238 sel.sport = xfrm_flowi_sport(fl, &fl6->uli); in mip6_destopt_reject()
241 sel.ifindex = fl6->flowi6_oif; in mip6_destopt_reject()
244 (hao ? (xfrm_address_t *)&hao->addr : NULL)); in mip6_destopt_reject()
250 static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb, in mip6_destopt_offset() argument
253 u16 offset = sizeof(struct ipv6hdr); in mip6_destopt_offset() local
257 unsigned int packet_len = skb_tail_pointer(skb) - in mip6_destopt_offset()
261 *nexthdr = &ipv6_hdr(skb)->nexthdr; in mip6_destopt_offset()
263 while (offset + 1 <= packet_len) { in mip6_destopt_offset()
277 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) { in mip6_destopt_offset()
279 return offset; in mip6_destopt_offset()
283 return offset; in mip6_destopt_offset()
287 return offset; in mip6_destopt_offset()
290 offset += ipv6_optlen(exthdr); in mip6_destopt_offset()
291 *nexthdr = &exthdr->nexthdr; in mip6_destopt_offset()
292 exthdr = (struct ipv6_opt_hdr *)(nh + offset); in mip6_destopt_offset()
295 return offset; in mip6_destopt_offset()
298 static int mip6_destopt_init_state(struct xfrm_state *x) in mip6_destopt_init_state() argument
300 if (x->id.spi) { in mip6_destopt_init_state()
301 pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); in mip6_destopt_init_state()
302 return -EINVAL; in mip6_destopt_init_state()
304 if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { in mip6_destopt_init_state()
306 __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); in mip6_destopt_init_state()
307 return -EINVAL; in mip6_destopt_init_state()
310 x->props.header_len = sizeof(struct ipv6_destopt_hdr) + in mip6_destopt_init_state()
313 WARN_ON(x->props.header_len != 24); in mip6_destopt_init_state()
322 static void mip6_destopt_destroy(struct xfrm_state *x) in mip6_destopt_destroy() argument
339 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb) in mip6_rthdr_input() argument
342 struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data; in mip6_rthdr_input()
343 int err = rt2->rt_hdr.nexthdr; in mip6_rthdr_input()
345 spin_lock(&x->lock); in mip6_rthdr_input()
346 if (!ipv6_addr_equal(&iph->daddr, (struct in6_addr *)x->coaddr) && in mip6_rthdr_input()
347 !ipv6_addr_any((struct in6_addr *)x->coaddr)) in mip6_rthdr_input()
348 err = -ENOENT; in mip6_rthdr_input()
349 spin_unlock(&x->lock); in mip6_rthdr_input()
357 static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) in mip6_rthdr_output() argument
363 skb_push(skb, -skb_network_offset(skb)); in mip6_rthdr_output()
370 rt2->rt_hdr.nexthdr = nexthdr; in mip6_rthdr_output()
371 rt2->rt_hdr.hdrlen = (x->props.header_len >> 3) - 1; in mip6_rthdr_output()
372 rt2->rt_hdr.type = IPV6_SRCRT_TYPE_2; in mip6_rthdr_output()
373 rt2->rt_hdr.segments_left = 1; in mip6_rthdr_output()
374 memset(&rt2->reserved, 0, sizeof(rt2->reserved)); in mip6_rthdr_output()
376 WARN_ON(rt2->rt_hdr.hdrlen != 2); in mip6_rthdr_output()
378 memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr)); in mip6_rthdr_output()
379 spin_lock_bh(&x->lock); in mip6_rthdr_output()
380 memcpy(&iph->daddr, x->coaddr, sizeof(iph->daddr)); in mip6_rthdr_output()
381 spin_unlock_bh(&x->lock); in mip6_rthdr_output()
386 static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb, in mip6_rthdr_offset() argument
389 u16 offset = sizeof(struct ipv6hdr); in mip6_rthdr_offset() local
393 unsigned int packet_len = skb_tail_pointer(skb) - in mip6_rthdr_offset()
397 *nexthdr = &ipv6_hdr(skb)->nexthdr; in mip6_rthdr_offset()
399 while (offset + 1 <= packet_len) { in mip6_rthdr_offset()
405 if (offset + 3 <= packet_len) { in mip6_rthdr_offset()
407 rt = (struct ipv6_rt_hdr *)(nh + offset); in mip6_rthdr_offset()
408 if (rt->type != 0) in mip6_rthdr_offset()
409 return offset; in mip6_rthdr_offset()
414 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) in mip6_rthdr_offset()
415 return offset; in mip6_rthdr_offset()
418 return offset; in mip6_rthdr_offset()
422 return offset; in mip6_rthdr_offset()
425 offset += ipv6_optlen(exthdr); in mip6_rthdr_offset()
426 *nexthdr = &exthdr->nexthdr; in mip6_rthdr_offset()
427 exthdr = (struct ipv6_opt_hdr *)(nh + offset); in mip6_rthdr_offset()
430 return offset; in mip6_rthdr_offset()
433 static int mip6_rthdr_init_state(struct xfrm_state *x) in mip6_rthdr_init_state() argument
435 if (x->id.spi) { in mip6_rthdr_init_state()
436 pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); in mip6_rthdr_init_state()
437 return -EINVAL; in mip6_rthdr_init_state()
439 if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { in mip6_rthdr_init_state()
441 __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); in mip6_rthdr_init_state()
442 return -EINVAL; in mip6_rthdr_init_state()
445 x->props.header_len = sizeof(struct rt2_hdr); in mip6_rthdr_init_state()
454 static void mip6_rthdr_destroy(struct xfrm_state *x) in mip6_rthdr_destroy() argument
495 return -EAGAIN; in mip6_init()