Commit f3bf7c0d authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[AH6]: Replace skb by iph in clear_mutable_options.

This patch replaces the skb argument in ipv6_clear_mutable_options() by
an ipv6hdr.  Doing so allows us to point skb->nh elsewhere when calling
this function.

I've also thrown in some obvious clean-ups for that function.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 785e4608
...@@ -74,49 +74,42 @@ static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) ...@@ -74,49 +74,42 @@ static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr)
return 0; return 0;
} }
static int ipv6_clear_mutable_options(struct sk_buff *skb, static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len)
unsigned int hdr_len)
{ {
u16 offset = sizeof(struct ipv6hdr); union {
struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); struct ipv6hdr *iph;
u8 nexthdr = skb->nh.ipv6h->nexthdr; struct ipv6_opt_hdr *opth;
struct ipv6_rt_hdr *rth;
while (offset + 1 <= hdr_len) { char *raw;
} exthdr = { .iph = iph };
char *end = exthdr.raw + len;
int nexthdr = iph->nexthdr;
exthdr.iph++;
while (exthdr.raw < end) {
switch (nexthdr) { switch (nexthdr) {
case NEXTHDR_HOP: case NEXTHDR_HOP:
offset += ipv6_optlen(exthdr); case NEXTHDR_DEST:
if (!zero_out_mutable_opts(exthdr)) { if (!zero_out_mutable_opts(exthdr.opth)) {
LIMIT_NETDEBUG( LIMIT_NETDEBUG(printk(
printk(KERN_WARNING "overrun hopopts\n")); KERN_WARNING "overrun %sopts\n",
nexthdr == NEXTHDR_HOP ?
"hop" : "dest"));
return -EINVAL; return -EINVAL;
} }
nexthdr = exthdr->nexthdr;
exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
break; break;
case NEXTHDR_ROUTING: case NEXTHDR_ROUTING:
offset += ipv6_optlen(exthdr); exthdr.rth->segments_left = 0;
((struct ipv6_rt_hdr*)exthdr)->segments_left = 0;
nexthdr = exthdr->nexthdr;
exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
break;
case NEXTHDR_DEST:
offset += ipv6_optlen(exthdr);
if (!zero_out_mutable_opts(exthdr)) {
LIMIT_NETDEBUG(
printk(KERN_WARNING "overrun destopt\n"));
return -EINVAL;
}
nexthdr = exthdr->nexthdr;
exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
break; break;
default : default :
return 0; return 0;
} }
nexthdr = exthdr.opth->nexthdr;
exthdr.raw += ipv6_optlen(exthdr.opth);
} }
return 0; return 0;
...@@ -175,7 +168,7 @@ int ah6_output(struct sk_buff **pskb) ...@@ -175,7 +168,7 @@ int ah6_output(struct sk_buff **pskb)
(*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len); (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr)); iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
memcpy((*pskb)->nh.ipv6h, iph, hdr_len); memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
err = ipv6_clear_mutable_options(*pskb, hdr_len); err = ipv6_clear_mutable_options((*pskb)->nh.ipv6h, hdr_len);
if (err) if (err)
goto error_free_iph; goto error_free_iph;
...@@ -283,7 +276,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -283,7 +276,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!tmp_hdr) if (!tmp_hdr)
goto out; goto out;
memcpy(tmp_hdr, skb->nh.raw, hdr_len); memcpy(tmp_hdr, skb->nh.raw, hdr_len);
if (ipv6_clear_mutable_options(skb, hdr_len)) if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len))
goto out; goto out;
skb->nh.ipv6h->priority = 0; skb->nh.ipv6h->priority = 0;
skb->nh.ipv6h->flow_lbl[0] = 0; skb->nh.ipv6h->flow_lbl[0] = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment