aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:45:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:45:48 -0400
commit95dfec6ae1cb8c03406aac612a5642cbddb676b3 (patch)
tree978de715f45de94a8e79eb08a08ca5fb9dfd9dea /net
parentae3a0064e6d69068b1c9fd075095da062430bda9 (diff)
parent159131149c2f56c1da5ae5e23ab9d5acef4916d1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (53 commits) tcp: Overflow bug in Vegas [IPv4] UFO: prevent generation of chained skb destined to UFO device iwlwifi: move the selects to the tristate drivers ipv4: annotate a few functions __init in ipconfig.c atm: ambassador: vcc_sf semaphore to mutex MAINTAINERS: The socketcan-core list is subscribers-only. netfilter: nf_conntrack: padding breaks conntrack hash on ARM ipv4: Update MTU to all related cache entries in ip_rt_frag_needed() sch_sfq: use del_timer_sync() in sfq_destroy() net: Add compat support for getsockopt (MCAST_MSFILTER) net: Several cleanups for the setsockopt compat support. ipvs: fix oops in backup for fwmark conn templates bridge: kernel panic when unloading bridge module bridge: fix error handling in br_add_if() netfilter: {nfnetlink,ip,ip6}_queue: fix skb_over_panic when enlarging packets netfilter: x_tables: fix net namespace leak when reading /proc/net/xxx_tables_names netfilter: xt_TCPOPTSTRIP: signed tcphoff for ipv6_skip_exthdr() retval tcp: Limit cwnd growth when deferring for GSO tcp: Allow send-limited cwnd to grow up to max_burst when gso disabled [netdrvr] gianfar: Determine TBIPA value dynamically ...
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_if.c5
-rw-r--r--net/compat.c90
-rw-r--r--net/ipv4/icmp.c3
-rw-r--r--net/ipv4/ip_output.c22
-rw-r--r--net/ipv4/ip_sockglue.c9
-rw-r--r--net/ipv4/ipconfig.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_ah.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_esp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c80
-rw-r--r--net/ipv4/netfilter/ip_queue.c5
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c2
-rw-r--r--net/ipv4/route.c38
-rw-r--r--net/ipv4/tcp_cong.c12
-rw-r--r--net/ipv4/tcp_vegas.c10
-rw-r--r--net/ipv4/tcp_veno.c8
-rw-r--r--net/ipv6/ipv6_sockglue.c4
-rw-r--r--net/ipv6/netfilter/ip6_queue.c5
-rw-r--r--net/netfilter/nf_conntrack_core.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c5
-rw-r--r--net/netfilter/x_tables.c2
-rw-r--r--net/netfilter/xt_TCPOPTSTRIP.c2
-rw-r--r--net/sched/sch_sfq.c3
26 files changed, 231 insertions, 94 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index a90182873120..8f3c58e5f7a5 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -76,7 +76,6 @@ static void __exit br_deinit(void)
76 rcu_assign_pointer(br_stp_sap->rcv_func, NULL); 76 rcu_assign_pointer(br_stp_sap->rcv_func, NULL);
77 77
78 br_netlink_fini(); 78 br_netlink_fini();
79 br_netfilter_fini();
80 unregister_netdevice_notifier(&br_device_notifier); 79 unregister_netdevice_notifier(&br_device_notifier);
81 brioctl_set(NULL); 80 brioctl_set(NULL);
82 81
@@ -84,6 +83,7 @@ static void __exit br_deinit(void)
84 83
85 synchronize_net(); 84 synchronize_net();
86 85
86 br_netfilter_fini();
87 llc_sap_put(br_stp_sap); 87 llc_sap_put(br_stp_sap);
88 br_fdb_get_hook = NULL; 88 br_fdb_get_hook = NULL;
89 br_fdb_put_hook = NULL; 89 br_fdb_put_hook = NULL;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 298e0f463c56..77a981a1ee52 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -411,9 +411,12 @@ err2:
411 br_fdb_delete_by_port(br, p, 1); 411 br_fdb_delete_by_port(br, p, 1);
412err1: 412err1:
413 kobject_del(&p->kobj); 413 kobject_del(&p->kobj);
414 return err; 414 goto put_back;
415err0: 415err0:
416 kobject_put(&p->kobj); 416 kobject_put(&p->kobj);
417
418put_back:
419 dev_put(dev);
417 return err; 420 return err;
418} 421}
419 422
diff --git a/net/compat.c b/net/compat.c
index 01bf95d0832e..c823f6f290cb 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -548,6 +548,9 @@ struct compat_group_filter {
548 __attribute__ ((aligned(4))); 548 __attribute__ ((aligned(4)));
549} __attribute__ ((packed)); 549} __attribute__ ((packed));
550 550
551#define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \
552 sizeof(struct __kernel_sockaddr_storage))
553
551 554
552int compat_mc_setsockopt(struct sock *sock, int level, int optname, 555int compat_mc_setsockopt(struct sock *sock, int level, int optname,
553 char __user *optval, int optlen, 556 char __user *optval, int optlen,
@@ -582,7 +585,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
582 case MCAST_UNBLOCK_SOURCE: 585 case MCAST_UNBLOCK_SOURCE:
583 { 586 {
584 struct compat_group_source_req __user *gsr32 = (void *)optval; 587 struct compat_group_source_req __user *gsr32 = (void *)optval;
585 struct group_source_req *kgsr = compat_alloc_user_space( 588 struct group_source_req __user *kgsr = compat_alloc_user_space(
586 sizeof(struct group_source_req)); 589 sizeof(struct group_source_req));
587 u32 interface; 590 u32 interface;
588 591
@@ -603,10 +606,10 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
603 case MCAST_MSFILTER: 606 case MCAST_MSFILTER:
604 { 607 {
605 struct compat_group_filter __user *gf32 = (void *)optval; 608 struct compat_group_filter __user *gf32 = (void *)optval;
606 struct group_filter *kgf; 609 struct group_filter __user *kgf;
607 u32 interface, fmode, numsrc; 610 u32 interface, fmode, numsrc;
608 611
609 if (!access_ok(VERIFY_READ, gf32, sizeof(*gf32)) || 612 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
610 __get_user(interface, &gf32->gf_interface) || 613 __get_user(interface, &gf32->gf_interface) ||
611 __get_user(fmode, &gf32->gf_fmode) || 614 __get_user(fmode, &gf32->gf_fmode) ||
612 __get_user(numsrc, &gf32->gf_numsrc)) 615 __get_user(numsrc, &gf32->gf_numsrc))
@@ -622,7 +625,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
622 __put_user(numsrc, &kgf->gf_numsrc) || 625 __put_user(numsrc, &kgf->gf_numsrc) ||
623 copy_in_user(&kgf->gf_group, &gf32->gf_group, 626 copy_in_user(&kgf->gf_group, &gf32->gf_group,
624 sizeof(kgf->gf_group)) || 627 sizeof(kgf->gf_group)) ||
625 (numsrc && copy_in_user(&kgf->gf_slist, &gf32->gf_slist, 628 (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist,
626 numsrc * sizeof(kgf->gf_slist[0])))) 629 numsrc * sizeof(kgf->gf_slist[0]))))
627 return -EFAULT; 630 return -EFAULT;
628 koptval = (char __user *)kgf; 631 koptval = (char __user *)kgf;
@@ -637,6 +640,85 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
637 640
638EXPORT_SYMBOL(compat_mc_setsockopt); 641EXPORT_SYMBOL(compat_mc_setsockopt);
639 642
643int compat_mc_getsockopt(struct sock *sock, int level, int optname,
644 char __user *optval, int __user *optlen,
645 int (*getsockopt)(struct sock *,int,int,char __user *,int __user *))
646{
647 struct compat_group_filter __user *gf32 = (void *)optval;
648 struct group_filter __user *kgf;
649 int __user *koptlen;
650 u32 interface, fmode, numsrc;
651 int klen, ulen, err;
652
653 if (optname != MCAST_MSFILTER)
654 return getsockopt(sock, level, optname, optval, optlen);
655
656 koptlen = compat_alloc_user_space(sizeof(*koptlen));
657 if (!access_ok(VERIFY_READ, optlen, sizeof(*optlen)) ||
658 __get_user(ulen, optlen))
659 return -EFAULT;
660
661 /* adjust len for pad */
662 klen = ulen + sizeof(*kgf) - sizeof(*gf32);
663
664 if (klen < GROUP_FILTER_SIZE(0))
665 return -EINVAL;
666
667 if (!access_ok(VERIFY_WRITE, koptlen, sizeof(*koptlen)) ||
668 __put_user(klen, koptlen))
669 return -EFAULT;
670
671 /* have to allow space for previous compat_alloc_user_space, too */
672 kgf = compat_alloc_user_space(klen+sizeof(*optlen));
673
674 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
675 __get_user(interface, &gf32->gf_interface) ||
676 __get_user(fmode, &gf32->gf_fmode) ||
677 __get_user(numsrc, &gf32->gf_numsrc) ||
678 __put_user(interface, &kgf->gf_interface) ||
679 __put_user(fmode, &kgf->gf_fmode) ||
680 __put_user(numsrc, &kgf->gf_numsrc) ||
681 copy_in_user(&kgf->gf_group,&gf32->gf_group,sizeof(kgf->gf_group)))
682 return -EFAULT;
683
684 err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen);
685 if (err)
686 return err;
687
688 if (!access_ok(VERIFY_READ, koptlen, sizeof(*koptlen)) ||
689 __get_user(klen, koptlen))
690 return -EFAULT;
691
692 ulen = klen - (sizeof(*kgf)-sizeof(*gf32));
693
694 if (!access_ok(VERIFY_WRITE, optlen, sizeof(*optlen)) ||
695 __put_user(ulen, optlen))
696 return -EFAULT;
697
698 if (!access_ok(VERIFY_READ, kgf, klen) ||
699 !access_ok(VERIFY_WRITE, gf32, ulen) ||
700 __get_user(interface, &kgf->gf_interface) ||
701 __get_user(fmode, &kgf->gf_fmode) ||
702 __get_user(numsrc, &kgf->gf_numsrc) ||
703 __put_user(interface, &gf32->gf_interface) ||
704 __put_user(fmode, &gf32->gf_fmode) ||
705 __put_user(numsrc, &gf32->gf_numsrc))
706 return -EFAULT;
707 if (numsrc) {
708 int copylen;
709
710 klen -= GROUP_FILTER_SIZE(0);
711 copylen = numsrc * sizeof(gf32->gf_slist[0]);
712 if (copylen > klen)
713 copylen = klen;
714 if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen))
715 return -EFAULT;
716 }
717 return err;
718}
719
720EXPORT_SYMBOL(compat_mc_getsockopt);
721
640 722
641/* Argument list sizes for compat_sys_socketcall */ 723/* Argument list sizes for compat_sys_socketcall */
642#define AL(x) ((x) * sizeof(u32)) 724#define AL(x) ((x) * sizeof(u32))
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index c67d00e8c600..87397351ddac 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -691,7 +691,8 @@ static void icmp_unreach(struct sk_buff *skb)
691 NIPQUAD(iph->daddr)); 691 NIPQUAD(iph->daddr));
692 } else { 692 } else {
693 info = ip_rt_frag_needed(net, iph, 693 info = ip_rt_frag_needed(net, iph,
694 ntohs(icmph->un.frag.mtu)); 694 ntohs(icmph->un.frag.mtu),
695 skb->dev);
695 if (!info) 696 if (!info)
696 goto out; 697 goto out;
697 } 698 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 08349267ceb4..e527628f56cf 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -753,23 +753,15 @@ static inline int ip_ufo_append_data(struct sock *sk,
753 skb->ip_summed = CHECKSUM_PARTIAL; 753 skb->ip_summed = CHECKSUM_PARTIAL;
754 skb->csum = 0; 754 skb->csum = 0;
755 sk->sk_sndmsg_off = 0; 755 sk->sk_sndmsg_off = 0;
756 }
757 756
758 err = skb_append_datato_frags(sk,skb, getfrag, from, 757 /* specify the length of each IP datagram fragment */
759 (length - transhdrlen));
760 if (!err) {
761 /* specify the length of each IP datagram fragment*/
762 skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 758 skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
763 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 759 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
764 __skb_queue_tail(&sk->sk_write_queue, skb); 760 __skb_queue_tail(&sk->sk_write_queue, skb);
765
766 return 0;
767 } 761 }
768 /* There is not enough support do UFO , 762
769 * so follow normal path 763 return skb_append_datato_frags(sk, skb, getfrag, from,
770 */ 764 (length - transhdrlen));
771 kfree_skb(skb);
772 return err;
773} 765}
774 766
775/* 767/*
@@ -863,9 +855,9 @@ int ip_append_data(struct sock *sk,
863 csummode = CHECKSUM_PARTIAL; 855 csummode = CHECKSUM_PARTIAL;
864 856
865 inet->cork.length += length; 857 inet->cork.length += length;
866 if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && 858 if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) &&
867 (rt->u.dst.dev->features & NETIF_F_UFO)) { 859 (sk->sk_protocol == IPPROTO_UDP) &&
868 860 (rt->u.dst.dev->features & NETIF_F_UFO)) {
869 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, 861 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
870 fragheaderlen, transhdrlen, mtu, 862 fragheaderlen, transhdrlen, mtu,
871 flags); 863 flags);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4d8d95404f45..e0514e82308e 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1186,7 +1186,14 @@ int ip_getsockopt(struct sock *sk, int level,
1186int compat_ip_getsockopt(struct sock *sk, int level, int optname, 1186int compat_ip_getsockopt(struct sock *sk, int level, int optname,
1187 char __user *optval, int __user *optlen) 1187 char __user *optval, int __user *optlen)
1188{ 1188{
1189 int err = do_ip_getsockopt(sk, level, optname, optval, optlen); 1189 int err;
1190
1191 if (optname == MCAST_MSFILTER)
1192 return compat_mc_getsockopt(sk, level, optname, optval, optlen,
1193 ip_getsockopt);
1194
1195 err = do_ip_getsockopt(sk, level, optname, optval, optlen);
1196
1190#ifdef CONFIG_NETFILTER 1197#ifdef CONFIG_NETFILTER
1191 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1198 /* we need to exclude all possible ENOPROTOOPTs except default case */
1192 if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && 1199 if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 0f42d1c1f690..89dee4346f60 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -412,12 +412,12 @@ static struct packet_type rarp_packet_type __initdata = {
412 .func = ic_rarp_recv, 412 .func = ic_rarp_recv,
413}; 413};
414 414
415static inline void ic_rarp_init(void) 415static inline void __init ic_rarp_init(void)
416{ 416{
417 dev_add_pack(&rarp_packet_type); 417 dev_add_pack(&rarp_packet_type);
418} 418}
419 419
420static inline void ic_rarp_cleanup(void) 420static inline void __init ic_rarp_cleanup(void)
421{ 421{
422 dev_remove_pack(&rarp_packet_type); 422 dev_remove_pack(&rarp_packet_type);
423} 423}
@@ -682,7 +682,7 @@ static void __init ic_bootp_init_ext(u8 *e)
682/* 682/*
683 * Initialize the DHCP/BOOTP mechanism. 683 * Initialize the DHCP/BOOTP mechanism.
684 */ 684 */
685static inline void ic_bootp_init(void) 685static inline void __init ic_bootp_init(void)
686{ 686{
687 int i; 687 int i;
688 688
@@ -696,7 +696,7 @@ static inline void ic_bootp_init(void)
696/* 696/*
697 * DHCP/BOOTP cleanup. 697 * DHCP/BOOTP cleanup.
698 */ 698 */
699static inline void ic_bootp_cleanup(void) 699static inline void __init ic_bootp_cleanup(void)
700{ 700{
701 dev_remove_pack(&bootp_packet_type); 701 dev_remove_pack(&bootp_packet_type);
702} 702}
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index dde28a250d92..4b1c16cbb16b 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -148,7 +148,7 @@ const char * ip_vs_state_name(__u16 proto, int state)
148 struct ip_vs_protocol *pp = ip_vs_proto_get(proto); 148 struct ip_vs_protocol *pp = ip_vs_proto_get(proto);
149 149
150 if (pp == NULL || pp->state_name == NULL) 150 if (pp == NULL || pp->state_name == NULL)
151 return "ERR!"; 151 return (IPPROTO_IP == proto) ? "NONE" : "ERR!";
152 return pp->state_name(state); 152 return pp->state_name(state);
153} 153}
154 154
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
index a842676e1c69..4bf835e1d86d 100644
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
@@ -160,6 +160,7 @@ static void ah_exit(struct ip_vs_protocol *pp)
160struct ip_vs_protocol ip_vs_protocol_ah = { 160struct ip_vs_protocol ip_vs_protocol_ah = {
161 .name = "AH", 161 .name = "AH",
162 .protocol = IPPROTO_AH, 162 .protocol = IPPROTO_AH,
163 .num_states = 1,
163 .dont_defrag = 1, 164 .dont_defrag = 1,
164 .init = ah_init, 165 .init = ah_init,
165 .exit = ah_exit, 166 .exit = ah_exit,
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
index aef0d3ee8e44..db6a6b7b1a0b 100644
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
@@ -159,6 +159,7 @@ static void esp_exit(struct ip_vs_protocol *pp)
159struct ip_vs_protocol ip_vs_protocol_esp = { 159struct ip_vs_protocol ip_vs_protocol_esp = {
160 .name = "ESP", 160 .name = "ESP",
161 .protocol = IPPROTO_ESP, 161 .protocol = IPPROTO_ESP,
162 .num_states = 1,
162 .dont_defrag = 1, 163 .dont_defrag = 1,
163 .init = esp_init, 164 .init = esp_init,
164 .exit = esp_exit, 165 .exit = esp_exit,
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index 620e40ff79a9..b83dc14b0a4d 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -594,6 +594,7 @@ static void ip_vs_tcp_exit(struct ip_vs_protocol *pp)
594struct ip_vs_protocol ip_vs_protocol_tcp = { 594struct ip_vs_protocol ip_vs_protocol_tcp = {
595 .name = "TCP", 595 .name = "TCP",
596 .protocol = IPPROTO_TCP, 596 .protocol = IPPROTO_TCP,
597 .num_states = IP_VS_TCP_S_LAST,
597 .dont_defrag = 0, 598 .dont_defrag = 0,
598 .appcnt = ATOMIC_INIT(0), 599 .appcnt = ATOMIC_INIT(0),
599 .init = ip_vs_tcp_init, 600 .init = ip_vs_tcp_init,
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 1caa2908373f..75771cb3cd6f 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -409,6 +409,7 @@ static void udp_exit(struct ip_vs_protocol *pp)
409struct ip_vs_protocol ip_vs_protocol_udp = { 409struct ip_vs_protocol ip_vs_protocol_udp = {
410 .name = "UDP", 410 .name = "UDP",
411 .protocol = IPPROTO_UDP, 411 .protocol = IPPROTO_UDP,
412 .num_states = IP_VS_UDP_S_LAST,
412 .dont_defrag = 0, 413 .dont_defrag = 0,
413 .init = udp_init, 414 .init = udp_init,
414 .exit = udp_exit, 415 .exit = udp_exit,
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 69c56663cc9a..eff54efe0351 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -288,11 +288,16 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
288 char *p; 288 char *p;
289 int i; 289 int i;
290 290
291 if (buflen < sizeof(struct ip_vs_sync_mesg)) {
292 IP_VS_ERR_RL("sync message header too short\n");
293 return;
294 }
295
291 /* Convert size back to host byte order */ 296 /* Convert size back to host byte order */
292 m->size = ntohs(m->size); 297 m->size = ntohs(m->size);
293 298
294 if (buflen != m->size) { 299 if (buflen != m->size) {
295 IP_VS_ERR("bogus message\n"); 300 IP_VS_ERR_RL("bogus sync message size\n");
296 return; 301 return;
297 } 302 }
298 303
@@ -307,9 +312,48 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
307 for (i=0; i<m->nr_conns; i++) { 312 for (i=0; i<m->nr_conns; i++) {
308 unsigned flags, state; 313 unsigned flags, state;
309 314
310 s = (struct ip_vs_sync_conn *)p; 315 if (p + SIMPLE_CONN_SIZE > buffer+buflen) {
316 IP_VS_ERR_RL("bogus conn in sync message\n");
317 return;
318 }
319 s = (struct ip_vs_sync_conn *) p;
311 flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC; 320 flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
321 flags &= ~IP_VS_CONN_F_HASHED;
322 if (flags & IP_VS_CONN_F_SEQ_MASK) {
323 opt = (struct ip_vs_sync_conn_options *)&s[1];
324 p += FULL_CONN_SIZE;
325 if (p > buffer+buflen) {
326 IP_VS_ERR_RL("bogus conn options in sync message\n");
327 return;
328 }
329 } else {
330 opt = NULL;
331 p += SIMPLE_CONN_SIZE;
332 }
333
312 state = ntohs(s->state); 334 state = ntohs(s->state);
335 if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
336 pp = ip_vs_proto_get(s->protocol);
337 if (!pp) {
338 IP_VS_ERR_RL("Unsupported protocol %u in sync msg\n",
339 s->protocol);
340 continue;
341 }
342 if (state >= pp->num_states) {
343 IP_VS_DBG(2, "Invalid %s state %u in sync msg\n",
344 pp->name, state);
345 continue;
346 }
347 } else {
348 /* protocol in templates is not used for state/timeout */
349 pp = NULL;
350 if (state > 0) {
351 IP_VS_DBG(2, "Invalid template state %u in sync msg\n",
352 state);
353 state = 0;
354 }
355 }
356
313 if (!(flags & IP_VS_CONN_F_TEMPLATE)) 357 if (!(flags & IP_VS_CONN_F_TEMPLATE))
314 cp = ip_vs_conn_in_get(s->protocol, 358 cp = ip_vs_conn_in_get(s->protocol,
315 s->caddr, s->cport, 359 s->caddr, s->cport,
@@ -345,14 +389,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
345 IP_VS_ERR("ip_vs_conn_new failed\n"); 389 IP_VS_ERR("ip_vs_conn_new failed\n");
346 return; 390 return;
347 } 391 }
348 cp->state = state;
349 } else if (!cp->dest) { 392 } else if (!cp->dest) {
350 dest = ip_vs_try_bind_dest(cp); 393 dest = ip_vs_try_bind_dest(cp);
351 if (!dest) { 394 if (dest)
352 /* it is an unbound entry created by
353 * synchronization */
354 cp->flags = flags | IP_VS_CONN_F_HASHED;
355 } else
356 atomic_dec(&dest->refcnt); 395 atomic_dec(&dest->refcnt);
357 } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) && 396 } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
358 (cp->state != state)) { 397 (cp->state != state)) {
@@ -371,23 +410,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
371 } 410 }
372 } 411 }
373 412
374 if (flags & IP_VS_CONN_F_SEQ_MASK) { 413 if (opt)
375 opt = (struct ip_vs_sync_conn_options *)&s[1];
376 memcpy(&cp->in_seq, opt, sizeof(*opt)); 414 memcpy(&cp->in_seq, opt, sizeof(*opt));
377 p += FULL_CONN_SIZE;
378 } else
379 p += SIMPLE_CONN_SIZE;
380
381 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]); 415 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
382 cp->state = state; 416 cp->state = state;
383 pp = ip_vs_proto_get(s->protocol); 417 cp->old_state = cp->state;
384 cp->timeout = pp->timeout_table[cp->state]; 418 /*
419 * We can not recover the right timeout for templates
420 * in all cases, we can not find the right fwmark
421 * virtual service. If needed, we can do it for
422 * non-fwmark persistent services.
423 */
424 if (!(flags & IP_VS_CONN_F_TEMPLATE) && pp->timeout_table)
425 cp->timeout = pp->timeout_table[state];
426 else
427 cp->timeout = (3*60*HZ);
385 ip_vs_conn_put(cp); 428 ip_vs_conn_put(cp);
386
387 if (p > buffer+buflen) {
388 IP_VS_ERR("bogus message\n");
389 return;
390 }
391 } 429 }
392} 430}
393 431
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 719be29f7506..26a37cedcf2e 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -296,9 +296,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
296 if (v->data_len > 0xFFFF) 296 if (v->data_len > 0xFFFF)
297 return -EINVAL; 297 return -EINVAL;
298 if (diff > skb_tailroom(e->skb)) { 298 if (diff > skb_tailroom(e->skb)) {
299 nskb = skb_copy_expand(e->skb, 0, 299 nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
300 diff - skb_tailroom(e->skb), 300 diff, GFP_ATOMIC);
301 GFP_ATOMIC);
302 if (!nskb) { 301 if (!nskb) {
303 printk(KERN_WARNING "ip_queue: error " 302 printk(KERN_WARNING "ip_queue: error "
304 "in mangle, dropping packet\n"); 303 "in mangle, dropping packet\n");
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index cacb9cb27dab..5a955c440364 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -303,7 +303,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
303 const struct nf_conntrack_tuple_hash *h; 303 const struct nf_conntrack_tuple_hash *h;
304 struct nf_conntrack_tuple tuple; 304 struct nf_conntrack_tuple tuple;
305 305
306 NF_CT_TUPLE_U_BLANK(&tuple); 306 memset(&tuple, 0, sizeof(tuple));
307 tuple.src.u3.ip = inet->rcv_saddr; 307 tuple.src.u3.ip = inet->rcv_saddr;
308 tuple.src.u.tcp.port = inet->sport; 308 tuple.src.u.tcp.port = inet->sport;
309 tuple.dst.u3.ip = inet->daddr; 309 tuple.dst.u3.ip = inet->daddr;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ce25a13f3430..5e3685c5c407 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1430,11 +1430,13 @@ static inline unsigned short guess_mtu(unsigned short old_mtu)
1430} 1430}
1431 1431
1432unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, 1432unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
1433 unsigned short new_mtu) 1433 unsigned short new_mtu,
1434 struct net_device *dev)
1434{ 1435{
1435 int i; 1436 int i, k;
1436 unsigned short old_mtu = ntohs(iph->tot_len); 1437 unsigned short old_mtu = ntohs(iph->tot_len);
1437 struct rtable *rth; 1438 struct rtable *rth;
1439 int ikeys[2] = { dev->ifindex, 0 };
1438 __be32 skeys[2] = { iph->saddr, 0, }; 1440 __be32 skeys[2] = { iph->saddr, 0, };
1439 __be32 daddr = iph->daddr; 1441 __be32 daddr = iph->daddr;
1440 unsigned short est_mtu = 0; 1442 unsigned short est_mtu = 0;
@@ -1442,22 +1444,26 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
1442 if (ipv4_config.no_pmtu_disc) 1444 if (ipv4_config.no_pmtu_disc)
1443 return 0; 1445 return 0;
1444 1446
1445 for (i = 0; i < 2; i++) { 1447 for (k = 0; k < 2; k++) {
1446 unsigned hash = rt_hash(daddr, skeys[i], 0); 1448 for (i = 0; i < 2; i++) {
1449 unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]);
1447 1450
1448 rcu_read_lock(); 1451 rcu_read_lock();
1449 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 1452 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
1450 rth = rcu_dereference(rth->u.dst.rt_next)) { 1453 rth = rcu_dereference(rth->u.dst.rt_next)) {
1451 if (rth->fl.fl4_dst == daddr &&
1452 rth->fl.fl4_src == skeys[i] &&
1453 rth->rt_dst == daddr &&
1454 rth->rt_src == iph->saddr &&
1455 rth->fl.iif == 0 &&
1456 !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) &&
1457 net_eq(dev_net(rth->u.dst.dev), net) &&
1458 rth->rt_genid == atomic_read(&rt_genid)) {
1459 unsigned short mtu = new_mtu; 1454 unsigned short mtu = new_mtu;
1460 1455
1456 if (rth->fl.fl4_dst != daddr ||
1457 rth->fl.fl4_src != skeys[i] ||
1458 rth->rt_dst != daddr ||
1459 rth->rt_src != iph->saddr ||
1460 rth->fl.oif != ikeys[k] ||
1461 rth->fl.iif != 0 ||
1462 dst_metric_locked(&rth->u.dst, RTAX_MTU) ||
1463 !net_eq(dev_net(rth->u.dst.dev), net) ||
1464 rth->rt_genid != atomic_read(&rt_genid))
1465 continue;
1466
1461 if (new_mtu < 68 || new_mtu >= old_mtu) { 1467 if (new_mtu < 68 || new_mtu >= old_mtu) {
1462 1468
1463 /* BSD 4.2 compatibility hack :-( */ 1469 /* BSD 4.2 compatibility hack :-( */
@@ -1483,8 +1489,8 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
1483 est_mtu = mtu; 1489 est_mtu = mtu;
1484 } 1490 }
1485 } 1491 }
1492 rcu_read_unlock();
1486 } 1493 }
1487 rcu_read_unlock();
1488 } 1494 }
1489 return est_mtu ? : new_mtu; 1495 return est_mtu ? : new_mtu;
1490} 1496}
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 3a6be23d222f..6a250828b767 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -285,14 +285,12 @@ int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
285 if (in_flight >= tp->snd_cwnd) 285 if (in_flight >= tp->snd_cwnd)
286 return 1; 286 return 1;
287 287
288 if (!sk_can_gso(sk))
289 return 0;
290
291 left = tp->snd_cwnd - in_flight; 288 left = tp->snd_cwnd - in_flight;
292 if (sysctl_tcp_tso_win_divisor) 289 if (sk_can_gso(sk) &&
293 return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd; 290 left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
294 else 291 left * tp->mss_cache < sk->sk_gso_max_size)
295 return left <= tcp_max_burst(tp); 292 return 1;
293 return left <= tcp_max_burst(tp);
296} 294}
297EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited); 295EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited);
298 296
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index be24d6ee34bd..0e1a8c91f78e 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -229,7 +229,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
229 */ 229 */
230 tcp_reno_cong_avoid(sk, ack, in_flight); 230 tcp_reno_cong_avoid(sk, ack, in_flight);
231 } else { 231 } else {
232 u32 rtt, target_cwnd, diff; 232 u32 rtt, diff;
233 u64 target_cwnd;
233 234
234 /* We have enough RTT samples, so, using the Vegas 235 /* We have enough RTT samples, so, using the Vegas
235 * algorithm, we determine if we should increase or 236 * algorithm, we determine if we should increase or
@@ -252,8 +253,9 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
252 * We keep it as a fixed point number with 253 * We keep it as a fixed point number with
253 * V_PARAM_SHIFT bits to the right of the binary point. 254 * V_PARAM_SHIFT bits to the right of the binary point.
254 */ 255 */
255 target_cwnd = ((old_wnd * vegas->baseRTT) 256 target_cwnd = ((u64)old_wnd * vegas->baseRTT);
256 << V_PARAM_SHIFT) / rtt; 257 target_cwnd <<= V_PARAM_SHIFT;
258 do_div(target_cwnd, rtt);
257 259
258 /* Calculate the difference between the window we had, 260 /* Calculate the difference between the window we had,
259 * and the window we would like to have. This quantity 261 * and the window we would like to have. This quantity
@@ -279,7 +281,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
279 * utilization. 281 * utilization.
280 */ 282 */
281 tp->snd_cwnd = min(tp->snd_cwnd, 283 tp->snd_cwnd = min(tp->snd_cwnd,
282 (target_cwnd >> 284 ((u32)target_cwnd >>
283 V_PARAM_SHIFT)+1); 285 V_PARAM_SHIFT)+1);
284 286
285 } else if (tp->snd_cwnd <= tp->snd_ssthresh) { 287 } else if (tp->snd_cwnd <= tp->snd_ssthresh) {
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index d16689e98516..2bf618a3b00b 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -133,7 +133,8 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
133 */ 133 */
134 tcp_reno_cong_avoid(sk, ack, in_flight); 134 tcp_reno_cong_avoid(sk, ack, in_flight);
135 } else { 135 } else {
136 u32 rtt, target_cwnd; 136 u64 target_cwnd;
137 u32 rtt;
137 138
138 /* We have enough rtt samples, so, using the Veno 139 /* We have enough rtt samples, so, using the Veno
139 * algorithm, we determine the state of the network. 140 * algorithm, we determine the state of the network.
@@ -141,8 +142,9 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
141 142
142 rtt = veno->minrtt; 143 rtt = veno->minrtt;
143 144
144 target_cwnd = ((tp->snd_cwnd * veno->basertt) 145 target_cwnd = (tp->snd_cwnd * veno->basertt);
145 << V_PARAM_SHIFT) / rtt; 146 target_cwnd <<= V_PARAM_SHIFT;
147 do_div(target_cwnd, rtt);
146 148
147 veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd; 149 veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
148 150
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index db6fdc1498aa..b4a26f2505f8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1089,6 +1089,10 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
1089 if(level != SOL_IPV6) 1089 if(level != SOL_IPV6)
1090 return -ENOPROTOOPT; 1090 return -ENOPROTOOPT;
1091 1091
1092 if (optname == MCAST_MSFILTER)
1093 return compat_mc_getsockopt(sk, level, optname, optval, optlen,
1094 ipv6_getsockopt);
1095
1092 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 1096 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
1093#ifdef CONFIG_NETFILTER 1097#ifdef CONFIG_NETFILTER
1094 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1098 /* we need to exclude all possible ENOPROTOOPTs except default case */
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 92a36c9e5402..2eff3ae8977d 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -298,9 +298,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
298 if (v->data_len > 0xFFFF) 298 if (v->data_len > 0xFFFF)
299 return -EINVAL; 299 return -EINVAL;
300 if (diff > skb_tailroom(e->skb)) { 300 if (diff > skb_tailroom(e->skb)) {
301 nskb = skb_copy_expand(e->skb, 0, 301 nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
302 diff - skb_tailroom(e->skb), 302 diff, GFP_ATOMIC);
303 GFP_ATOMIC);
304 if (!nskb) { 303 if (!nskb) {
305 printk(KERN_WARNING "ip6_queue: OOM " 304 printk(KERN_WARNING "ip6_queue: OOM "
306 "in mangle, dropping packet\n"); 305 "in mangle, dropping packet\n");
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 4eac65c74ed0..c4b1799da5d7 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -104,7 +104,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
104 const struct nf_conntrack_l3proto *l3proto, 104 const struct nf_conntrack_l3proto *l3proto,
105 const struct nf_conntrack_l4proto *l4proto) 105 const struct nf_conntrack_l4proto *l4proto)
106{ 106{
107 NF_CT_TUPLE_U_BLANK(tuple); 107 memset(tuple, 0, sizeof(*tuple));
108 108
109 tuple->src.l3num = l3num; 109 tuple->src.l3num = l3num;
110 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0) 110 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
@@ -151,7 +151,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
151 const struct nf_conntrack_l3proto *l3proto, 151 const struct nf_conntrack_l3proto *l3proto,
152 const struct nf_conntrack_l4proto *l4proto) 152 const struct nf_conntrack_l4proto *l4proto)
153{ 153{
154 NF_CT_TUPLE_U_BLANK(inverse); 154 memset(inverse, 0, sizeof(*inverse));
155 155
156 inverse->src.l3num = orig->src.l3num; 156 inverse->src.l3num = orig->src.l3num;
157 if (l3proto->invert_tuple(inverse, orig) == 0) 157 if (l3proto->invert_tuple(inverse, orig) == 0)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 2c9fe5c12894..3447025ce068 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -454,9 +454,8 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
454 if (data_len > 0xFFFF) 454 if (data_len > 0xFFFF)
455 return -EINVAL; 455 return -EINVAL;
456 if (diff > skb_tailroom(e->skb)) { 456 if (diff > skb_tailroom(e->skb)) {
457 nskb = skb_copy_expand(e->skb, 0, 457 nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
458 diff - skb_tailroom(e->skb), 458 diff, GFP_ATOMIC);
459 GFP_ATOMIC);
460 if (!nskb) { 459 if (!nskb) {
461 printk(KERN_WARNING "nf_queue: OOM " 460 printk(KERN_WARNING "nf_queue: OOM "
462 "in mangle, dropping packet\n"); 461 "in mangle, dropping packet\n");
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index f52f7f810ac4..11b22abc2b70 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -787,7 +787,7 @@ static const struct file_operations xt_table_ops = {
787 .open = xt_table_open, 787 .open = xt_table_open,
788 .read = seq_read, 788 .read = seq_read,
789 .llseek = seq_lseek, 789 .llseek = seq_lseek,
790 .release = seq_release, 790 .release = seq_release_net,
791}; 791};
792 792
793static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) 793static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 3b2aa56833b9..9685b6fcbc81 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -90,7 +90,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
90 const struct xt_target *target, const void *targinfo) 90 const struct xt_target *target, const void *targinfo)
91{ 91{
92 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 92 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
93 unsigned int tcphoff; 93 int tcphoff;
94 u_int8_t nexthdr; 94 u_int8_t nexthdr;
95 95
96 nexthdr = ipv6h->nexthdr; 96 nexthdr = ipv6h->nexthdr;
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index a20e2ef7704b..f0463d757a98 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -521,7 +521,8 @@ static void sfq_destroy(struct Qdisc *sch)
521 struct sfq_sched_data *q = qdisc_priv(sch); 521 struct sfq_sched_data *q = qdisc_priv(sch);
522 522
523 tcf_destroy_chain(q->filter_list); 523 tcf_destroy_chain(q->filter_list);
524 del_timer(&q->perturb_timer); 524 q->perturb_period = 0;
525 del_timer_sync(&q->perturb_timer);
525} 526}
526 527
527static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) 528static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)