aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bnx2x.h4
-rw-r--r--drivers/net/bnx2x_main.c42
-rw-r--r--drivers/net/bonding/bond_alb.c2
-rw-r--r--drivers/net/igb/igb_main.c9
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c9
-rw-r--r--drivers/net/macvlan.c10
-rw-r--r--drivers/net/macvtap.c18
-rw-r--r--drivers/net/s2io.h2
-rw-r--r--drivers/net/tun.c14
-rw-r--r--drivers/net/wimax/i2400m/i2400m-usb.h1
-rw-r--r--drivers/net/wimax/i2400m/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
-rw-r--r--include/linux/if_macvlan.h2
-rw-r--r--include/net/tc_act/tc_mirred.h1
-rw-r--r--net/core/dev.c1
-rw-r--r--net/core/skbuff.c7
-rw-r--r--net/ipv6/addrconf.c14
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/sched/act_mirred.c43
19 files changed, 151 insertions, 36 deletions
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 8bd23687c53..bb0872a6331 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1062,6 +1062,10 @@ struct bnx2x {
1062 1062
1063 /* used to synchronize stats collecting */ 1063 /* used to synchronize stats collecting */
1064 int stats_state; 1064 int stats_state;
1065
1066 /* used for synchronization of concurrent threads statistics handling */
1067 spinlock_t stats_lock;
1068
1065 /* used by dmae command loader */ 1069 /* used by dmae command loader */
1066 struct dmae_command stats_dmae; 1070 struct dmae_command stats_dmae;
1067 int executer_idx; 1071 int executer_idx;
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 57ff5b3bcce..46167c08172 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -57,8 +57,8 @@
57#include "bnx2x_init_ops.h" 57#include "bnx2x_init_ops.h"
58#include "bnx2x_dump.h" 58#include "bnx2x_dump.h"
59 59
60#define DRV_MODULE_VERSION "1.52.53-1" 60#define DRV_MODULE_VERSION "1.52.53-2"
61#define DRV_MODULE_RELDATE "2010/18/04" 61#define DRV_MODULE_RELDATE "2010/21/07"
62#define BNX2X_BC_VER 0x040200 62#define BNX2X_BC_VER 0x040200
63 63
64#include <linux/firmware.h> 64#include <linux/firmware.h>
@@ -3789,6 +3789,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
3789 struct eth_query_ramrod_data ramrod_data = {0}; 3789 struct eth_query_ramrod_data ramrod_data = {0};
3790 int i, rc; 3790 int i, rc;
3791 3791
3792 spin_lock_bh(&bp->stats_lock);
3793
3792 ramrod_data.drv_counter = bp->stats_counter++; 3794 ramrod_data.drv_counter = bp->stats_counter++;
3793 ramrod_data.collect_port = bp->port.pmf ? 1 : 0; 3795 ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
3794 for_each_queue(bp, i) 3796 for_each_queue(bp, i)
@@ -3802,6 +3804,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
3802 bp->spq_left++; 3804 bp->spq_left++;
3803 bp->stats_pending = 1; 3805 bp->stats_pending = 1;
3804 } 3806 }
3807
3808 spin_unlock_bh(&bp->stats_lock);
3805 } 3809 }
3806} 3810}
3807 3811
@@ -4367,6 +4371,14 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
4367 struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); 4371 struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
4368 struct bnx2x_eth_stats *estats = &bp->eth_stats; 4372 struct bnx2x_eth_stats *estats = &bp->eth_stats;
4369 int i; 4373 int i;
4374 u16 cur_stats_counter;
4375
4376 /* Make sure we use the value of the counter
4377 * used for sending the last stats ramrod.
4378 */
4379 spin_lock_bh(&bp->stats_lock);
4380 cur_stats_counter = bp->stats_counter - 1;
4381 spin_unlock_bh(&bp->stats_lock);
4370 4382
4371 memcpy(&(fstats->total_bytes_received_hi), 4383 memcpy(&(fstats->total_bytes_received_hi),
4372 &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), 4384 &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi),
@@ -4394,25 +4406,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
4394 u32 diff; 4406 u32 diff;
4395 4407
4396 /* are storm stats valid? */ 4408 /* are storm stats valid? */
4397 if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != 4409 if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) {
4398 bp->stats_counter) {
4399 DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" 4410 DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
4400 " xstorm counter (0x%x) != stats_counter (0x%x)\n", 4411 " xstorm counter (0x%x) != stats_counter (0x%x)\n",
4401 i, xclient->stats_counter, bp->stats_counter); 4412 i, xclient->stats_counter, cur_stats_counter + 1);
4402 return -1; 4413 return -1;
4403 } 4414 }
4404 if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != 4415 if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) {
4405 bp->stats_counter) {
4406 DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" 4416 DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
4407 " tstorm counter (0x%x) != stats_counter (0x%x)\n", 4417 " tstorm counter (0x%x) != stats_counter (0x%x)\n",
4408 i, tclient->stats_counter, bp->stats_counter); 4418 i, tclient->stats_counter, cur_stats_counter + 1);
4409 return -2; 4419 return -2;
4410 } 4420 }
4411 if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != 4421 if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) {
4412 bp->stats_counter) {
4413 DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" 4422 DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
4414 " ustorm counter (0x%x) != stats_counter (0x%x)\n", 4423 " ustorm counter (0x%x) != stats_counter (0x%x)\n",
4415 i, uclient->stats_counter, bp->stats_counter); 4424 i, uclient->stats_counter, cur_stats_counter + 1);
4416 return -4; 4425 return -4;
4417 } 4426 }
4418 4427
@@ -4849,16 +4858,18 @@ static const struct {
4849 4858
4850static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) 4859static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
4851{ 4860{
4852 enum bnx2x_stats_state state = bp->stats_state; 4861 enum bnx2x_stats_state state;
4853 4862
4854 if (unlikely(bp->panic)) 4863 if (unlikely(bp->panic))
4855 return; 4864 return;
4856 4865
4857 bnx2x_stats_stm[state][event].action(bp); 4866 /* Protect a state change flow */
4867 spin_lock_bh(&bp->stats_lock);
4868 state = bp->stats_state;
4858 bp->stats_state = bnx2x_stats_stm[state][event].next_state; 4869 bp->stats_state = bnx2x_stats_stm[state][event].next_state;
4870 spin_unlock_bh(&bp->stats_lock);
4859 4871
4860 /* Make sure the state has been "changed" */ 4872 bnx2x_stats_stm[state][event].action(bp);
4861 smp_wmb();
4862 4873
4863 if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) 4874 if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
4864 DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", 4875 DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
@@ -9908,6 +9919,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
9908 9919
9909 mutex_init(&bp->port.phy_mutex); 9920 mutex_init(&bp->port.phy_mutex);
9910 mutex_init(&bp->fw_mb_mutex); 9921 mutex_init(&bp->fw_mb_mutex);
9922 spin_lock_init(&bp->stats_lock);
9911#ifdef BCM_CNIC 9923#ifdef BCM_CNIC
9912 mutex_init(&bp->cnic_mutex); 9924 mutex_init(&bp->cnic_mutex);
9913#endif 9925#endif
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index df483076eda..8d7dfd2f1e9 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -822,7 +822,7 @@ static int rlb_initialize(struct bonding *bond)
822 822
823 /*initialize packet type*/ 823 /*initialize packet type*/
824 pk_type->type = cpu_to_be16(ETH_P_ARP); 824 pk_type->type = cpu_to_be16(ETH_P_ARP);
825 pk_type->dev = NULL; 825 pk_type->dev = bond->dev;
826 pk_type->func = rlb_arp_recv; 826 pk_type->func = rlb_arp_recv;
827 827
828 /* register to receive ARPs */ 828 /* register to receive ARPs */
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 3881918f538..cea37e0837f 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1722,6 +1722,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
1722 u16 eeprom_apme_mask = IGB_EEPROM_APME; 1722 u16 eeprom_apme_mask = IGB_EEPROM_APME;
1723 u32 part_num; 1723 u32 part_num;
1724 1724
1725 /* Catch broken hardware that put the wrong VF device ID in
1726 * the PCIe SR-IOV capability.
1727 */
1728 if (pdev->is_virtfn) {
1729 WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
1730 pci_name(pdev), pdev->vendor, pdev->device);
1731 return -EINVAL;
1732 }
1733
1725 err = pci_enable_device_mem(pdev); 1734 err = pci_enable_device_mem(pdev);
1726 if (err) 1735 if (err)
1727 return err; 1736 return err;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7b5d9764f31..74d9b6df302 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6492,6 +6492,15 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
6492#endif 6492#endif
6493 u32 part_num, eec; 6493 u32 part_num, eec;
6494 6494
6495 /* Catch broken hardware that put the wrong VF device ID in
6496 * the PCIe SR-IOV capability.
6497 */
6498 if (pdev->is_virtfn) {
6499 WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
6500 pci_name(pdev), pdev->vendor, pdev->device);
6501 return -EINVAL;
6502 }
6503
6495 err = pci_enable_device_mem(pdev); 6504 err = pci_enable_device_mem(pdev);
6496 if (err) 6505 if (err)
6497 return err; 6506 return err;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 87e8d4cb405..f15fe2cf72a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -499,7 +499,7 @@ static const struct net_device_ops macvlan_netdev_ops = {
499 .ndo_validate_addr = eth_validate_addr, 499 .ndo_validate_addr = eth_validate_addr,
500}; 500};
501 501
502static void macvlan_setup(struct net_device *dev) 502void macvlan_common_setup(struct net_device *dev)
503{ 503{
504 ether_setup(dev); 504 ether_setup(dev);
505 505
@@ -508,6 +508,12 @@ static void macvlan_setup(struct net_device *dev)
508 dev->destructor = free_netdev; 508 dev->destructor = free_netdev;
509 dev->header_ops = &macvlan_hard_header_ops, 509 dev->header_ops = &macvlan_hard_header_ops,
510 dev->ethtool_ops = &macvlan_ethtool_ops; 510 dev->ethtool_ops = &macvlan_ethtool_ops;
511}
512EXPORT_SYMBOL_GPL(macvlan_common_setup);
513
514static void macvlan_setup(struct net_device *dev)
515{
516 macvlan_common_setup(dev);
511 dev->tx_queue_len = 0; 517 dev->tx_queue_len = 0;
512} 518}
513 519
@@ -705,7 +711,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
705 /* common fields */ 711 /* common fields */
706 ops->priv_size = sizeof(struct macvlan_dev); 712 ops->priv_size = sizeof(struct macvlan_dev);
707 ops->get_tx_queues = macvlan_get_tx_queues; 713 ops->get_tx_queues = macvlan_get_tx_queues;
708 ops->setup = macvlan_setup;
709 ops->validate = macvlan_validate; 714 ops->validate = macvlan_validate;
710 ops->maxtype = IFLA_MACVLAN_MAX; 715 ops->maxtype = IFLA_MACVLAN_MAX;
711 ops->policy = macvlan_policy; 716 ops->policy = macvlan_policy;
@@ -719,6 +724,7 @@ EXPORT_SYMBOL_GPL(macvlan_link_register);
719 724
720static struct rtnl_link_ops macvlan_link_ops = { 725static struct rtnl_link_ops macvlan_link_ops = {
721 .kind = "macvlan", 726 .kind = "macvlan",
727 .setup = macvlan_setup,
722 .newlink = macvlan_newlink, 728 .newlink = macvlan_newlink,
723 .dellink = macvlan_dellink, 729 .dellink = macvlan_dellink,
724}; 730};
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index a8a94e2f6dd..ff02b836c3c 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -180,11 +180,18 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb)
180{ 180{
181 struct macvtap_queue *q = macvtap_get_queue(dev, skb); 181 struct macvtap_queue *q = macvtap_get_queue(dev, skb);
182 if (!q) 182 if (!q)
183 return -ENOLINK; 183 goto drop;
184
185 if (skb_queue_len(&q->sk.sk_receive_queue) >= dev->tx_queue_len)
186 goto drop;
184 187
185 skb_queue_tail(&q->sk.sk_receive_queue, skb); 188 skb_queue_tail(&q->sk.sk_receive_queue, skb);
186 wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND); 189 wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND);
187 return 0; 190 return NET_RX_SUCCESS;
191
192drop:
193 kfree_skb(skb);
194 return NET_RX_DROP;
188} 195}
189 196
190/* 197/*
@@ -235,8 +242,15 @@ static void macvtap_dellink(struct net_device *dev,
235 macvlan_dellink(dev, head); 242 macvlan_dellink(dev, head);
236} 243}
237 244
245static void macvtap_setup(struct net_device *dev)
246{
247 macvlan_common_setup(dev);
248 dev->tx_queue_len = TUN_READQ_SIZE;
249}
250
238static struct rtnl_link_ops macvtap_link_ops __read_mostly = { 251static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
239 .kind = "macvtap", 252 .kind = "macvtap",
253 .setup = macvtap_setup,
240 .newlink = macvtap_newlink, 254 .newlink = macvtap_newlink,
241 .dellink = macvtap_dellink, 255 .dellink = macvtap_dellink,
242}; 256};
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 5e52c75892d..7f3a53dcc6e 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -65,7 +65,7 @@ static int debug_level = ERR_DBG;
65 65
66/* DEBUG message print. */ 66/* DEBUG message print. */
67#define DBG_PRINT(dbg_level, fmt, args...) do { \ 67#define DBG_PRINT(dbg_level, fmt, args...) do { \
68 if (dbg_level >= debug_level) \ 68 if (dbg_level <= debug_level) \
69 pr_info(fmt, ##args); \ 69 pr_info(fmt, ##args); \
70 } while (0) 70 } while (0)
71 71
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 6ad6fe70631..63042596f0c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -736,8 +736,18 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
736 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; 736 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
737 else if (sinfo->gso_type & SKB_GSO_UDP) 737 else if (sinfo->gso_type & SKB_GSO_UDP)
738 gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; 738 gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
739 else 739 else {
740 BUG(); 740 printk(KERN_ERR "tun: unexpected GSO type: "
741 "0x%x, gso_size %d, hdr_len %d\n",
742 sinfo->gso_type, gso.gso_size,
743 gso.hdr_len);
744 print_hex_dump(KERN_ERR, "tun: ",
745 DUMP_PREFIX_NONE,
746 16, 1, skb->head,
747 min((int)gso.hdr_len, 64), true);
748 WARN_ON_ONCE(1);
749 return -EINVAL;
750 }
741 if (sinfo->gso_type & SKB_GSO_TCP_ECN) 751 if (sinfo->gso_type & SKB_GSO_TCP_ECN)
742 gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; 752 gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN;
743 } else 753 } else
diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h
index 2d7c96d7e86..eb80243e22d 100644
--- a/drivers/net/wimax/i2400m/i2400m-usb.h
+++ b/drivers/net/wimax/i2400m/i2400m-usb.h
@@ -152,6 +152,7 @@ enum {
152 /* Device IDs */ 152 /* Device IDs */
153 USB_DEVICE_ID_I6050 = 0x0186, 153 USB_DEVICE_ID_I6050 = 0x0186,
154 USB_DEVICE_ID_I6050_2 = 0x0188, 154 USB_DEVICE_ID_I6050_2 = 0x0188,
155 USB_DEVICE_ID_I6250 = 0x0187,
155}; 156};
156 157
157 158
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 0d5081d77dc..d3365ac85dd 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -491,6 +491,7 @@ int i2400mu_probe(struct usb_interface *iface,
491 switch (id->idProduct) { 491 switch (id->idProduct) {
492 case USB_DEVICE_ID_I6050: 492 case USB_DEVICE_ID_I6050:
493 case USB_DEVICE_ID_I6050_2: 493 case USB_DEVICE_ID_I6050_2:
494 case USB_DEVICE_ID_I6250:
494 i2400mu->i6050 = 1; 495 i2400mu->i6050 = 1;
495 break; 496 break;
496 default: 497 default:
@@ -739,6 +740,7 @@ static
739struct usb_device_id i2400mu_id_table[] = { 740struct usb_device_id i2400mu_id_table[] = {
740 { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) }, 741 { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) },
741 { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) }, 742 { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) },
743 { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) },
742 { USB_DEVICE(0x8086, 0x0181) }, 744 { USB_DEVICE(0x8086, 0x0181) },
743 { USB_DEVICE(0x8086, 0x1403) }, 745 { USB_DEVICE(0x8086, 0x1403) },
744 { USB_DEVICE(0x8086, 0x1405) }, 746 { USB_DEVICE(0x8086, 0x1405) },
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ca6065b71b4..e3e52913d83 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -844,9 +844,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
844 int dma_type; 844 int dma_type;
845 845
846 if (edma) 846 if (edma)
847 dma_type = DMA_FROM_DEVICE;
848 else
849 dma_type = DMA_BIDIRECTIONAL; 847 dma_type = DMA_BIDIRECTIONAL;
848 else
849 dma_type = DMA_FROM_DEVICE;
850 850
851 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; 851 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
852 spin_lock_bh(&sc->rx.rxbuflock); 852 spin_lock_bh(&sc->rx.rxbuflock);
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index 9ea047aca79..1ffaeffeff7 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -67,6 +67,8 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
67 } 67 }
68} 68}
69 69
70extern void macvlan_common_setup(struct net_device *dev);
71
70extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev, 72extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
71 struct nlattr *tb[], struct nlattr *data[], 73 struct nlattr *tb[], struct nlattr *data[],
72 int (*receive)(struct sk_buff *skb), 74 int (*receive)(struct sk_buff *skb),
diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
index ceac661cdfd..cfe2943690f 100644
--- a/include/net/tc_act/tc_mirred.h
+++ b/include/net/tc_act/tc_mirred.h
@@ -9,6 +9,7 @@ struct tcf_mirred {
9 int tcfm_ifindex; 9 int tcfm_ifindex;
10 int tcfm_ok_push; 10 int tcfm_ok_push;
11 struct net_device *tcfm_dev; 11 struct net_device *tcfm_dev;
12 struct list_head tcfm_list;
12}; 13};
13#define to_mirred(pc) \ 14#define to_mirred(pc) \
14 container_of(pc, struct tcf_mirred, common) 15 container_of(pc, struct tcf_mirred, common)
diff --git a/net/core/dev.c b/net/core/dev.c
index 0ea10f849be..1f466e82ac3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1488,6 +1488,7 @@ static inline void net_timestamp_check(struct sk_buff *skb)
1488int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) 1488int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
1489{ 1489{
1490 skb_orphan(skb); 1490 skb_orphan(skb);
1491 nf_reset(skb);
1491 1492
1492 if (!(dev->flags & IFF_UP) || 1493 if (!(dev->flags & IFF_UP) ||
1493 (skb->len > (dev->mtu + dev->hard_header_len))) { 1494 (skb->len > (dev->mtu + dev->hard_header_len))) {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 34432b4e96b..ce88293a34e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -843,7 +843,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
843 skb->network_header += off; 843 skb->network_header += off;
844 if (skb_mac_header_was_set(skb)) 844 if (skb_mac_header_was_set(skb))
845 skb->mac_header += off; 845 skb->mac_header += off;
846 skb->csum_start += nhead; 846 /* Only adjust this if it actually is csum_start rather than csum */
847 if (skb->ip_summed == CHECKSUM_PARTIAL)
848 skb->csum_start += nhead;
847 skb->cloned = 0; 849 skb->cloned = 0;
848 skb->hdr_len = 0; 850 skb->hdr_len = 0;
849 skb->nohdr = 0; 851 skb->nohdr = 0;
@@ -930,7 +932,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
930 copy_skb_header(n, skb); 932 copy_skb_header(n, skb);
931 933
932 off = newheadroom - oldheadroom; 934 off = newheadroom - oldheadroom;
933 n->csum_start += off; 935 if (n->ip_summed == CHECKSUM_PARTIAL)
936 n->csum_start += off;
934#ifdef NET_SKBUFF_DATA_USES_OFFSET 937#ifdef NET_SKBUFF_DATA_USES_OFFSET
935 n->transport_header += off; 938 n->transport_header += off;
936 n->network_header += off; 939 n->network_header += off;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e1a698df570..784f34d11fd 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1760,7 +1760,10 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1760 1760
1761 idev = ipv6_find_idev(dev); 1761 idev = ipv6_find_idev(dev);
1762 if (!idev) 1762 if (!idev)
1763 return NULL; 1763 return ERR_PTR(-ENOBUFS);
1764
1765 if (idev->cnf.disable_ipv6)
1766 return ERR_PTR(-EACCES);
1764 1767
1765 /* Add default multicast route */ 1768 /* Add default multicast route */
1766 addrconf_add_mroute(dev); 1769 addrconf_add_mroute(dev);
@@ -2129,8 +2132,9 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
2129 if (!dev) 2132 if (!dev)
2130 return -ENODEV; 2133 return -ENODEV;
2131 2134
2132 if ((idev = addrconf_add_dev(dev)) == NULL) 2135 idev = addrconf_add_dev(dev);
2133 return -ENOBUFS; 2136 if (IS_ERR(idev))
2137 return PTR_ERR(idev);
2134 2138
2135 scope = ipv6_addr_scope(pfx); 2139 scope = ipv6_addr_scope(pfx);
2136 2140
@@ -2377,7 +2381,7 @@ static void addrconf_dev_config(struct net_device *dev)
2377 } 2381 }
2378 2382
2379 idev = addrconf_add_dev(dev); 2383 idev = addrconf_add_dev(dev);
2380 if (idev == NULL) 2384 if (IS_ERR(idev))
2381 return; 2385 return;
2382 2386
2383 memset(&addr, 0, sizeof(struct in6_addr)); 2387 memset(&addr, 0, sizeof(struct in6_addr));
@@ -2468,7 +2472,7 @@ static void addrconf_ip6_tnl_config(struct net_device *dev)
2468 ASSERT_RTNL(); 2472 ASSERT_RTNL();
2469 2473
2470 idev = addrconf_add_dev(dev); 2474 idev = addrconf_add_dev(dev);
2471 if (!idev) { 2475 if (IS_ERR(idev)) {
2472 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); 2476 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
2473 return; 2477 return;
2474 } 2478 }
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c7000a6ca37..67ee34f57df 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -632,7 +632,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
632 skb->dev = sta->sdata->dev; 632 skb->dev = sta->sdata->dev;
633 skb->protocol = eth_type_trans(skb, sta->sdata->dev); 633 skb->protocol = eth_type_trans(skb, sta->sdata->dev);
634 memset(skb->cb, 0, sizeof(skb->cb)); 634 memset(skb->cb, 0, sizeof(skb->cb));
635 netif_rx(skb); 635 netif_rx_ni(skb);
636} 636}
637 637
638static void sta_apply_parameters(struct ieee80211_local *local, 638static void sta_apply_parameters(struct ieee80211_local *local,
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index c0b6863e3b8..1980b71c283 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -33,6 +33,7 @@
33static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; 33static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1];
34static u32 mirred_idx_gen; 34static u32 mirred_idx_gen;
35static DEFINE_RWLOCK(mirred_lock); 35static DEFINE_RWLOCK(mirred_lock);
36static LIST_HEAD(mirred_list);
36 37
37static struct tcf_hashinfo mirred_hash_info = { 38static struct tcf_hashinfo mirred_hash_info = {
38 .htab = tcf_mirred_ht, 39 .htab = tcf_mirred_ht,
@@ -47,7 +48,9 @@ static inline int tcf_mirred_release(struct tcf_mirred *m, int bind)
47 m->tcf_bindcnt--; 48 m->tcf_bindcnt--;
48 m->tcf_refcnt--; 49 m->tcf_refcnt--;
49 if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) { 50 if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
50 dev_put(m->tcfm_dev); 51 list_del(&m->tcfm_list);
52 if (m->tcfm_dev)
53 dev_put(m->tcfm_dev);
51 tcf_hash_destroy(&m->common, &mirred_hash_info); 54 tcf_hash_destroy(&m->common, &mirred_hash_info);
52 return 1; 55 return 1;
53 } 56 }
@@ -134,8 +137,10 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
134 m->tcfm_ok_push = ok_push; 137 m->tcfm_ok_push = ok_push;
135 } 138 }
136 spin_unlock_bh(&m->tcf_lock); 139 spin_unlock_bh(&m->tcf_lock);
137 if (ret == ACT_P_CREATED) 140 if (ret == ACT_P_CREATED) {
141 list_add(&m->tcfm_list, &mirred_list);
138 tcf_hash_insert(pc, &mirred_hash_info); 142 tcf_hash_insert(pc, &mirred_hash_info);
143 }
139 144
140 return ret; 145 return ret;
141} 146}
@@ -162,9 +167,14 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
162 m->tcf_tm.lastuse = jiffies; 167 m->tcf_tm.lastuse = jiffies;
163 168
164 dev = m->tcfm_dev; 169 dev = m->tcfm_dev;
170 if (!dev) {
171 printk_once(KERN_NOTICE "tc mirred: target device is gone\n");
172 goto out;
173 }
174
165 if (!(dev->flags & IFF_UP)) { 175 if (!(dev->flags & IFF_UP)) {
166 if (net_ratelimit()) 176 if (net_ratelimit())
167 pr_notice("tc mirred to Houston: device %s is gone!\n", 177 pr_notice("tc mirred to Houston: device %s is down\n",
168 dev->name); 178 dev->name);
169 goto out; 179 goto out;
170 } 180 }
@@ -232,6 +242,28 @@ nla_put_failure:
232 return -1; 242 return -1;
233} 243}
234 244
245static int mirred_device_event(struct notifier_block *unused,
246 unsigned long event, void *ptr)
247{
248 struct net_device *dev = ptr;
249 struct tcf_mirred *m;
250
251 if (event == NETDEV_UNREGISTER)
252 list_for_each_entry(m, &mirred_list, tcfm_list) {
253 if (m->tcfm_dev == dev) {
254 dev_put(dev);
255 m->tcfm_dev = NULL;
256 }
257 }
258
259 return NOTIFY_DONE;
260}
261
262static struct notifier_block mirred_device_notifier = {
263 .notifier_call = mirred_device_event,
264};
265
266
235static struct tc_action_ops act_mirred_ops = { 267static struct tc_action_ops act_mirred_ops = {
236 .kind = "mirred", 268 .kind = "mirred",
237 .hinfo = &mirred_hash_info, 269 .hinfo = &mirred_hash_info,
@@ -252,12 +284,17 @@ MODULE_LICENSE("GPL");
252 284
253static int __init mirred_init_module(void) 285static int __init mirred_init_module(void)
254{ 286{
287 int err = register_netdevice_notifier(&mirred_device_notifier);
288 if (err)
289 return err;
290
255 pr_info("Mirror/redirect action on\n"); 291 pr_info("Mirror/redirect action on\n");
256 return tcf_register_action(&act_mirred_ops); 292 return tcf_register_action(&act_mirred_ops);
257} 293}
258 294
259static void __exit mirred_cleanup_module(void) 295static void __exit mirred_cleanup_module(void)
260{ 296{
297 unregister_netdevice_notifier(&mirred_device_notifier);
261 tcf_unregister_action(&act_mirred_ops); 298 tcf_unregister_action(&act_mirred_ops);
262} 299}
263 300