diff options
author | David S. Miller <davem@davemloft.net> | 2010-09-27 04:03:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-27 04:03:03 -0400 |
commit | e40051d134f7ee95c8c1f7a3471e84eafc9ab326 (patch) | |
tree | 88eb44e49a75721ae926665a2c42f08badac9d07 /net/ipv6 | |
parent | 42099d7a3941d4aaf853caac92b3ae76149fc6e7 (diff) | |
parent | 2cc6d2bf3d6195fabcf0febc192c01f99519a8f3 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/qlcnic/qlcnic_init.c
net/ipv4/ip_output.c
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 11 | ||||
-rw-r--r-- | net/ipv6/addrlabel.c | 5 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 18 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 33 |
4 files changed, 45 insertions, 22 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 89aa54394a08..8c88340278f5 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4638,10 +4638,12 @@ int __init addrconf_init(void) | |||
4638 | if (err < 0) { | 4638 | if (err < 0) { |
4639 | printk(KERN_CRIT "IPv6 Addrconf:" | 4639 | printk(KERN_CRIT "IPv6 Addrconf:" |
4640 | " cannot initialize default policy table: %d.\n", err); | 4640 | " cannot initialize default policy table: %d.\n", err); |
4641 | return err; | 4641 | goto out; |
4642 | } | 4642 | } |
4643 | 4643 | ||
4644 | register_pernet_subsys(&addrconf_ops); | 4644 | err = register_pernet_subsys(&addrconf_ops); |
4645 | if (err < 0) | ||
4646 | goto out_addrlabel; | ||
4645 | 4647 | ||
4646 | /* The addrconf netdev notifier requires that loopback_dev | 4648 | /* The addrconf netdev notifier requires that loopback_dev |
4647 | * has it's ipv6 private information allocated and setup | 4649 | * has it's ipv6 private information allocated and setup |
@@ -4693,7 +4695,9 @@ errout: | |||
4693 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4695 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4694 | errlo: | 4696 | errlo: |
4695 | unregister_pernet_subsys(&addrconf_ops); | 4697 | unregister_pernet_subsys(&addrconf_ops); |
4696 | 4698 | out_addrlabel: | |
4699 | ipv6_addr_label_cleanup(); | ||
4700 | out: | ||
4697 | return err; | 4701 | return err; |
4698 | } | 4702 | } |
4699 | 4703 | ||
@@ -4704,6 +4708,7 @@ void addrconf_cleanup(void) | |||
4704 | 4708 | ||
4705 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4709 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4706 | unregister_pernet_subsys(&addrconf_ops); | 4710 | unregister_pernet_subsys(&addrconf_ops); |
4711 | ipv6_addr_label_cleanup(); | ||
4707 | 4712 | ||
4708 | rtnl_lock(); | 4713 | rtnl_lock(); |
4709 | 4714 | ||
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 921dcf6c271a..c8993e5a337c 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -393,6 +393,11 @@ int __init ipv6_addr_label_init(void) | |||
393 | return register_pernet_subsys(&ipv6_addr_label_ops); | 393 | return register_pernet_subsys(&ipv6_addr_label_ops); |
394 | } | 394 | } |
395 | 395 | ||
396 | void ipv6_addr_label_cleanup(void) | ||
397 | { | ||
398 | unregister_pernet_subsys(&ipv6_addr_label_ops); | ||
399 | } | ||
400 | |||
396 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { | 401 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { |
397 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, | 402 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, |
398 | [IFAL_LABEL] = { .len = sizeof(u32), }, | 403 | [IFAL_LABEL] = { .len = sizeof(u32), }, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index efbbbce68f9e..99157b4cd56e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
639 | 639 | ||
640 | if (skb_has_frag_list(skb)) { | 640 | if (skb_has_frag_list(skb)) { |
641 | int first_len = skb_pagelen(skb); | 641 | int first_len = skb_pagelen(skb); |
642 | int truesizes = 0; | 642 | struct sk_buff *frag2; |
643 | 643 | ||
644 | if (first_len - hlen > mtu || | 644 | if (first_len - hlen > mtu || |
645 | ((first_len - hlen) & 7) || | 645 | ((first_len - hlen) & 7) || |
@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
651 | if (frag->len > mtu || | 651 | if (frag->len > mtu || |
652 | ((frag->len & 7) && frag->next) || | 652 | ((frag->len & 7) && frag->next) || |
653 | skb_headroom(frag) < hlen) | 653 | skb_headroom(frag) < hlen) |
654 | goto slow_path; | 654 | goto slow_path_clean; |
655 | 655 | ||
656 | /* Partially cloned skb? */ | 656 | /* Partially cloned skb? */ |
657 | if (skb_shared(frag)) | 657 | if (skb_shared(frag)) |
658 | goto slow_path; | 658 | goto slow_path_clean; |
659 | 659 | ||
660 | BUG_ON(frag->sk); | 660 | BUG_ON(frag->sk); |
661 | if (skb->sk) { | 661 | if (skb->sk) { |
662 | frag->sk = skb->sk; | 662 | frag->sk = skb->sk; |
663 | frag->destructor = sock_wfree; | 663 | frag->destructor = sock_wfree; |
664 | truesizes += frag->truesize; | ||
665 | } | 664 | } |
665 | skb->truesize -= frag->truesize; | ||
666 | } | 666 | } |
667 | 667 | ||
668 | err = 0; | 668 | err = 0; |
@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
693 | 693 | ||
694 | first_len = skb_pagelen(skb); | 694 | first_len = skb_pagelen(skb); |
695 | skb->data_len = first_len - skb_headlen(skb); | 695 | skb->data_len = first_len - skb_headlen(skb); |
696 | skb->truesize -= truesizes; | ||
697 | skb->len = first_len; | 696 | skb->len = first_len; |
698 | ipv6_hdr(skb)->payload_len = htons(first_len - | 697 | ipv6_hdr(skb)->payload_len = htons(first_len - |
699 | sizeof(struct ipv6hdr)); | 698 | sizeof(struct ipv6hdr)); |
@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | IPSTATS_MIB_FRAGFAILS); | 755 | IPSTATS_MIB_FRAGFAILS); |
757 | dst_release(&rt->dst); | 756 | dst_release(&rt->dst); |
758 | return err; | 757 | return err; |
758 | |||
759 | slow_path_clean: | ||
760 | skb_walk_frags(skb, frag2) { | ||
761 | if (frag2 == frag) | ||
762 | break; | ||
763 | frag2->sk = NULL; | ||
764 | frag2->destructor = NULL; | ||
765 | skb->truesize += frag2->truesize; | ||
766 | } | ||
759 | } | 767 | } |
760 | 768 | ||
761 | slow_path: | 769 | slow_path: |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index f417b77fa0e1..a67575d472a3 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -20,23 +20,27 @@ | |||
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static void | 22 | static void |
23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
24 | struct xfrm_tmpl *tmpl, | ||
25 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
26 | { | 24 | { |
27 | /* Initialize temporary selector matching only | 25 | /* Initialize temporary selector matching only |
28 | * to current session. */ | 26 | * to current session. */ |
29 | ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst); | 27 | ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst); |
30 | ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src); | 28 | ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src); |
31 | x->sel.dport = xfrm_flowi_dport(fl); | 29 | sel->dport = xfrm_flowi_dport(fl); |
32 | x->sel.dport_mask = htons(0xffff); | 30 | sel->dport_mask = htons(0xffff); |
33 | x->sel.sport = xfrm_flowi_sport(fl); | 31 | sel->sport = xfrm_flowi_sport(fl); |
34 | x->sel.sport_mask = htons(0xffff); | 32 | sel->sport_mask = htons(0xffff); |
35 | x->sel.family = AF_INET6; | 33 | sel->family = AF_INET6; |
36 | x->sel.prefixlen_d = 128; | 34 | sel->prefixlen_d = 128; |
37 | x->sel.prefixlen_s = 128; | 35 | sel->prefixlen_s = 128; |
38 | x->sel.proto = fl->proto; | 36 | sel->proto = fl->proto; |
39 | x->sel.ifindex = fl->oif; | 37 | sel->ifindex = fl->oif; |
38 | } | ||
39 | |||
40 | static void | ||
41 | xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
42 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
43 | { | ||
40 | x->id = tmpl->id; | 44 | x->id = tmpl->id; |
41 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) | 45 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) |
42 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); | 46 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); |
@@ -168,6 +172,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
168 | .eth_proto = htons(ETH_P_IPV6), | 172 | .eth_proto = htons(ETH_P_IPV6), |
169 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
170 | .init_tempsel = __xfrm6_init_tempsel, | 174 | .init_tempsel = __xfrm6_init_tempsel, |
175 | .init_temprop = xfrm6_init_temprop, | ||
171 | .tmpl_sort = __xfrm6_tmpl_sort, | 176 | .tmpl_sort = __xfrm6_tmpl_sort, |
172 | .state_sort = __xfrm6_state_sort, | 177 | .state_sort = __xfrm6_state_sort, |
173 | .output = xfrm6_output, | 178 | .output = xfrm6_output, |