Skip to content

Commit e490d1d

Browse files
yasuyuki5David S. Miller
authored andcommitted
[IPV6] IP6TUNNEL: Split out generic routine in ip6ip6_err().
This enables to add IPv4/IPv6 specific error handling later, Signed-off-by: Yasuyuki Kozakai <[email protected]> Signed-off-by: YOSHIFUJI Hideaki <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7159039 commit e490d1d

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

net/ipv6/ip6_tunnel.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -372,16 +372,16 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
372372
}
373373

374374
/**
375-
* ip6ip6_err - tunnel error handler
375+
* ip6_tnl_err - tunnel error handler
376376
*
377377
* Description:
378-
* ip6ip6_err() should handle errors in the tunnel according
378+
* ip6_tnl_err() should handle errors in the tunnel according
379379
* to the specifications in RFC 2473.
380380
**/
381381

382382
static int
383-
ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
384-
int type, int code, int offset, __be32 info)
383+
ip6_tnl_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
384+
int *type, int *code, int *msg, __be32 *info, int offset)
385385
{
386386
struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
387387
struct ip6_tnl *t;
@@ -402,7 +402,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
402402

403403
err = 0;
404404

405-
switch (type) {
405+
switch (*type) {
406406
__u32 teli;
407407
struct ipv6_tlv_tnl_enc_lim *tel;
408408
__u32 mtu;
@@ -414,7 +414,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
414414
rel_msg = 1;
415415
break;
416416
case ICMPV6_TIME_EXCEED:
417-
if (code == ICMPV6_EXC_HOPLIMIT) {
417+
if ((*code) == ICMPV6_EXC_HOPLIMIT) {
418418
if (net_ratelimit())
419419
printk(KERN_WARNING
420420
"%s: Too small hop limit or "
@@ -425,10 +425,10 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
425425
break;
426426
case ICMPV6_PARAMPROB:
427427
teli = 0;
428-
if (code == ICMPV6_HDR_FIELD)
428+
if ((*code) == ICMPV6_HDR_FIELD)
429429
teli = parse_tlv_tnl_enc_lim(skb, skb->data);
430430

431-
if (teli && teli == ntohl(info) - 2) {
431+
if (teli && teli == ntohl(*info) - 2) {
432432
tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
433433
if (tel->encap_limit == 0) {
434434
if (net_ratelimit())
@@ -445,7 +445,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
445445
}
446446
break;
447447
case ICMPV6_PKT_TOOBIG:
448-
mtu = ntohl(info) - offset;
448+
mtu = ntohl(*info) - offset;
449449
if (mtu < IPV6_MIN_MTU)
450450
mtu = IPV6_MIN_MTU;
451451
t->dev->mtu = mtu;
@@ -458,12 +458,38 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
458458
}
459459
break;
460460
}
461-
if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) {
461+
462+
*type = rel_type;
463+
*code = rel_code;
464+
*info = rel_info;
465+
*msg = rel_msg;
466+
467+
out:
468+
read_unlock(&ip6ip6_lock);
469+
return err;
470+
}
471+
472+
static int
473+
ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
474+
int type, int code, int offset, __u32 info)
475+
{
476+
int rel_msg = 0;
477+
int rel_type = type;
478+
int rel_code = code;
479+
__u32 rel_info = info;
480+
int err;
481+
482+
err = ip6_tnl_err(skb, opt, &rel_type, &rel_code, &rel_msg, &rel_info,
483+
offset);
484+
if (err < 0)
485+
return err;
486+
487+
if (rel_msg && pskb_may_pull(skb, offset + sizeof(struct ipv6hdr))) {
462488
struct rt6_info *rt;
463489
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
464490

465491
if (!skb2)
466-
goto out;
492+
return 0;
467493

468494
dst_release(skb2->dst);
469495
skb2->dst = NULL;
@@ -483,9 +509,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
483509

484510
kfree_skb(skb2);
485511
}
486-
out:
487-
read_unlock(&ip6ip6_lock);
488-
return err;
512+
513+
return 0;
489514
}
490515

491516
static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,

0 commit comments

Comments
 (0)