From f649a3bfd1b0ad8872312ed1c223d69b74406e1f Mon Sep 17 00:00:00 2001 From: Yasuyuki KOZAKAI Date: Mon, 25 Apr 2005 12:00:04 -0700 Subject: [PATCH 1/8] [NETFILTER]: Fix truncated sequence numbers in FTP helper Signed-off-by: Yasuyuki KOZAKAI Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_ftp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 12b88cbb11db..dd86503aa788 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -252,7 +252,7 @@ static int find_pattern(const char *data, size_t dlen, } /* Look up to see if we're just after a \n. */ -static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir) +static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir) { unsigned int i; @@ -263,7 +263,7 @@ static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir) } /* We don't update if it's older than what we have. */ -static void update_nl_seq(u16 nl_seq, struct ip_ct_ftp_master *info, int dir) +static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir) { unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; From b31e5b1bb53b99dfd5e890aa07e943aff114ae1c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 25 Apr 2005 12:01:07 -0700 Subject: [PATCH 2/8] [NETFILTER]: Drop conntrack reference when packet leaves IP In the event a raw socket is created for sending purposes only, the creator never bothers to check the socket's receive queue. But we continue to add skbs to its queue until it fills up. Unfortunately, if ip_conntrack is loaded on the box, each skb we add to the queue potentially holds a reference to a conntrack. If the user attempts to unload ip_conntrack, we will spin around forever since the queued skbs are pinned. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 2 ++ net/ipv4/netfilter/ip_conntrack_standalone.c | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 30ab7b6ab761..38f69532a029 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -195,6 +195,8 @@ static inline int ip_finish_output2(struct sk_buff *skb) nf_debug_ip_finish_output2(skb); #endif /*CONFIG_NETFILTER_DEBUG*/ + nf_reset(skb); + if (hh) { int hh_alen; diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 0c29ccf62a89..46ca45f74d85 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -431,13 +431,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum, const struct net_device *out, int (*okfn)(struct sk_buff *)) { -#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE) - /* Previously seen (loopback)? Ignore. Do this before - fragment check. */ - if ((*pskb)->nfct) - return NF_ACCEPT; -#endif - /* Gather fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { *pskb = ip_ct_gather_frags(*pskb, From cbdbf00aaf0addd391259f94aaa8e7dc1bfc9081 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 25 Apr 2005 12:15:01 -0700 Subject: [PATCH 3/8] [PKT_SCHED]: Eliminate unnecessary includes in simple.c Noted by Al Viro. Signed-off-by: David S. Miller --- net/sched/simple.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/net/sched/simple.c b/net/sched/simple.c index b0d3d15848ad..3ab4c675ab5d 100644 --- a/net/sched/simple.c +++ b/net/sched/simple.c @@ -10,27 +10,13 @@ * */ -#include -#include -#include #include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include -#include -#include -#include #include #define TCA_ACT_SIMP 22 From 483ba50bd41d14d5325d6cd9935de86a982d08a2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2005 15:14:03 -0700 Subject: [PATCH 4/8] [TG3]: Fix bug in tg3_rx() This patch fixes a bug that causes tg3_has_work() to always return 1. rx work is determined by comparing tp->rx_rcb_ptr with the current hw producer index. The hw producer index is modulo the ring size, but tp- >rx_rcb_ptr is a free running counter that goes up beyond the ring size. After the ring wraps around once, tg3_has_work() will always return 1. The fix is to always do modulo arithmetic on tp->rx_rcb_ptr. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 10d476153ee0..e53c1dc58d08 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2686,8 +2686,8 @@ static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag) static int tg3_rx(struct tg3 *tp, int budget) { u32 work_mask; - u32 rx_rcb_ptr = tp->rx_rcb_ptr; - u16 hw_idx, sw_idx; + u32 sw_idx = tp->rx_rcb_ptr; + u16 hw_idx; int received; hw_idx = tp->hw_status->idx[0].rx_producer; @@ -2696,7 +2696,6 @@ static int tg3_rx(struct tg3 *tp, int budget) * the opaque cookie. */ rmb(); - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); work_mask = 0; received = 0; while (sw_idx != hw_idx && budget > 0) { @@ -2801,14 +2800,13 @@ static int tg3_rx(struct tg3 *tp, int budget) next_pkt: (*post_ptr)++; next_pkt_nopost: - rx_rcb_ptr++; - sw_idx = rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp); + sw_idx++; + sw_idx %= TG3_RX_RCB_RING_SIZE(tp); } /* ACK the status ring. */ - tp->rx_rcb_ptr = rx_rcb_ptr; - tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, - (rx_rcb_ptr % TG3_RX_RCB_RING_SIZE(tp))); + tp->rx_rcb_ptr = sw_idx; + tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx); /* Refill RX ring(s). */ if (work_mask & RXD_OPAQUE_RING_STD) { From 52f6d697dc0f2c039e8413e780b0f45ddf8161fc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2005 15:14:32 -0700 Subject: [PATCH 5/8] [TG3]: Refresh hw index in tg3_rx() This patch refreshes the hw rx producer in tg3_rx() so that additional work posted by the hardware can be processed. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e53c1dc58d08..92b0e4975135 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2802,6 +2802,12 @@ static int tg3_rx(struct tg3 *tp, int budget) next_pkt_nopost: sw_idx++; sw_idx %= TG3_RX_RCB_RING_SIZE(tp); + + /* Refresh hw_idx to see if there is new work */ + if (sw_idx == hw_idx) { + hw_idx = tp->hw_status->idx[0].rx_producer; + rmb(); + } } /* ACK the status ring. */ From 04237dddd14375fce1df4bfb1be92a35aa1c247f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2005 15:17:17 -0700 Subject: [PATCH 6/8] [TG3]: Fix tg3_restart_ints() tg3_restart_ints() is called to re-enable interrupts after tg3_poll() has finished all the work. It calls tg3_cond_int() to force an interrupt if the status block updated bit is set. The updated bit will be set if there is a new status block update sometime during tg3_poll() and it can be very often. The worst part is that even if all the work has been processed, the updated bit remains set and an interrupt will be forced unnecessarily. The fix is to call tg3_has_work() instead to determine if new work is posted before forcing an interrupt. The way to force an interrupt is also changed to use "coalesce_now" instead of "SETINT". The former is generally a safer way to force the interrupt. Also deleted the first parameter to tg3_has_work() which is unused. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 53 +++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 92b0e4975135..903d0ced7ddb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -426,9 +426,30 @@ static void tg3_enable_ints(struct tg3 *tp) tg3_cond_int(tp); } +static inline unsigned int tg3_has_work(struct tg3 *tp) +{ + struct tg3_hw_status *sblk = tp->hw_status; + unsigned int work_exists = 0; + + /* check for phy events */ + if (!(tp->tg3_flags & + (TG3_FLAG_USE_LINKCHG_REG | + TG3_FLAG_POLL_SERDES))) { + if (sblk->status & SD_STATUS_LINK_CHG) + work_exists = 1; + } + /* check for RX/TX work to do */ + if (sblk->idx[0].tx_consumer != tp->tx_cons || + sblk->idx[0].rx_producer != tp->rx_rcb_ptr) + work_exists = 1; + + return work_exists; +} + /* tg3_restart_ints - * similar to tg3_enable_ints, but it can return without flushing the - * PIO write which reenables interrupts + * similar to tg3_enable_ints, but it accurately determines whether there + * is new work pending and can return without flushing the PIO write + * which reenables interrupts */ static void tg3_restart_ints(struct tg3 *tp) { @@ -437,7 +458,9 @@ static void tg3_restart_ints(struct tg3 *tp) tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); mmiowb(); - tg3_cond_int(tp); + if (tg3_has_work(tp)) + tw32(HOSTCC_MODE, tp->coalesce_mode | + (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); } static inline void tg3_netif_stop(struct tg3 *tp) @@ -2891,26 +2914,6 @@ static int tg3_poll(struct net_device *netdev, int *budget) return (done ? 0 : 1); } -static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp) -{ - struct tg3_hw_status *sblk = tp->hw_status; - unsigned int work_exists = 0; - - /* check for phy events */ - if (!(tp->tg3_flags & - (TG3_FLAG_USE_LINKCHG_REG | - TG3_FLAG_POLL_SERDES))) { - if (sblk->status & SD_STATUS_LINK_CHG) - work_exists = 1; - } - /* check for RX/TX work to do */ - if (sblk->idx[0].tx_consumer != tp->tx_cons || - sblk->idx[0].rx_producer != tp->rx_rcb_ptr) - work_exists = 1; - - return work_exists; -} - /* MSI ISR - No need to check for interrupt sharing and no need to * flush status block and interrupt mailbox. PCI ordering rules * guarantee that MSI will arrive after the status block. @@ -2934,7 +2937,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(dev, tp))) + if (likely(tg3_has_work(tp))) netif_rx_schedule(dev); /* schedule NAPI poll */ else { /* no work, re-enable interrupts @@ -2981,7 +2984,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(dev, tp))) + if (likely(tg3_has_work(tp))) netif_rx_schedule(dev); /* schedule NAPI poll */ else { /* no work, shared interrupt perhaps? re-enable From 088dd3a45fdb8fb726cd50575856562c4f6f1c3e Mon Sep 17 00:00:00 2001 From: James Morris Date: Mon, 25 Apr 2005 21:39:29 -0700 Subject: [PATCH 7/8] [TCP]: Trivial tcp_data_queue() cleanup This patch removes a superfluous intialization from tcp_data_queue(). Signed-off-by: James Morris Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 250492735902..6984042c0927 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3517,7 +3517,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) goto drop; - th = skb->h.th; __skb_pull(skb, th->doff*4); TCP_ECN_accept_cwr(tp, skb); From 5523662c4cd585b892811d7bb3e25d9a787e19b3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 25 Apr 2005 21:40:39 -0700 Subject: [PATCH 8/8] [NET]: kill gratitious includes of major.h A lot of places in there are including major.h for no reason whatsoever. Removed. And yes, it still builds. The history of that stuff is often amusing. E.g. for net/core/sock.c the story looks so, as far as I've been able to reconstruct it: we used to need major.h in net/socket.c circa 1.1.early. In 1.1.13 that need had disappeared, along with register_chrdev(SOCKET_MAJOR, "socket", &net_fops) in sock_init(). Include had not. When 1.2 -> 1.3 reorg of net/* had moved a lot of stuff from net/socket.c to net/core/sock.c, this crap had followed... Signed-off-by: Al Viro Signed-off-by: David S. Miller --- net/bluetooth/af_bluetooth.c | 1 - net/bluetooth/bnep/sock.c | 1 - net/bluetooth/cmtp/capi.c | 1 - net/bluetooth/cmtp/core.c | 1 - net/bluetooth/cmtp/sock.c | 1 - net/bluetooth/hci_conn.c | 1 - net/bluetooth/hci_core.c | 1 - net/bluetooth/hci_event.c | 1 - net/bluetooth/hci_sock.c | 1 - net/bluetooth/hidp/core.c | 1 - net/bluetooth/hidp/sock.c | 1 - net/bluetooth/l2cap.c | 1 - net/bluetooth/rfcomm/sock.c | 1 - net/bluetooth/sco.c | 1 - net/core/rtnetlink.c | 1 - net/core/scm.c | 1 - net/core/sock.c | 1 - net/ipv4/af_inet.c | 1 - net/ipv6/af_inet6.c | 1 - net/netlink/af_netlink.c | 1 - net/unix/af_unix.c | 1 - 21 files changed, 21 deletions(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 1650c6bf6997..12b43345b54f 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 9a8d99a39b6d..9778c6acd53b 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 1e5c030b72ad..b2e7e38531c6 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 20ce04f2be8b..2e341de3e763 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 4c7f9e20dade..beb045bf5714 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 71762d7e9970..a31244e58888 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 860dba7bdd89..fb5524365bc2 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8ccba8ee9979..c4b592b4ef10 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index c9792ba75122..ebdcce5e7ca0 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 2cf98ceabcc7..affbc55462e8 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index fabb36d4666b..f8986f881431 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c12babcf0b3c..32fccfb5bfa5 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 640028a2183c..f3f6355a2786 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 3e750ef09e60..746c11fc017e 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 44dfaf8f04af..d8c198e42f90 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/net/core/scm.c b/net/core/scm.c index a2ebf30f6aa8..e887d19be506 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/net/core/sock.c b/net/core/sock.c index 4df4fa3c5de0..5c2f72fa1013 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -97,7 +97,6 @@ #include #include #include -#include #include #include #include diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index c34dab67e461..cdad47642ae7 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -73,7 +73,6 @@ #include #include #include -#include #include #include #include diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 53a6680d540f..2b193e3df49a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 1d5905c90cd4..29a5fd231eac 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index acc73fe68698..c478fc8db776 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -85,7 +85,6 @@ #include #include #include -#include #include #include #include