mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
xfrm: ipv6: move mip6_destopt_offset into xfrm core
This helper is relatively small, just move this to the xfrm core and call it directly. Next patch does the same for the ROUTING type. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
9acf4d3b9e
commit
37b9e7eb55
@ -247,54 +247,6 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
|
|
||||||
u8 **nexthdr)
|
|
||||||
{
|
|
||||||
u16 offset = sizeof(struct ipv6hdr);
|
|
||||||
struct ipv6_opt_hdr *exthdr =
|
|
||||||
(struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
|
|
||||||
const unsigned char *nh = skb_network_header(skb);
|
|
||||||
unsigned int packet_len = skb_tail_pointer(skb) -
|
|
||||||
skb_network_header(skb);
|
|
||||||
int found_rhdr = 0;
|
|
||||||
|
|
||||||
*nexthdr = &ipv6_hdr(skb)->nexthdr;
|
|
||||||
|
|
||||||
while (offset + 1 <= packet_len) {
|
|
||||||
|
|
||||||
switch (**nexthdr) {
|
|
||||||
case NEXTHDR_HOP:
|
|
||||||
break;
|
|
||||||
case NEXTHDR_ROUTING:
|
|
||||||
found_rhdr = 1;
|
|
||||||
break;
|
|
||||||
case NEXTHDR_DEST:
|
|
||||||
/*
|
|
||||||
* HAO MUST NOT appear more than once.
|
|
||||||
* XXX: It is better to try to find by the end of
|
|
||||||
* XXX: packet if HAO exists.
|
|
||||||
*/
|
|
||||||
if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) {
|
|
||||||
net_dbg_ratelimited("mip6: hao exists already, override\n");
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_rhdr)
|
|
||||||
return offset;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += ipv6_optlen(exthdr);
|
|
||||||
*nexthdr = &exthdr->nexthdr;
|
|
||||||
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mip6_destopt_init_state(struct xfrm_state *x)
|
static int mip6_destopt_init_state(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
if (x->id.spi) {
|
if (x->id.spi) {
|
||||||
@ -332,7 +284,6 @@ static const struct xfrm_type mip6_destopt_type = {
|
|||||||
.input = mip6_destopt_input,
|
.input = mip6_destopt_input,
|
||||||
.output = mip6_destopt_output,
|
.output = mip6_destopt_output,
|
||||||
.reject = mip6_destopt_reject,
|
.reject = mip6_destopt_reject,
|
||||||
.hdr_offset = mip6_destopt_offset,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
|
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
|
@ -77,8 +77,65 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||||
|
static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
|
||||||
|
u8 **nexthdr)
|
||||||
|
{
|
||||||
|
u16 offset = sizeof(struct ipv6hdr);
|
||||||
|
struct ipv6_opt_hdr *exthdr =
|
||||||
|
(struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
|
||||||
|
const unsigned char *nh = skb_network_header(skb);
|
||||||
|
unsigned int packet_len = skb_tail_pointer(skb) -
|
||||||
|
skb_network_header(skb);
|
||||||
|
int found_rhdr = 0;
|
||||||
|
|
||||||
|
*nexthdr = &ipv6_hdr(skb)->nexthdr;
|
||||||
|
|
||||||
|
while (offset + 1 <= packet_len) {
|
||||||
|
switch (**nexthdr) {
|
||||||
|
case NEXTHDR_HOP:
|
||||||
|
break;
|
||||||
|
case NEXTHDR_ROUTING:
|
||||||
|
found_rhdr = 1;
|
||||||
|
break;
|
||||||
|
case NEXTHDR_DEST:
|
||||||
|
/* HAO MUST NOT appear more than once.
|
||||||
|
* XXX: It is better to try to find by the end of
|
||||||
|
* XXX: packet if HAO exists.
|
||||||
|
*/
|
||||||
|
if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) {
|
||||||
|
net_dbg_ratelimited("mip6: hao exists already, override\n");
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_rhdr)
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += ipv6_optlen(exthdr);
|
||||||
|
*nexthdr = &exthdr->nexthdr;
|
||||||
|
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int xfrm6_hdr_offset(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr)
|
static int xfrm6_hdr_offset(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr)
|
||||||
{
|
{
|
||||||
|
switch (x->type->proto) {
|
||||||
|
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||||
|
case IPPROTO_DSTOPTS:
|
||||||
|
return mip6_destopt_offset(x, skb, prevhdr);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return x->type->hdr_offset(x, skb, prevhdr);
|
return x->type->hdr_offset(x, skb, prevhdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user