From f3f511e1ce6f1a6f0a5bb8320e9f802e76f6b999 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 5 Jan 2012 20:16:39 +0000 Subject: net: fix sock_clone reference mismatch with tcp memcontrol Sockets can also be created through sock_clone. Because it copies all data in the sock structure, it also copies the memcg-related pointer, and all should be fine. However, since we now use reference counts in socket creation, we are left with some sockets that have no reference counts. It matters when we destroy them, since it leads to a mismatch. Signed-off-by: Glauber Costa CC: David S. Miller CC: Greg Thelen CC: Hiroyouki Kamezawa CC: Laurent Chavey Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index bb972d2..0ed65e3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1103,6 +1103,12 @@ sk_sockets_allocated_read_positive(struct sock *sk) return percpu_counter_sum_positive(prot->sockets_allocated); } +static inline void sk_update_clone(const struct sock *sk, struct sock *newsk) +{ + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sock_update_memcg(newsk); +} + static inline int proto_sockets_allocated_sum_positive(struct proto *prot) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 94da8ee..9c72d5d 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -381,16 +381,25 @@ static void mem_cgroup_put(struct mem_cgroup *memcg); static bool mem_cgroup_is_root(struct mem_cgroup *memcg); void sock_update_memcg(struct sock *sk) { - /* A socket spends its whole life in the same cgroup */ - if (sk->sk_cgrp) { - WARN_ON(1); - return; - } if (static_branch(&memcg_socket_limit_enabled)) { struct mem_cgroup *memcg; BUG_ON(!sk->sk_prot->proto_cgroup); + /* Socket cloning can throw us here with sk_cgrp already + * filled. It won't however, necessarily happen from + * process context. So the test for root memcg given + * the current task's memcg won't help us in this case. + * + * Respecting the original socket's memcg is a better + * decision in this case. + */ + if (sk->sk_cgrp) { + BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); + mem_cgroup_get(sk->sk_cgrp->memcg); + return; + } + rcu_read_lock(); memcg = mem_cgroup_from_task(current); if (!mem_cgroup_is_root(memcg)) { diff --git a/net/core/sock.c b/net/core/sock.c index 002939c..e80b64f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1362,6 +1362,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sk_set_socket(newsk, NULL); newsk->sk_wq = NULL; + sk_update_clone(sk, newsk); + if (newsk->sk_prot->sockets_allocated) sk_sockets_allocated_inc(newsk); -- cgit v0.10.2 From 77e1e438cbb1b8f9b7a3bb2d4f0264d1dd952d75 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Sat, 7 Jan 2012 05:13:17 +0000 Subject: r6040: fix typo in use of MCR0 register bits Commit 4e16d6ebd65b4f2c4e3f780b4c5704beef64019c (r6040: define more MCR0 register bits) added #define values for MCR0 register bits and converted uses of hardcoded magic values to uses of these defines. However, one of the conversions looks suspicious: #define MCR0 0x00 /* Control register 0 */ +#define MCR0_RCVEN 0x0002 /* Receive enable */ +#define MCR0_XMTEN 0x1000 /* Transmission enable */ /* Init RDC private data */ - lp->mcr0 = 0x1002; + lp->mcr0 = MCR0_XMTEN | MCR0; I believe what was meant here was MCR0_XMTEN | MCR0_RCVEN, which makes sense and matches the original values. Signed-off-by: Cesar Eduardo Barros Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 87aa439..cb0eca8 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1160,7 +1160,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, lp->dev = dev; /* Init RDC private data */ - lp->mcr0 = MCR0_XMTEN | MCR0; + lp->mcr0 = MCR0_XMTEN | MCR0_RCVEN; /* The RDC-specific entries in the device structure. */ dev->netdev_ops = &r6040_netdev_ops; -- cgit v0.10.2 From 6d62a66e4211546f9e5c5d1ad586749a51cf30db Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 7 Jan 2012 12:13:06 -0800 Subject: net: Default UDP and UNIX diag to 'n'. Signed-off-by: David S. Miller diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 1a8f93b..43e1439 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -410,8 +410,12 @@ config INET_TCP_DIAG def_tristate INET_DIAG config INET_UDP_DIAG + tristate "UDP: socket monitoring interface" depends on INET_DIAG - def_tristate INET_DIAG && IPV6 + default n + ---help--- + Support for UDP socket monitoring interface used by the ss tool. + If unsure, say Y. menuconfig TCP_CONG_ADVANCED bool "TCP: advanced congestion control" diff --git a/net/unix/Kconfig b/net/unix/Kconfig index c2128b1..8b31ab8 100644 --- a/net/unix/Kconfig +++ b/net/unix/Kconfig @@ -22,7 +22,7 @@ config UNIX config UNIX_DIAG tristate "UNIX: socket monitoring interface" depends on UNIX - default UNIX + default n ---help--- Support for UNIX socket monitoring interface used by the ss tool. If unsure, say Y. -- cgit v0.10.2 From 6c15d74defd38e7e7f8805392578b7a1d508097e Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Sat, 7 Jan 2012 12:15:16 -0800 Subject: asix: fix infinite loop in rx_fixup() At this point if skb->len happens to be 2, the subsequant skb_pull(skb, 4) call won't work and the skb->len won't be decreased and won't ever reach 0, resulting in an infinite loop. With an ASIX 88772 under heavy load, without this patch, rx_fixup() reaches an infinite loop in less than a minute. With this patch applied, no infinite loop even after hours of heavy load. Signed-off-by: Aurelien Jacobs Signed-off-by: David S. Miller diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index dbdca22..df2b08d 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -376,7 +376,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) skb_pull(skb, (size + 1) & 0xfffe); - if (skb->len == 0) + if (skb->len < sizeof(header)) break; head = (u8 *) skb->data; -- cgit v0.10.2 From 96dab45fc3eb732de7b7fe03d2250d3815af8929 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 7 Jan 2012 12:22:11 -0800 Subject: smsc911x: Unconditionally include linux/smscphy.h in smsc911x.h The energy detect enable/disable code in the driver uses some register defines in this header unconditionally, so guarding the smscphy.h header include with CONFIG_SMSC_PHY leads to build failures in some configurations. Reported-by: Shawn Guo Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/smsc/smsc911x.h b/drivers/net/ethernet/smsc/smsc911x.h index 938ecf2..9ad5e5d 100644 --- a/drivers/net/ethernet/smsc/smsc911x.h +++ b/drivers/net/ethernet/smsc/smsc911x.h @@ -401,8 +401,6 @@ #include #endif -#ifdef CONFIG_SMSC_PHY #include -#endif #endif /* __SMSC911X_H__ */ -- cgit v0.10.2 From 26e29eeda048aa6699984c4b9d6997dd1a1315db Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 6 Jan 2012 03:13:47 +0000 Subject: pktgen: set correct max and min in pktgen_setup_inject() In 882716604ec "pktgen: fix multiple queue warning" we added special logic to handle the case where ntxq is zero. It's not clear to me that ntxq can actually be zero. But if it were then we would set ->queue_map_min and ->queue_map_max to USHRT_MAX when probably we want to set them to zero? Signed-off-by: David S. Miller diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 449fe0f..65f80c7 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2024,13 +2024,13 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) pr_warning("WARNING: Requested queue_map_min (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, pkt_dev->odevname); - pkt_dev->queue_map_min = ntxq - 1; + pkt_dev->queue_map_min = (ntxq ?: 1) - 1; } if (pkt_dev->queue_map_max >= ntxq) { pr_warning("WARNING: Requested queue_map_max (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, pkt_dev->odevname); - pkt_dev->queue_map_max = ntxq - 1; + pkt_dev->queue_map_max = (ntxq ?: 1) - 1; } /* Default to the interface's mac if not explicitly set. */ -- cgit v0.10.2 From b189e810619a676e6b931a942a3e8387f3d39c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Sun, 8 Jan 2012 13:41:33 +0000 Subject: 8139cp: fix missing napi_gro_flush. The driver uses __napi_complete and napi_gro_receive. Without it, the driver hits the BUG_ON(n->gro_list) assertion hard in __napi_complete. Signed-off-by: Francois Romieu Tested-by: Marin Glibic Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index cc6b391..abc7907 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -563,6 +563,7 @@ rx_next: if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; + napi_gro_flush(napi); spin_lock_irqsave(&cp->lock, flags); __napi_complete(napi); cpw16_f(IntrMask, cp_intr_mask); -- cgit v0.10.2 From 475f1b52645a29936b9df1d8fcd45f7e56bd4a9f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 9 Jan 2012 16:33:16 +1100 Subject: net: sk_update_clone is only used in net/core/sock.c so move it there. Fixes build errors when CONFIG_INET is not defined: In file included from include/linux/tcp.h:211:0, from include/linux/ipv6.h:221, from include/net/ipv6.h:16, from include/linux/sunrpc/clnt.h:26, from include/linux/nfs_fs.h:50, from init/do_mounts.c:20: include/net/sock.h: In function 'sk_update_clone': include/net/sock.h:1109:3: error: implicit declaration of function 'sock_update_memcg' [-Werror=implicit-function-declaration] Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 0ed65e3..bb972d2 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1103,12 +1103,6 @@ sk_sockets_allocated_read_positive(struct sock *sk) return percpu_counter_sum_positive(prot->sockets_allocated); } -static inline void sk_update_clone(const struct sock *sk, struct sock *newsk) -{ - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sock_update_memcg(newsk); -} - static inline int proto_sockets_allocated_sum_positive(struct proto *prot) { diff --git a/net/core/sock.c b/net/core/sock.c index e80b64f..c3ae73d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1272,6 +1272,12 @@ void sk_release_kernel(struct sock *sk) } EXPORT_SYMBOL(sk_release_kernel); +static void sk_update_clone(const struct sock *sk, struct sock *newsk) +{ + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sock_update_memcg(newsk); +} + /** * sk_clone_lock - clone a socket, and lock its clone * @sk: the socket to clone -- cgit v0.10.2 From ab16ebf375f0513d6b0f5193de84186a3fc0c33b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 9 Jan 2012 06:18:34 +0000 Subject: net: correct lock name in dev_[uc/mc]_sync documentations. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index febba51..c34ce9f 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -427,7 +427,7 @@ EXPORT_SYMBOL(dev_uc_del); * * Add newly added addresses to the destination device and release * addresses that have no users left. The source device must be - * locked by netif_tx_lock_bh. + * locked by netif_addr_lock_bh. * * This function is intended to be called from the dev->set_rx_mode * function of layered software devices. @@ -590,7 +590,7 @@ EXPORT_SYMBOL(dev_mc_del_global); * * Add newly added addresses to the destination device and release * addresses that have no users left. The source device must be - * locked by netif_tx_lock_bh. + * locked by netif_addr_lock_bh. * * This function is intended to be called from the ndo_set_rx_mode * function of layered software devices. -- cgit v0.10.2 From 2429f7ac2ef429378536d87fcbbf6f424aa5b47f Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 9 Jan 2012 06:36:54 +0000 Subject: net: introduce netif_addr_lock_nested() and call if when appropriate dev_uc_sync() and dev_mc_sync() are acquiring netif_addr_lock for destination device of synchronization. Since netif_addr_lock is already held at the time for source device, this triggers lockdep deadlock warning. There's no way this deadlock can happen so use spin_lock_nested() to silence the warning. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a1d1095..d0522bb 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2450,6 +2450,11 @@ static inline void netif_addr_lock(struct net_device *dev) spin_lock(&dev->addr_list_lock); } +static inline void netif_addr_lock_nested(struct net_device *dev) +{ + spin_lock_nested(&dev->addr_list_lock, SINGLE_DEPTH_NESTING); +} + static inline void netif_addr_lock_bh(struct net_device *dev) { spin_lock_bh(&dev->addr_list_lock); diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index c34ce9f..29c07fe 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -439,11 +439,11 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_bh(to); + netif_addr_lock_nested(to); err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); if (!err) __dev_set_rx_mode(to); - netif_addr_unlock_bh(to); + netif_addr_unlock(to); return err; } EXPORT_SYMBOL(dev_uc_sync); @@ -463,7 +463,7 @@ void dev_uc_unsync(struct net_device *to, struct net_device *from) return; netif_addr_lock_bh(from); - netif_addr_lock(to); + netif_addr_lock_nested(to); __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -602,11 +602,11 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_bh(to); + netif_addr_lock_nested(to); err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); if (!err) __dev_set_rx_mode(to); - netif_addr_unlock_bh(to); + netif_addr_unlock(to); return err; } EXPORT_SYMBOL(dev_mc_sync); @@ -626,7 +626,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) return; netif_addr_lock_bh(from); - netif_addr_lock(to); + netif_addr_lock_nested(to); __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); __dev_set_rx_mode(to); netif_addr_unlock(to); -- cgit v0.10.2 From 3969eb3859e4fad4b32ca8f96d4ec8551c20704a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 9 Jan 2012 13:44:23 -0800 Subject: net: Fix build with INET disabled. > net/core/sock.c: In function 'sk_update_clone': > net/core/sock.c:1278:3: error: implicit declaration of function 'sock_update_memcg' Reported-by: Randy Dunlap Signed-off-by: David S. Miller diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 9b296ea..f944591 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -390,7 +390,6 @@ enum { OVER_LIMIT, }; -#ifdef CONFIG_INET struct sock; #ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM void sock_update_memcg(struct sock *sk); @@ -403,6 +402,5 @@ static inline void sock_release_memcg(struct sock *sk) { } #endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */ -#endif /* CONFIG_INET */ #endif /* _LINUX_MEMCONTROL_H */ diff --git a/net/core/sock.c b/net/core/sock.c index c3ae73d..5c5af998 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -112,6 +112,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From bc689c9788f2cc9829d01d84083bc1714b969b15 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 5 Jan 2012 19:10:23 +0000 Subject: usbnet: make ethtool_ops const The ethtool_ops table of function pointers should be const. Fix all the usb network drivers. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index df2b08d..5857a40 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1152,7 +1152,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) return 0; } -static struct ethtool_ops ax88178_ethtool_ops = { +static const struct ethtool_ops ax88178_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, .get_link = asix_get_link, .get_msglevel = usbnet_get_msglevel, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 009dd0f..47fca6f 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -138,7 +138,7 @@ struct cdc_ncm_ctx { static void cdc_ncm_tx_timeout(unsigned long arg); static const struct driver_info cdc_ncm_info; static struct usb_driver cdc_ncm_driver; -static struct ethtool_ops cdc_ncm_ethtool_ops; +static const struct ethtool_ops cdc_ncm_ethtool_ops; static const struct usb_device_id cdc_devs[] = { { USB_INTERFACE_INFO(USB_CLASS_COMM, @@ -1220,7 +1220,7 @@ static struct usb_driver cdc_ncm_driver = { .supports_autosuspend = 1, }; -static struct ethtool_ops cdc_ncm_ethtool_ops = { +static const struct ethtool_ops cdc_ncm_ethtool_ops = { .get_drvinfo = cdc_ncm_get_drvinfo, .get_link = usbnet_get_link, .get_msglevel = usbnet_get_msglevel, diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 13c1f04..a9a97c8 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -420,7 +420,7 @@ static u32 ipheth_ethtool_op_get_link(struct net_device *net) return netif_carrier_ok(dev->net); } -static struct ethtool_ops ops = { +static const struct ethtool_ops ops = { .get_link = ipheth_ethtool_op_get_link }; diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index ed1b432..6253486 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -618,7 +618,7 @@ static u32 sierra_net_get_link(struct net_device *net) return sierra_net_get_private(dev)->link_up && netif_running(net); } -static struct ethtool_ops sierra_net_ethtool_ops = { +static const struct ethtool_ops sierra_net_ethtool_ops = { .get_drvinfo = sierra_net_get_drvinfo, .get_link = sierra_net_get_link, .get_msglevel = usbnet_get_msglevel, -- cgit v0.10.2 From 1aff0cbe9d51236efba2e721a34e2c15779f95f3 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 5 Jan 2012 19:10:24 +0000 Subject: bcm63xx: make ethtool_ops const Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index a11a8ad..d44331e 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1469,7 +1469,7 @@ static int bcm_enet_set_pauseparam(struct net_device *dev, return 0; } -static struct ethtool_ops bcm_enet_ethtool_ops = { +static const struct ethtool_ops bcm_enet_ethtool_ops = { .get_strings = bcm_enet_get_strings, .get_sset_count = bcm_enet_get_sset_count, .get_ethtool_stats = bcm_enet_get_ethtool_stats, -- cgit v0.10.2 From e5686ad82ca2aeed7a8f24ffca115c0b7478dec9 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 5 Jan 2012 19:10:25 +0000 Subject: netdev: make net_device_ops const More drivers where net_device_ops should be const. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 6c46753..a6bcdb5 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3080,7 +3080,7 @@ fw_exit: return status; } -static struct net_device_ops be_netdev_ops = { +static const struct net_device_ops be_netdev_ops = { .ndo_open = be_open, .ndo_stop = be_close, .ndo_start_xmit = be_xmit, diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 6b75063..d9951af 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c @@ -2260,8 +2260,7 @@ static int tile_net_get_mac(struct net_device *dev) return 0; } - -static struct net_device_ops tile_net_ops = { +static const struct net_device_ops tile_net_ops = { .ndo_open = tile_net_open, .ndo_stop = tile_net_stop, .ndo_start_xmit = tile_net_tx, -- cgit v0.10.2 From a8c1f65c79cbbb2f7da782d4c9d15639a9b94b27 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 14:06:46 -0800 Subject: igmp: Avoid zero delay when receiving odd mixture of IGMP queries Commit 5b7c84066733c5dfb0e4016d939757b38de189e4 ('ipv4: correct IGMP behavior on v3 query during v2-compatibility mode') added yet another case for query parsing, which can result in max_delay = 0. Substitute a value of 1, as in the usual v3 case. Reported-by: Simon McVittie References: http://bugs.debian.org/654876 Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index fa057d1..5104bc0 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -880,6 +880,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, * to be intended in a v3 query. */ max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); + if (!max_delay) + max_delay = 1; /* can't mod w/ 0 */ } else { /* v3 */ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) return; -- cgit v0.10.2