diff options
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 4 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 1 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 37 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 9 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 9 | ||||
-rw-r--r-- | drivers/net/macvlan.c | 10 | ||||
-rw-r--r-- | drivers/net/macvtap.c | 18 | ||||
-rw-r--r-- | drivers/net/s2io.h | 2 | ||||
-rw-r--r-- | drivers/net/tun.c | 14 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/i2400m-usb.h | 1 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/usb.c | 2 | ||||
-rw-r--r-- | include/linux/if_macvlan.h | 2 | ||||
-rw-r--r-- | include/net/tc_act/tc_mirred.h | 1 | ||||
-rw-r--r-- | net/core/dev.c | 1 | ||||
-rw-r--r-- | net/core/skbuff.c | 7 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 14 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 43 |
19 files changed, 147 insertions, 32 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 817b0887f8cd..53af9c93e75c 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -863,6 +863,10 @@ struct bnx2x { | |||
863 | 863 | ||
864 | /* used to synchronize stats collecting */ | 864 | /* used to synchronize stats collecting */ |
865 | int stats_state; | 865 | int stats_state; |
866 | |||
867 | /* used for synchronization of concurrent threads statistics handling */ | ||
868 | spinlock_t stats_lock; | ||
869 | |||
866 | /* used by dmae command loader */ | 870 | /* used by dmae command loader */ |
867 | struct dmae_command stats_dmae; | 871 | struct dmae_command stats_dmae; |
868 | int executer_idx; | 872 | int executer_idx; |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 75568f111754..b4ec2b02a465 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -6714,6 +6714,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
6714 | 6714 | ||
6715 | mutex_init(&bp->port.phy_mutex); | 6715 | mutex_init(&bp->port.phy_mutex); |
6716 | mutex_init(&bp->fw_mb_mutex); | 6716 | mutex_init(&bp->fw_mb_mutex); |
6717 | spin_lock_init(&bp->stats_lock); | ||
6717 | #ifdef BCM_CNIC | 6718 | #ifdef BCM_CNIC |
6718 | mutex_init(&bp->cnic_mutex); | 6719 | mutex_init(&bp->cnic_mutex); |
6719 | #endif | 6720 | #endif |
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 3f5127720423..c74724461020 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c | |||
@@ -156,6 +156,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) | |||
156 | struct eth_query_ramrod_data ramrod_data = {0}; | 156 | struct eth_query_ramrod_data ramrod_data = {0}; |
157 | int i, rc; | 157 | int i, rc; |
158 | 158 | ||
159 | spin_lock_bh(&bp->stats_lock); | ||
160 | |||
159 | ramrod_data.drv_counter = bp->stats_counter++; | 161 | ramrod_data.drv_counter = bp->stats_counter++; |
160 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; | 162 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; |
161 | for_each_queue(bp, i) | 163 | for_each_queue(bp, i) |
@@ -169,6 +171,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) | |||
169 | bp->spq_left++; | 171 | bp->spq_left++; |
170 | bp->stats_pending = 1; | 172 | bp->stats_pending = 1; |
171 | } | 173 | } |
174 | |||
175 | spin_unlock_bh(&bp->stats_lock); | ||
172 | } | 176 | } |
173 | } | 177 | } |
174 | 178 | ||
@@ -734,6 +738,14 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) | |||
734 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); | 738 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); |
735 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | 739 | struct bnx2x_eth_stats *estats = &bp->eth_stats; |
736 | int i; | 740 | int i; |
741 | u16 cur_stats_counter; | ||
742 | |||
743 | /* Make sure we use the value of the counter | ||
744 | * used for sending the last stats ramrod. | ||
745 | */ | ||
746 | spin_lock_bh(&bp->stats_lock); | ||
747 | cur_stats_counter = bp->stats_counter - 1; | ||
748 | spin_unlock_bh(&bp->stats_lock); | ||
737 | 749 | ||
738 | memcpy(&(fstats->total_bytes_received_hi), | 750 | memcpy(&(fstats->total_bytes_received_hi), |
739 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), | 751 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), |
@@ -761,25 +773,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) | |||
761 | u32 diff; | 773 | u32 diff; |
762 | 774 | ||
763 | /* are storm stats valid? */ | 775 | /* are storm stats valid? */ |
764 | if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != | 776 | if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) { |
765 | bp->stats_counter) { | ||
766 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" | 777 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" |
767 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", | 778 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", |
768 | i, xclient->stats_counter, bp->stats_counter); | 779 | i, xclient->stats_counter, cur_stats_counter + 1); |
769 | return -1; | 780 | return -1; |
770 | } | 781 | } |
771 | if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != | 782 | if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) { |
772 | bp->stats_counter) { | ||
773 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" | 783 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" |
774 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", | 784 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", |
775 | i, tclient->stats_counter, bp->stats_counter); | 785 | i, tclient->stats_counter, cur_stats_counter + 1); |
776 | return -2; | 786 | return -2; |
777 | } | 787 | } |
778 | if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != | 788 | if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) { |
779 | bp->stats_counter) { | ||
780 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" | 789 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" |
781 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", | 790 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", |
782 | i, uclient->stats_counter, bp->stats_counter); | 791 | i, uclient->stats_counter, cur_stats_counter + 1); |
783 | return -4; | 792 | return -4; |
784 | } | 793 | } |
785 | 794 | ||
@@ -1216,16 +1225,18 @@ static const struct { | |||
1216 | 1225 | ||
1217 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | 1226 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) |
1218 | { | 1227 | { |
1219 | enum bnx2x_stats_state state = bp->stats_state; | 1228 | enum bnx2x_stats_state state; |
1220 | 1229 | ||
1221 | if (unlikely(bp->panic)) | 1230 | if (unlikely(bp->panic)) |
1222 | return; | 1231 | return; |
1223 | 1232 | ||
1224 | bnx2x_stats_stm[state][event].action(bp); | 1233 | /* Protect a state change flow */ |
1234 | spin_lock_bh(&bp->stats_lock); | ||
1235 | state = bp->stats_state; | ||
1225 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | 1236 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; |
1237 | spin_unlock_bh(&bp->stats_lock); | ||
1226 | 1238 | ||
1227 | /* Make sure the state has been "changed" */ | 1239 | bnx2x_stats_stm[state][event].action(bp); |
1228 | smp_wmb(); | ||
1229 | 1240 | ||
1230 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | 1241 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) |
1231 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | 1242 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index e3b35d0b4284..c746b331771d 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -815,7 +815,7 @@ static int rlb_initialize(struct bonding *bond) | |||
815 | 815 | ||
816 | /*initialize packet type*/ | 816 | /*initialize packet type*/ |
817 | pk_type->type = cpu_to_be16(ETH_P_ARP); | 817 | pk_type->type = cpu_to_be16(ETH_P_ARP); |
818 | pk_type->dev = NULL; | 818 | pk_type->dev = bond->dev; |
819 | pk_type->func = rlb_arp_recv; | 819 | pk_type->func = rlb_arp_recv; |
820 | 820 | ||
821 | /* register to receive ARPs */ | 821 | /* register to receive ARPs */ |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 94656179441d..667b527b0312 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 e92acbf5a307..7d6a415bcf88 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -6539,6 +6539,15 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
6539 | #endif | 6539 | #endif |
6540 | u32 part_num, eec; | 6540 | u32 part_num, eec; |
6541 | 6541 | ||
6542 | /* Catch broken hardware that put the wrong VF device ID in | ||
6543 | * the PCIe SR-IOV capability. | ||
6544 | */ | ||
6545 | if (pdev->is_virtfn) { | ||
6546 | WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n", | ||
6547 | pci_name(pdev), pdev->vendor, pdev->device); | ||
6548 | return -EINVAL; | ||
6549 | } | ||
6550 | |||
6542 | err = pci_enable_device_mem(pdev); | 6551 | err = pci_enable_device_mem(pdev); |
6543 | if (err) | 6552 | if (err) |
6544 | return err; | 6553 | return err; |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1b28aaec0a5a..6e9da96a87b2 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -515,7 +515,7 @@ static const struct net_device_ops macvlan_netdev_ops = { | |||
515 | .ndo_validate_addr = eth_validate_addr, | 515 | .ndo_validate_addr = eth_validate_addr, |
516 | }; | 516 | }; |
517 | 517 | ||
518 | static void macvlan_setup(struct net_device *dev) | 518 | void macvlan_common_setup(struct net_device *dev) |
519 | { | 519 | { |
520 | ether_setup(dev); | 520 | ether_setup(dev); |
521 | 521 | ||
@@ -524,6 +524,12 @@ static void macvlan_setup(struct net_device *dev) | |||
524 | dev->destructor = free_netdev; | 524 | dev->destructor = free_netdev; |
525 | dev->header_ops = &macvlan_hard_header_ops, | 525 | dev->header_ops = &macvlan_hard_header_ops, |
526 | dev->ethtool_ops = &macvlan_ethtool_ops; | 526 | dev->ethtool_ops = &macvlan_ethtool_ops; |
527 | } | ||
528 | EXPORT_SYMBOL_GPL(macvlan_common_setup); | ||
529 | |||
530 | static void macvlan_setup(struct net_device *dev) | ||
531 | { | ||
532 | macvlan_common_setup(dev); | ||
527 | dev->tx_queue_len = 0; | 533 | dev->tx_queue_len = 0; |
528 | } | 534 | } |
529 | 535 | ||
@@ -735,7 +741,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops) | |||
735 | /* common fields */ | 741 | /* common fields */ |
736 | ops->priv_size = sizeof(struct macvlan_dev); | 742 | ops->priv_size = sizeof(struct macvlan_dev); |
737 | ops->get_tx_queues = macvlan_get_tx_queues; | 743 | ops->get_tx_queues = macvlan_get_tx_queues; |
738 | ops->setup = macvlan_setup; | ||
739 | ops->validate = macvlan_validate; | 744 | ops->validate = macvlan_validate; |
740 | ops->maxtype = IFLA_MACVLAN_MAX; | 745 | ops->maxtype = IFLA_MACVLAN_MAX; |
741 | ops->policy = macvlan_policy; | 746 | ops->policy = macvlan_policy; |
@@ -749,6 +754,7 @@ EXPORT_SYMBOL_GPL(macvlan_link_register); | |||
749 | 754 | ||
750 | static struct rtnl_link_ops macvlan_link_ops = { | 755 | static struct rtnl_link_ops macvlan_link_ops = { |
751 | .kind = "macvlan", | 756 | .kind = "macvlan", |
757 | .setup = macvlan_setup, | ||
752 | .newlink = macvlan_newlink, | 758 | .newlink = macvlan_newlink, |
753 | .dellink = macvlan_dellink, | 759 | .dellink = macvlan_dellink, |
754 | }; | 760 | }; |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2b4d59b58b2c..3b1c54a9c6ef 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 | |||
192 | drop: | ||
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 | ||
245 | static void macvtap_setup(struct net_device *dev) | ||
246 | { | ||
247 | macvlan_common_setup(dev); | ||
248 | dev->tx_queue_len = TUN_READQ_SIZE; | ||
249 | } | ||
250 | |||
238 | static struct rtnl_link_ops macvtap_link_ops __read_mostly = { | 251 | static 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 3645fb3673db..0af033533905 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 6ad6fe706312..63042596f0cf 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 2d7c96d7e865..eb80243e22df 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 0d5081d77dc0..d3365ac85dde 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 | |||
739 | struct usb_device_id i2400mu_id_table[] = { | 740 | struct 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/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index e24ce6ea1fa3..35280b302290 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h | |||
@@ -72,6 +72,8 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | extern void macvlan_common_setup(struct net_device *dev); | ||
76 | |||
75 | extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | 77 | extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev, |
76 | struct nlattr *tb[], struct nlattr *data[], | 78 | struct nlattr *tb[], struct nlattr *data[], |
77 | int (*receive)(struct sk_buff *skb), | 79 | 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 ceac661cdfd5..cfe2943690ff 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 6e1b4370781c..b74fcd3e9365 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1484,6 +1484,7 @@ static inline void net_timestamp_check(struct sk_buff *skb) | |||
1484 | int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | 1484 | int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) |
1485 | { | 1485 | { |
1486 | skb_orphan(skb); | 1486 | skb_orphan(skb); |
1487 | nf_reset(skb); | ||
1487 | 1488 | ||
1488 | if (!(dev->flags & IFF_UP) || | 1489 | if (!(dev->flags & IFF_UP) || |
1489 | (skb->len > (dev->mtu + dev->hard_header_len))) { | 1490 | (skb->len > (dev->mtu + dev->hard_header_len))) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7da58a25ad92..3a2513f0d0c3 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 e81155d2f251..ab70a3fbcafa 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1763,7 +1763,10 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | |||
1763 | 1763 | ||
1764 | idev = ipv6_find_idev(dev); | 1764 | idev = ipv6_find_idev(dev); |
1765 | if (!idev) | 1765 | if (!idev) |
1766 | return NULL; | 1766 | return ERR_PTR(-ENOBUFS); |
1767 | |||
1768 | if (idev->cnf.disable_ipv6) | ||
1769 | return ERR_PTR(-EACCES); | ||
1767 | 1770 | ||
1768 | /* Add default multicast route */ | 1771 | /* Add default multicast route */ |
1769 | addrconf_add_mroute(dev); | 1772 | addrconf_add_mroute(dev); |
@@ -2132,8 +2135,9 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2132 | if (!dev) | 2135 | if (!dev) |
2133 | return -ENODEV; | 2136 | return -ENODEV; |
2134 | 2137 | ||
2135 | if ((idev = addrconf_add_dev(dev)) == NULL) | 2138 | idev = addrconf_add_dev(dev); |
2136 | return -ENOBUFS; | 2139 | if (IS_ERR(idev)) |
2140 | return PTR_ERR(idev); | ||
2137 | 2141 | ||
2138 | scope = ipv6_addr_scope(pfx); | 2142 | scope = ipv6_addr_scope(pfx); |
2139 | 2143 | ||
@@ -2380,7 +2384,7 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2380 | } | 2384 | } |
2381 | 2385 | ||
2382 | idev = addrconf_add_dev(dev); | 2386 | idev = addrconf_add_dev(dev); |
2383 | if (idev == NULL) | 2387 | if (IS_ERR(idev)) |
2384 | return; | 2388 | return; |
2385 | 2389 | ||
2386 | memset(&addr, 0, sizeof(struct in6_addr)); | 2390 | memset(&addr, 0, sizeof(struct in6_addr)); |
@@ -2471,7 +2475,7 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) | |||
2471 | ASSERT_RTNL(); | 2475 | ASSERT_RTNL(); |
2472 | 2476 | ||
2473 | idev = addrconf_add_dev(dev); | 2477 | idev = addrconf_add_dev(dev); |
2474 | if (!idev) { | 2478 | if (IS_ERR(idev)) { |
2475 | printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); | 2479 | printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); |
2476 | return; | 2480 | return; |
2477 | } | 2481 | } |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a3f3325df9f2..db4d9340c846 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 | ||
638 | static void sta_apply_parameters(struct ieee80211_local *local, | 638 | static void sta_apply_parameters(struct ieee80211_local *local, |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index a16b0175f890..11f195af2da0 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -33,6 +33,7 @@ | |||
33 | static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; | 33 | static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; |
34 | static u32 mirred_idx_gen; | 34 | static u32 mirred_idx_gen; |
35 | static DEFINE_RWLOCK(mirred_lock); | 35 | static DEFINE_RWLOCK(mirred_lock); |
36 | static LIST_HEAD(mirred_list); | ||
36 | 37 | ||
37 | static struct tcf_hashinfo mirred_hash_info = { | 38 | static 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 | } |
@@ -164,9 +169,14 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, | |||
164 | m->tcf_bstats.packets++; | 169 | m->tcf_bstats.packets++; |
165 | 170 | ||
166 | dev = m->tcfm_dev; | 171 | dev = m->tcfm_dev; |
172 | if (!dev) { | ||
173 | printk_once(KERN_NOTICE "tc mirred: target device is gone\n"); | ||
174 | goto out; | ||
175 | } | ||
176 | |||
167 | if (!(dev->flags & IFF_UP)) { | 177 | if (!(dev->flags & IFF_UP)) { |
168 | if (net_ratelimit()) | 178 | if (net_ratelimit()) |
169 | pr_notice("tc mirred to Houston: device %s is gone!\n", | 179 | pr_notice("tc mirred to Houston: device %s is down\n", |
170 | dev->name); | 180 | dev->name); |
171 | goto out; | 181 | goto out; |
172 | } | 182 | } |
@@ -230,6 +240,28 @@ nla_put_failure: | |||
230 | return -1; | 240 | return -1; |
231 | } | 241 | } |
232 | 242 | ||
243 | static int mirred_device_event(struct notifier_block *unused, | ||
244 | unsigned long event, void *ptr) | ||
245 | { | ||
246 | struct net_device *dev = ptr; | ||
247 | struct tcf_mirred *m; | ||
248 | |||
249 | if (event == NETDEV_UNREGISTER) | ||
250 | list_for_each_entry(m, &mirred_list, tcfm_list) { | ||
251 | if (m->tcfm_dev == dev) { | ||
252 | dev_put(dev); | ||
253 | m->tcfm_dev = NULL; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | return NOTIFY_DONE; | ||
258 | } | ||
259 | |||
260 | static struct notifier_block mirred_device_notifier = { | ||
261 | .notifier_call = mirred_device_event, | ||
262 | }; | ||
263 | |||
264 | |||
233 | static struct tc_action_ops act_mirred_ops = { | 265 | static struct tc_action_ops act_mirred_ops = { |
234 | .kind = "mirred", | 266 | .kind = "mirred", |
235 | .hinfo = &mirred_hash_info, | 267 | .hinfo = &mirred_hash_info, |
@@ -250,12 +282,17 @@ MODULE_LICENSE("GPL"); | |||
250 | 282 | ||
251 | static int __init mirred_init_module(void) | 283 | static int __init mirred_init_module(void) |
252 | { | 284 | { |
285 | int err = register_netdevice_notifier(&mirred_device_notifier); | ||
286 | if (err) | ||
287 | return err; | ||
288 | |||
253 | pr_info("Mirror/redirect action on\n"); | 289 | pr_info("Mirror/redirect action on\n"); |
254 | return tcf_register_action(&act_mirred_ops); | 290 | return tcf_register_action(&act_mirred_ops); |
255 | } | 291 | } |
256 | 292 | ||
257 | static void __exit mirred_cleanup_module(void) | 293 | static void __exit mirred_cleanup_module(void) |
258 | { | 294 | { |
295 | unregister_netdevice_notifier(&mirred_device_notifier); | ||
259 | tcf_unregister_action(&act_mirred_ops); | 296 | tcf_unregister_action(&act_mirred_ops); |
260 | } | 297 | } |
261 | 298 | ||