diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
commit | 7a6362800cb7d1d618a697a650c7aaed3eb39320 (patch) | |
tree | 087f9bc6c13ef1fad4b392c5cf9325cd28fa8523 /net/core | |
parent | 6445ced8670f37cfc2c5e24a9de9b413dbfc788d (diff) | |
parent | ceda86a108671294052cbf51660097b6534672f5 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1480 commits)
bonding: enable netpoll without checking link status
xfrm: Refcount destination entry on xfrm_lookup
net: introduce rx_handler results and logic around that
bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag
bonding: wrap slave state work
net: get rid of multiple bond-related netdevice->priv_flags
bonding: register slave pointer for rx_handler
be2net: Bump up the version number
be2net: Copyright notice change. Update to Emulex instead of ServerEngines
e1000e: fix kconfig for crc32 dependency
netfilter ebtables: fix xt_AUDIT to work with ebtables
xen network backend driver
bonding: Improve syslog message at device creation time
bonding: Call netif_carrier_off after register_netdevice
bonding: Incorrect TX queue offset
net_sched: fix ip_tos2prio
xfrm: fix __xfrm_route_forward()
be2net: Fix UDP packet detected status in RX compl
Phonet: fix aligned-mode pipe socket buffer header reserve
netxen: support for GbE port settings
...
Fix up conflicts in drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
with the staging updates.
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 463 | ||||
-rw-r--r-- | net/core/dst.c | 43 | ||||
-rw-r--r-- | net/core/ethtool.c | 604 | ||||
-rw-r--r-- | net/core/fib_rules.c | 6 | ||||
-rw-r--r-- | net/core/filter.c | 6 | ||||
-rw-r--r-- | net/core/flow.c | 14 | ||||
-rw-r--r-- | net/core/neighbour.c | 13 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 17 | ||||
-rw-r--r-- | net/core/netpoll.c | 13 | ||||
-rw-r--r-- | net/core/pktgen.c | 233 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 86 | ||||
-rw-r--r-- | net/core/skbuff.c | 8 |
12 files changed, 1003 insertions, 503 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 6561021d22d1..0b88eba97dab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -132,6 +132,7 @@ | |||
132 | #include <trace/events/skb.h> | 132 | #include <trace/events/skb.h> |
133 | #include <linux/pci.h> | 133 | #include <linux/pci.h> |
134 | #include <linux/inetdevice.h> | 134 | #include <linux/inetdevice.h> |
135 | #include <linux/cpu_rmap.h> | ||
135 | 136 | ||
136 | #include "net-sysfs.h" | 137 | #include "net-sysfs.h" |
137 | 138 | ||
@@ -1297,7 +1298,7 @@ static int __dev_close(struct net_device *dev) | |||
1297 | return retval; | 1298 | return retval; |
1298 | } | 1299 | } |
1299 | 1300 | ||
1300 | int dev_close_many(struct list_head *head) | 1301 | static int dev_close_many(struct list_head *head) |
1301 | { | 1302 | { |
1302 | struct net_device *dev, *tmp; | 1303 | struct net_device *dev, *tmp; |
1303 | LIST_HEAD(tmp_list); | 1304 | LIST_HEAD(tmp_list); |
@@ -1605,6 +1606,48 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1605 | rcu_read_unlock(); | 1606 | rcu_read_unlock(); |
1606 | } | 1607 | } |
1607 | 1608 | ||
1609 | /* netif_setup_tc - Handle tc mappings on real_num_tx_queues change | ||
1610 | * @dev: Network device | ||
1611 | * @txq: number of queues available | ||
1612 | * | ||
1613 | * If real_num_tx_queues is changed the tc mappings may no longer be | ||
1614 | * valid. To resolve this verify the tc mapping remains valid and if | ||
1615 | * not NULL the mapping. With no priorities mapping to this | ||
1616 | * offset/count pair it will no longer be used. In the worst case TC0 | ||
1617 | * is invalid nothing can be done so disable priority mappings. If is | ||
1618 | * expected that drivers will fix this mapping if they can before | ||
1619 | * calling netif_set_real_num_tx_queues. | ||
1620 | */ | ||
1621 | static void netif_setup_tc(struct net_device *dev, unsigned int txq) | ||
1622 | { | ||
1623 | int i; | ||
1624 | struct netdev_tc_txq *tc = &dev->tc_to_txq[0]; | ||
1625 | |||
1626 | /* If TC0 is invalidated disable TC mapping */ | ||
1627 | if (tc->offset + tc->count > txq) { | ||
1628 | pr_warning("Number of in use tx queues changed " | ||
1629 | "invalidating tc mappings. Priority " | ||
1630 | "traffic classification disabled!\n"); | ||
1631 | dev->num_tc = 0; | ||
1632 | return; | ||
1633 | } | ||
1634 | |||
1635 | /* Invalidated prio to tc mappings set to TC0 */ | ||
1636 | for (i = 1; i < TC_BITMASK + 1; i++) { | ||
1637 | int q = netdev_get_prio_tc_map(dev, i); | ||
1638 | |||
1639 | tc = &dev->tc_to_txq[q]; | ||
1640 | if (tc->offset + tc->count > txq) { | ||
1641 | pr_warning("Number of in use tx queues " | ||
1642 | "changed. Priority %i to tc " | ||
1643 | "mapping %i is no longer valid " | ||
1644 | "setting map to 0\n", | ||
1645 | i, q); | ||
1646 | netdev_set_prio_tc_map(dev, i, 0); | ||
1647 | } | ||
1648 | } | ||
1649 | } | ||
1650 | |||
1608 | /* | 1651 | /* |
1609 | * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues | 1652 | * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues |
1610 | * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. | 1653 | * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. |
@@ -1616,7 +1659,8 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) | |||
1616 | if (txq < 1 || txq > dev->num_tx_queues) | 1659 | if (txq < 1 || txq > dev->num_tx_queues) |
1617 | return -EINVAL; | 1660 | return -EINVAL; |
1618 | 1661 | ||
1619 | if (dev->reg_state == NETREG_REGISTERED) { | 1662 | if (dev->reg_state == NETREG_REGISTERED || |
1663 | dev->reg_state == NETREG_UNREGISTERING) { | ||
1620 | ASSERT_RTNL(); | 1664 | ASSERT_RTNL(); |
1621 | 1665 | ||
1622 | rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, | 1666 | rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, |
@@ -1624,6 +1668,9 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) | |||
1624 | if (rc) | 1668 | if (rc) |
1625 | return rc; | 1669 | return rc; |
1626 | 1670 | ||
1671 | if (dev->num_tc) | ||
1672 | netif_setup_tc(dev, txq); | ||
1673 | |||
1627 | if (txq < dev->real_num_tx_queues) | 1674 | if (txq < dev->real_num_tx_queues) |
1628 | qdisc_reset_all_tx_gt(dev, txq); | 1675 | qdisc_reset_all_tx_gt(dev, txq); |
1629 | } | 1676 | } |
@@ -1823,7 +1870,7 @@ EXPORT_SYMBOL(skb_checksum_help); | |||
1823 | * It may return NULL if the skb requires no segmentation. This is | 1870 | * It may return NULL if the skb requires no segmentation. This is |
1824 | * only possible when GSO is used for verifying header integrity. | 1871 | * only possible when GSO is used for verifying header integrity. |
1825 | */ | 1872 | */ |
1826 | struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) | 1873 | struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features) |
1827 | { | 1874 | { |
1828 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | 1875 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); |
1829 | struct packet_type *ptype; | 1876 | struct packet_type *ptype; |
@@ -2011,7 +2058,7 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) | |||
2011 | protocol == htons(ETH_P_FCOE))); | 2058 | protocol == htons(ETH_P_FCOE))); |
2012 | } | 2059 | } |
2013 | 2060 | ||
2014 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) | 2061 | static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features) |
2015 | { | 2062 | { |
2016 | if (!can_checksum_protocol(features, protocol)) { | 2063 | if (!can_checksum_protocol(features, protocol)) { |
2017 | features &= ~NETIF_F_ALL_CSUM; | 2064 | features &= ~NETIF_F_ALL_CSUM; |
@@ -2023,10 +2070,10 @@ static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features | |||
2023 | return features; | 2070 | return features; |
2024 | } | 2071 | } |
2025 | 2072 | ||
2026 | int netif_skb_features(struct sk_buff *skb) | 2073 | u32 netif_skb_features(struct sk_buff *skb) |
2027 | { | 2074 | { |
2028 | __be16 protocol = skb->protocol; | 2075 | __be16 protocol = skb->protocol; |
2029 | int features = skb->dev->features; | 2076 | u32 features = skb->dev->features; |
2030 | 2077 | ||
2031 | if (protocol == htons(ETH_P_8021Q)) { | 2078 | if (protocol == htons(ETH_P_8021Q)) { |
2032 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2079 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
@@ -2071,7 +2118,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2071 | int rc = NETDEV_TX_OK; | 2118 | int rc = NETDEV_TX_OK; |
2072 | 2119 | ||
2073 | if (likely(!skb->next)) { | 2120 | if (likely(!skb->next)) { |
2074 | int features; | 2121 | u32 features; |
2075 | 2122 | ||
2076 | /* | 2123 | /* |
2077 | * If device doesnt need skb->dst, release it right now while | 2124 | * If device doesnt need skb->dst, release it right now while |
@@ -2173,6 +2220,8 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, | |||
2173 | unsigned int num_tx_queues) | 2220 | unsigned int num_tx_queues) |
2174 | { | 2221 | { |
2175 | u32 hash; | 2222 | u32 hash; |
2223 | u16 qoffset = 0; | ||
2224 | u16 qcount = num_tx_queues; | ||
2176 | 2225 | ||
2177 | if (skb_rx_queue_recorded(skb)) { | 2226 | if (skb_rx_queue_recorded(skb)) { |
2178 | hash = skb_get_rx_queue(skb); | 2227 | hash = skb_get_rx_queue(skb); |
@@ -2181,13 +2230,19 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, | |||
2181 | return hash; | 2230 | return hash; |
2182 | } | 2231 | } |
2183 | 2232 | ||
2233 | if (dev->num_tc) { | ||
2234 | u8 tc = netdev_get_prio_tc_map(dev, skb->priority); | ||
2235 | qoffset = dev->tc_to_txq[tc].offset; | ||
2236 | qcount = dev->tc_to_txq[tc].count; | ||
2237 | } | ||
2238 | |||
2184 | if (skb->sk && skb->sk->sk_hash) | 2239 | if (skb->sk && skb->sk->sk_hash) |
2185 | hash = skb->sk->sk_hash; | 2240 | hash = skb->sk->sk_hash; |
2186 | else | 2241 | else |
2187 | hash = (__force u16) skb->protocol ^ skb->rxhash; | 2242 | hash = (__force u16) skb->protocol ^ skb->rxhash; |
2188 | hash = jhash_1word(hash, hashrnd); | 2243 | hash = jhash_1word(hash, hashrnd); |
2189 | 2244 | ||
2190 | return (u16) (((u64) hash * num_tx_queues) >> 32); | 2245 | return (u16) (((u64) hash * qcount) >> 32) + qoffset; |
2191 | } | 2246 | } |
2192 | EXPORT_SYMBOL(__skb_tx_hash); | 2247 | EXPORT_SYMBOL(__skb_tx_hash); |
2193 | 2248 | ||
@@ -2284,15 +2339,18 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2284 | struct netdev_queue *txq) | 2339 | struct netdev_queue *txq) |
2285 | { | 2340 | { |
2286 | spinlock_t *root_lock = qdisc_lock(q); | 2341 | spinlock_t *root_lock = qdisc_lock(q); |
2287 | bool contended = qdisc_is_running(q); | 2342 | bool contended; |
2288 | int rc; | 2343 | int rc; |
2289 | 2344 | ||
2345 | qdisc_skb_cb(skb)->pkt_len = skb->len; | ||
2346 | qdisc_calculate_pkt_len(skb, q); | ||
2290 | /* | 2347 | /* |
2291 | * Heuristic to force contended enqueues to serialize on a | 2348 | * Heuristic to force contended enqueues to serialize on a |
2292 | * separate lock before trying to get qdisc main lock. | 2349 | * separate lock before trying to get qdisc main lock. |
2293 | * This permits __QDISC_STATE_RUNNING owner to get the lock more often | 2350 | * This permits __QDISC_STATE_RUNNING owner to get the lock more often |
2294 | * and dequeue packets faster. | 2351 | * and dequeue packets faster. |
2295 | */ | 2352 | */ |
2353 | contended = qdisc_is_running(q); | ||
2296 | if (unlikely(contended)) | 2354 | if (unlikely(contended)) |
2297 | spin_lock(&q->busylock); | 2355 | spin_lock(&q->busylock); |
2298 | 2356 | ||
@@ -2310,7 +2368,6 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2310 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) | 2368 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) |
2311 | skb_dst_force(skb); | 2369 | skb_dst_force(skb); |
2312 | 2370 | ||
2313 | qdisc_skb_cb(skb)->pkt_len = skb->len; | ||
2314 | qdisc_bstats_update(q, skb); | 2371 | qdisc_bstats_update(q, skb); |
2315 | 2372 | ||
2316 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) { | 2373 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) { |
@@ -2325,7 +2382,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2325 | rc = NET_XMIT_SUCCESS; | 2382 | rc = NET_XMIT_SUCCESS; |
2326 | } else { | 2383 | } else { |
2327 | skb_dst_force(skb); | 2384 | skb_dst_force(skb); |
2328 | rc = qdisc_enqueue_root(skb, q); | 2385 | rc = q->enqueue(skb, q) & NET_XMIT_MASK; |
2329 | if (qdisc_run_begin(q)) { | 2386 | if (qdisc_run_begin(q)) { |
2330 | if (unlikely(contended)) { | 2387 | if (unlikely(contended)) { |
2331 | spin_unlock(&q->busylock); | 2388 | spin_unlock(&q->busylock); |
@@ -2544,6 +2601,54 @@ EXPORT_SYMBOL(__skb_get_rxhash); | |||
2544 | struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly; | 2601 | struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly; |
2545 | EXPORT_SYMBOL(rps_sock_flow_table); | 2602 | EXPORT_SYMBOL(rps_sock_flow_table); |
2546 | 2603 | ||
2604 | static struct rps_dev_flow * | ||
2605 | set_rps_cpu(struct net_device *dev, struct sk_buff *skb, | ||
2606 | struct rps_dev_flow *rflow, u16 next_cpu) | ||
2607 | { | ||
2608 | u16 tcpu; | ||
2609 | |||
2610 | tcpu = rflow->cpu = next_cpu; | ||
2611 | if (tcpu != RPS_NO_CPU) { | ||
2612 | #ifdef CONFIG_RFS_ACCEL | ||
2613 | struct netdev_rx_queue *rxqueue; | ||
2614 | struct rps_dev_flow_table *flow_table; | ||
2615 | struct rps_dev_flow *old_rflow; | ||
2616 | u32 flow_id; | ||
2617 | u16 rxq_index; | ||
2618 | int rc; | ||
2619 | |||
2620 | /* Should we steer this flow to a different hardware queue? */ | ||
2621 | if (!skb_rx_queue_recorded(skb) || !dev->rx_cpu_rmap || | ||
2622 | !(dev->features & NETIF_F_NTUPLE)) | ||
2623 | goto out; | ||
2624 | rxq_index = cpu_rmap_lookup_index(dev->rx_cpu_rmap, next_cpu); | ||
2625 | if (rxq_index == skb_get_rx_queue(skb)) | ||
2626 | goto out; | ||
2627 | |||
2628 | rxqueue = dev->_rx + rxq_index; | ||
2629 | flow_table = rcu_dereference(rxqueue->rps_flow_table); | ||
2630 | if (!flow_table) | ||
2631 | goto out; | ||
2632 | flow_id = skb->rxhash & flow_table->mask; | ||
2633 | rc = dev->netdev_ops->ndo_rx_flow_steer(dev, skb, | ||
2634 | rxq_index, flow_id); | ||
2635 | if (rc < 0) | ||
2636 | goto out; | ||
2637 | old_rflow = rflow; | ||
2638 | rflow = &flow_table->flows[flow_id]; | ||
2639 | rflow->cpu = next_cpu; | ||
2640 | rflow->filter = rc; | ||
2641 | if (old_rflow->filter == rflow->filter) | ||
2642 | old_rflow->filter = RPS_NO_FILTER; | ||
2643 | out: | ||
2644 | #endif | ||
2645 | rflow->last_qtail = | ||
2646 | per_cpu(softnet_data, tcpu).input_queue_head; | ||
2647 | } | ||
2648 | |||
2649 | return rflow; | ||
2650 | } | ||
2651 | |||
2547 | /* | 2652 | /* |
2548 | * get_rps_cpu is called from netif_receive_skb and returns the target | 2653 | * get_rps_cpu is called from netif_receive_skb and returns the target |
2549 | * CPU from the RPS map of the receiving queue for a given skb. | 2654 | * CPU from the RPS map of the receiving queue for a given skb. |
@@ -2615,12 +2720,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2615 | if (unlikely(tcpu != next_cpu) && | 2720 | if (unlikely(tcpu != next_cpu) && |
2616 | (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || | 2721 | (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || |
2617 | ((int)(per_cpu(softnet_data, tcpu).input_queue_head - | 2722 | ((int)(per_cpu(softnet_data, tcpu).input_queue_head - |
2618 | rflow->last_qtail)) >= 0)) { | 2723 | rflow->last_qtail)) >= 0)) |
2619 | tcpu = rflow->cpu = next_cpu; | 2724 | rflow = set_rps_cpu(dev, skb, rflow, next_cpu); |
2620 | if (tcpu != RPS_NO_CPU) | 2725 | |
2621 | rflow->last_qtail = per_cpu(softnet_data, | ||
2622 | tcpu).input_queue_head; | ||
2623 | } | ||
2624 | if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { | 2726 | if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { |
2625 | *rflowp = rflow; | 2727 | *rflowp = rflow; |
2626 | cpu = tcpu; | 2728 | cpu = tcpu; |
@@ -2641,6 +2743,46 @@ done: | |||
2641 | return cpu; | 2743 | return cpu; |
2642 | } | 2744 | } |
2643 | 2745 | ||
2746 | #ifdef CONFIG_RFS_ACCEL | ||
2747 | |||
2748 | /** | ||
2749 | * rps_may_expire_flow - check whether an RFS hardware filter may be removed | ||
2750 | * @dev: Device on which the filter was set | ||
2751 | * @rxq_index: RX queue index | ||
2752 | * @flow_id: Flow ID passed to ndo_rx_flow_steer() | ||
2753 | * @filter_id: Filter ID returned by ndo_rx_flow_steer() | ||
2754 | * | ||
2755 | * Drivers that implement ndo_rx_flow_steer() should periodically call | ||
2756 | * this function for each installed filter and remove the filters for | ||
2757 | * which it returns %true. | ||
2758 | */ | ||
2759 | bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index, | ||
2760 | u32 flow_id, u16 filter_id) | ||
2761 | { | ||
2762 | struct netdev_rx_queue *rxqueue = dev->_rx + rxq_index; | ||
2763 | struct rps_dev_flow_table *flow_table; | ||
2764 | struct rps_dev_flow *rflow; | ||
2765 | bool expire = true; | ||
2766 | int cpu; | ||
2767 | |||
2768 | rcu_read_lock(); | ||
2769 | flow_table = rcu_dereference(rxqueue->rps_flow_table); | ||
2770 | if (flow_table && flow_id <= flow_table->mask) { | ||
2771 | rflow = &flow_table->flows[flow_id]; | ||
2772 | cpu = ACCESS_ONCE(rflow->cpu); | ||
2773 | if (rflow->filter == filter_id && cpu != RPS_NO_CPU && | ||
2774 | ((int)(per_cpu(softnet_data, cpu).input_queue_head - | ||
2775 | rflow->last_qtail) < | ||
2776 | (int)(10 * flow_table->mask))) | ||
2777 | expire = false; | ||
2778 | } | ||
2779 | rcu_read_unlock(); | ||
2780 | return expire; | ||
2781 | } | ||
2782 | EXPORT_SYMBOL(rps_may_expire_flow); | ||
2783 | |||
2784 | #endif /* CONFIG_RFS_ACCEL */ | ||
2785 | |||
2644 | /* Called from hardirq (IPI) context */ | 2786 | /* Called from hardirq (IPI) context */ |
2645 | static void rps_trigger_softirq(void *data) | 2787 | static void rps_trigger_softirq(void *data) |
2646 | { | 2788 | { |
@@ -2928,6 +3070,8 @@ out: | |||
2928 | * on a failure. | 3070 | * on a failure. |
2929 | * | 3071 | * |
2930 | * The caller must hold the rtnl_mutex. | 3072 | * The caller must hold the rtnl_mutex. |
3073 | * | ||
3074 | * For a general description of rx_handler, see enum rx_handler_result. | ||
2931 | */ | 3075 | */ |
2932 | int netdev_rx_handler_register(struct net_device *dev, | 3076 | int netdev_rx_handler_register(struct net_device *dev, |
2933 | rx_handler_func_t *rx_handler, | 3077 | rx_handler_func_t *rx_handler, |
@@ -2962,64 +3106,32 @@ void netdev_rx_handler_unregister(struct net_device *dev) | |||
2962 | } | 3106 | } |
2963 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); | 3107 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); |
2964 | 3108 | ||
2965 | static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, | 3109 | static void vlan_on_bond_hook(struct sk_buff *skb) |
2966 | struct net_device *master) | ||
2967 | { | 3110 | { |
2968 | if (skb->pkt_type == PACKET_HOST) { | 3111 | /* |
2969 | u16 *dest = (u16 *) eth_hdr(skb)->h_dest; | 3112 | * Make sure ARP frames received on VLAN interfaces stacked on |
2970 | 3113 | * bonding interfaces still make their way to any base bonding | |
2971 | memcpy(dest, master->dev_addr, ETH_ALEN); | 3114 | * device that may have registered for a specific ptype. |
2972 | } | 3115 | */ |
2973 | } | 3116 | if (skb->dev->priv_flags & IFF_802_1Q_VLAN && |
2974 | 3117 | vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING && | |
2975 | /* On bonding slaves other than the currently active slave, suppress | 3118 | skb->protocol == htons(ETH_P_ARP)) { |
2976 | * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and | 3119 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
2977 | * ARP on active-backup slaves with arp_validate enabled. | ||
2978 | */ | ||
2979 | int __skb_bond_should_drop(struct sk_buff *skb, struct net_device *master) | ||
2980 | { | ||
2981 | struct net_device *dev = skb->dev; | ||
2982 | |||
2983 | if (master->priv_flags & IFF_MASTER_ARPMON) | ||
2984 | dev->last_rx = jiffies; | ||
2985 | |||
2986 | if ((master->priv_flags & IFF_MASTER_ALB) && | ||
2987 | (master->priv_flags & IFF_BRIDGE_PORT)) { | ||
2988 | /* Do address unmangle. The local destination address | ||
2989 | * will be always the one master has. Provides the right | ||
2990 | * functionality in a bridge. | ||
2991 | */ | ||
2992 | skb_bond_set_mac_by_master(skb, master); | ||
2993 | } | ||
2994 | |||
2995 | if (dev->priv_flags & IFF_SLAVE_INACTIVE) { | ||
2996 | if ((dev->priv_flags & IFF_SLAVE_NEEDARP) && | ||
2997 | skb->protocol == __cpu_to_be16(ETH_P_ARP)) | ||
2998 | return 0; | ||
2999 | |||
3000 | if (master->priv_flags & IFF_MASTER_ALB) { | ||
3001 | if (skb->pkt_type != PACKET_BROADCAST && | ||
3002 | skb->pkt_type != PACKET_MULTICAST) | ||
3003 | return 0; | ||
3004 | } | ||
3005 | if (master->priv_flags & IFF_MASTER_8023AD && | ||
3006 | skb->protocol == __cpu_to_be16(ETH_P_SLOW)) | ||
3007 | return 0; | ||
3008 | 3120 | ||
3009 | return 1; | 3121 | if (!skb2) |
3122 | return; | ||
3123 | skb2->dev = vlan_dev_real_dev(skb->dev); | ||
3124 | netif_rx(skb2); | ||
3010 | } | 3125 | } |
3011 | return 0; | ||
3012 | } | 3126 | } |
3013 | EXPORT_SYMBOL(__skb_bond_should_drop); | ||
3014 | 3127 | ||
3015 | static int __netif_receive_skb(struct sk_buff *skb) | 3128 | static int __netif_receive_skb(struct sk_buff *skb) |
3016 | { | 3129 | { |
3017 | struct packet_type *ptype, *pt_prev; | 3130 | struct packet_type *ptype, *pt_prev; |
3018 | rx_handler_func_t *rx_handler; | 3131 | rx_handler_func_t *rx_handler; |
3019 | struct net_device *orig_dev; | 3132 | struct net_device *orig_dev; |
3020 | struct net_device *master; | 3133 | struct net_device *null_or_dev; |
3021 | struct net_device *null_or_orig; | 3134 | bool deliver_exact = false; |
3022 | struct net_device *orig_or_bond; | ||
3023 | int ret = NET_RX_DROP; | 3135 | int ret = NET_RX_DROP; |
3024 | __be16 type; | 3136 | __be16 type; |
3025 | 3137 | ||
@@ -3034,28 +3146,8 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3034 | 3146 | ||
3035 | if (!skb->skb_iif) | 3147 | if (!skb->skb_iif) |
3036 | skb->skb_iif = skb->dev->ifindex; | 3148 | skb->skb_iif = skb->dev->ifindex; |
3037 | |||
3038 | /* | ||
3039 | * bonding note: skbs received on inactive slaves should only | ||
3040 | * be delivered to pkt handlers that are exact matches. Also | ||
3041 | * the deliver_no_wcard flag will be set. If packet handlers | ||
3042 | * are sensitive to duplicate packets these skbs will need to | ||
3043 | * be dropped at the handler. | ||
3044 | */ | ||
3045 | null_or_orig = NULL; | ||
3046 | orig_dev = skb->dev; | 3149 | orig_dev = skb->dev; |
3047 | master = ACCESS_ONCE(orig_dev->master); | ||
3048 | if (skb->deliver_no_wcard) | ||
3049 | null_or_orig = orig_dev; | ||
3050 | else if (master) { | ||
3051 | if (skb_bond_should_drop(skb, master)) { | ||
3052 | skb->deliver_no_wcard = 1; | ||
3053 | null_or_orig = orig_dev; /* deliver only exact match */ | ||
3054 | } else | ||
3055 | skb->dev = master; | ||
3056 | } | ||
3057 | 3150 | ||
3058 | __this_cpu_inc(softnet_data.processed); | ||
3059 | skb_reset_network_header(skb); | 3151 | skb_reset_network_header(skb); |
3060 | skb_reset_transport_header(skb); | 3152 | skb_reset_transport_header(skb); |
3061 | skb->mac_len = skb->network_header - skb->mac_header; | 3153 | skb->mac_len = skb->network_header - skb->mac_header; |
@@ -3064,6 +3156,10 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3064 | 3156 | ||
3065 | rcu_read_lock(); | 3157 | rcu_read_lock(); |
3066 | 3158 | ||
3159 | another_round: | ||
3160 | |||
3161 | __this_cpu_inc(softnet_data.processed); | ||
3162 | |||
3067 | #ifdef CONFIG_NET_CLS_ACT | 3163 | #ifdef CONFIG_NET_CLS_ACT |
3068 | if (skb->tc_verd & TC_NCLS) { | 3164 | if (skb->tc_verd & TC_NCLS) { |
3069 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); | 3165 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); |
@@ -3072,8 +3168,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3072 | #endif | 3168 | #endif |
3073 | 3169 | ||
3074 | list_for_each_entry_rcu(ptype, &ptype_all, list) { | 3170 | list_for_each_entry_rcu(ptype, &ptype_all, list) { |
3075 | if (ptype->dev == null_or_orig || ptype->dev == skb->dev || | 3171 | if (!ptype->dev || ptype->dev == skb->dev) { |
3076 | ptype->dev == orig_dev) { | ||
3077 | if (pt_prev) | 3172 | if (pt_prev) |
3078 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3173 | ret = deliver_skb(skb, pt_prev, orig_dev); |
3079 | pt_prev = ptype; | 3174 | pt_prev = ptype; |
@@ -3087,16 +3182,24 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3087 | ncls: | 3182 | ncls: |
3088 | #endif | 3183 | #endif |
3089 | 3184 | ||
3090 | /* Handle special case of bridge or macvlan */ | ||
3091 | rx_handler = rcu_dereference(skb->dev->rx_handler); | 3185 | rx_handler = rcu_dereference(skb->dev->rx_handler); |
3092 | if (rx_handler) { | 3186 | if (rx_handler) { |
3093 | if (pt_prev) { | 3187 | if (pt_prev) { |
3094 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3188 | ret = deliver_skb(skb, pt_prev, orig_dev); |
3095 | pt_prev = NULL; | 3189 | pt_prev = NULL; |
3096 | } | 3190 | } |
3097 | skb = rx_handler(skb); | 3191 | switch (rx_handler(&skb)) { |
3098 | if (!skb) | 3192 | case RX_HANDLER_CONSUMED: |
3099 | goto out; | 3193 | goto out; |
3194 | case RX_HANDLER_ANOTHER: | ||
3195 | goto another_round; | ||
3196 | case RX_HANDLER_EXACT: | ||
3197 | deliver_exact = true; | ||
3198 | case RX_HANDLER_PASS: | ||
3199 | break; | ||
3200 | default: | ||
3201 | BUG(); | ||
3202 | } | ||
3100 | } | 3203 | } |
3101 | 3204 | ||
3102 | if (vlan_tx_tag_present(skb)) { | 3205 | if (vlan_tx_tag_present(skb)) { |
@@ -3111,24 +3214,17 @@ ncls: | |||
3111 | goto out; | 3214 | goto out; |
3112 | } | 3215 | } |
3113 | 3216 | ||
3114 | /* | 3217 | vlan_on_bond_hook(skb); |
3115 | * Make sure frames received on VLAN interfaces stacked on | 3218 | |
3116 | * bonding interfaces still make their way to any base bonding | 3219 | /* deliver only exact match when indicated */ |
3117 | * device that may have registered for a specific ptype. The | 3220 | null_or_dev = deliver_exact ? skb->dev : NULL; |
3118 | * handler may have to adjust skb->dev and orig_dev. | ||
3119 | */ | ||
3120 | orig_or_bond = orig_dev; | ||
3121 | if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) && | ||
3122 | (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) { | ||
3123 | orig_or_bond = vlan_dev_real_dev(skb->dev); | ||
3124 | } | ||
3125 | 3221 | ||
3126 | type = skb->protocol; | 3222 | type = skb->protocol; |
3127 | list_for_each_entry_rcu(ptype, | 3223 | list_for_each_entry_rcu(ptype, |
3128 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 3224 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { |
3129 | if (ptype->type == type && (ptype->dev == null_or_orig || | 3225 | if (ptype->type == type && |
3130 | ptype->dev == skb->dev || ptype->dev == orig_dev || | 3226 | (ptype->dev == null_or_dev || ptype->dev == skb->dev || |
3131 | ptype->dev == orig_or_bond)) { | 3227 | ptype->dev == orig_dev)) { |
3132 | if (pt_prev) | 3228 | if (pt_prev) |
3133 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3229 | ret = deliver_skb(skb, pt_prev, orig_dev); |
3134 | pt_prev = ptype; | 3230 | pt_prev = ptype; |
@@ -3925,12 +4021,15 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) | |||
3925 | 4021 | ||
3926 | void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 4022 | void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
3927 | { | 4023 | { |
3928 | struct net_device *dev = (v == SEQ_START_TOKEN) ? | 4024 | struct net_device *dev = v; |
3929 | first_net_device(seq_file_net(seq)) : | 4025 | |
3930 | next_net_device((struct net_device *)v); | 4026 | if (v == SEQ_START_TOKEN) |
4027 | dev = first_net_device_rcu(seq_file_net(seq)); | ||
4028 | else | ||
4029 | dev = next_net_device_rcu(dev); | ||
3931 | 4030 | ||
3932 | ++*pos; | 4031 | ++*pos; |
3933 | return rcu_dereference(dev); | 4032 | return dev; |
3934 | } | 4033 | } |
3935 | 4034 | ||
3936 | void dev_seq_stop(struct seq_file *seq, void *v) | 4035 | void dev_seq_stop(struct seq_file *seq, void *v) |
@@ -4214,15 +4313,14 @@ static int __init dev_proc_init(void) | |||
4214 | 4313 | ||
4215 | 4314 | ||
4216 | /** | 4315 | /** |
4217 | * netdev_set_master - set up master/slave pair | 4316 | * netdev_set_master - set up master pointer |
4218 | * @slave: slave device | 4317 | * @slave: slave device |
4219 | * @master: new master device | 4318 | * @master: new master device |
4220 | * | 4319 | * |
4221 | * Changes the master device of the slave. Pass %NULL to break the | 4320 | * Changes the master device of the slave. Pass %NULL to break the |
4222 | * bonding. The caller must hold the RTNL semaphore. On a failure | 4321 | * bonding. The caller must hold the RTNL semaphore. On a failure |
4223 | * a negative errno code is returned. On success the reference counts | 4322 | * a negative errno code is returned. On success the reference counts |
4224 | * are adjusted, %RTM_NEWLINK is sent to the routing socket and the | 4323 | * are adjusted and the function returns zero. |
4225 | * function returns zero. | ||
4226 | */ | 4324 | */ |
4227 | int netdev_set_master(struct net_device *slave, struct net_device *master) | 4325 | int netdev_set_master(struct net_device *slave, struct net_device *master) |
4228 | { | 4326 | { |
@@ -4242,6 +4340,29 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) | |||
4242 | synchronize_net(); | 4340 | synchronize_net(); |
4243 | dev_put(old); | 4341 | dev_put(old); |
4244 | } | 4342 | } |
4343 | return 0; | ||
4344 | } | ||
4345 | EXPORT_SYMBOL(netdev_set_master); | ||
4346 | |||
4347 | /** | ||
4348 | * netdev_set_bond_master - set up bonding master/slave pair | ||
4349 | * @slave: slave device | ||
4350 | * @master: new master device | ||
4351 | * | ||
4352 | * Changes the master device of the slave. Pass %NULL to break the | ||
4353 | * bonding. The caller must hold the RTNL semaphore. On a failure | ||
4354 | * a negative errno code is returned. On success %RTM_NEWLINK is sent | ||
4355 | * to the routing socket and the function returns zero. | ||
4356 | */ | ||
4357 | int netdev_set_bond_master(struct net_device *slave, struct net_device *master) | ||
4358 | { | ||
4359 | int err; | ||
4360 | |||
4361 | ASSERT_RTNL(); | ||
4362 | |||
4363 | err = netdev_set_master(slave, master); | ||
4364 | if (err) | ||
4365 | return err; | ||
4245 | if (master) | 4366 | if (master) |
4246 | slave->flags |= IFF_SLAVE; | 4367 | slave->flags |= IFF_SLAVE; |
4247 | else | 4368 | else |
@@ -4250,7 +4371,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) | |||
4250 | rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE); | 4371 | rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE); |
4251 | return 0; | 4372 | return 0; |
4252 | } | 4373 | } |
4253 | EXPORT_SYMBOL(netdev_set_master); | 4374 | EXPORT_SYMBOL(netdev_set_bond_master); |
4254 | 4375 | ||
4255 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 4376 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
4256 | { | 4377 | { |
@@ -4587,6 +4708,17 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
4587 | EXPORT_SYMBOL(dev_set_mtu); | 4708 | EXPORT_SYMBOL(dev_set_mtu); |
4588 | 4709 | ||
4589 | /** | 4710 | /** |
4711 | * dev_set_group - Change group this device belongs to | ||
4712 | * @dev: device | ||
4713 | * @new_group: group this device should belong to | ||
4714 | */ | ||
4715 | void dev_set_group(struct net_device *dev, int new_group) | ||
4716 | { | ||
4717 | dev->group = new_group; | ||
4718 | } | ||
4719 | EXPORT_SYMBOL(dev_set_group); | ||
4720 | |||
4721 | /** | ||
4590 | * dev_set_mac_address - Change Media Access Control Address | 4722 | * dev_set_mac_address - Change Media Access Control Address |
4591 | * @dev: device | 4723 | * @dev: device |
4592 | * @sa: new address | 4724 | * @sa: new address |
@@ -5077,41 +5209,55 @@ static void rollback_registered(struct net_device *dev) | |||
5077 | list_del(&single); | 5209 | list_del(&single); |
5078 | } | 5210 | } |
5079 | 5211 | ||
5080 | unsigned long netdev_fix_features(unsigned long features, const char *name) | 5212 | u32 netdev_fix_features(struct net_device *dev, u32 features) |
5081 | { | 5213 | { |
5214 | /* Fix illegal checksum combinations */ | ||
5215 | if ((features & NETIF_F_HW_CSUM) && | ||
5216 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||
5217 | netdev_info(dev, "mixed HW and IP checksum settings.\n"); | ||
5218 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | ||
5219 | } | ||
5220 | |||
5221 | if ((features & NETIF_F_NO_CSUM) && | ||
5222 | (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||
5223 | netdev_info(dev, "mixed no checksumming and other settings.\n"); | ||
5224 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | ||
5225 | } | ||
5226 | |||
5082 | /* Fix illegal SG+CSUM combinations. */ | 5227 | /* Fix illegal SG+CSUM combinations. */ |
5083 | if ((features & NETIF_F_SG) && | 5228 | if ((features & NETIF_F_SG) && |
5084 | !(features & NETIF_F_ALL_CSUM)) { | 5229 | !(features & NETIF_F_ALL_CSUM)) { |
5085 | if (name) | 5230 | netdev_info(dev, |
5086 | printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no " | 5231 | "Dropping NETIF_F_SG since no checksum feature.\n"); |
5087 | "checksum feature.\n", name); | ||
5088 | features &= ~NETIF_F_SG; | 5232 | features &= ~NETIF_F_SG; |
5089 | } | 5233 | } |
5090 | 5234 | ||
5091 | /* TSO requires that SG is present as well. */ | 5235 | /* TSO requires that SG is present as well. */ |
5092 | if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { | 5236 | if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { |
5093 | if (name) | 5237 | netdev_info(dev, "Dropping NETIF_F_TSO since no SG feature.\n"); |
5094 | printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no " | ||
5095 | "SG feature.\n", name); | ||
5096 | features &= ~NETIF_F_TSO; | 5238 | features &= ~NETIF_F_TSO; |
5097 | } | 5239 | } |
5098 | 5240 | ||
5241 | /* Software GSO depends on SG. */ | ||
5242 | if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { | ||
5243 | netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); | ||
5244 | features &= ~NETIF_F_GSO; | ||
5245 | } | ||
5246 | |||
5247 | /* UFO needs SG and checksumming */ | ||
5099 | if (features & NETIF_F_UFO) { | 5248 | if (features & NETIF_F_UFO) { |
5100 | /* maybe split UFO into V4 and V6? */ | 5249 | /* maybe split UFO into V4 and V6? */ |
5101 | if (!((features & NETIF_F_GEN_CSUM) || | 5250 | if (!((features & NETIF_F_GEN_CSUM) || |
5102 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) | 5251 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) |
5103 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5252 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { |
5104 | if (name) | 5253 | netdev_info(dev, |
5105 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO " | 5254 | "Dropping NETIF_F_UFO since no checksum offload features.\n"); |
5106 | "since no checksum offload features.\n", | ||
5107 | name); | ||
5108 | features &= ~NETIF_F_UFO; | 5255 | features &= ~NETIF_F_UFO; |
5109 | } | 5256 | } |
5110 | 5257 | ||
5111 | if (!(features & NETIF_F_SG)) { | 5258 | if (!(features & NETIF_F_SG)) { |
5112 | if (name) | 5259 | netdev_info(dev, |
5113 | printk(KERN_ERR "%s: Dropping NETIF_F_UFO " | 5260 | "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); |
5114 | "since no NETIF_F_SG feature.\n", name); | ||
5115 | features &= ~NETIF_F_UFO; | 5261 | features &= ~NETIF_F_UFO; |
5116 | } | 5262 | } |
5117 | } | 5263 | } |
@@ -5120,6 +5266,37 @@ unsigned long netdev_fix_features(unsigned long features, const char *name) | |||
5120 | } | 5266 | } |
5121 | EXPORT_SYMBOL(netdev_fix_features); | 5267 | EXPORT_SYMBOL(netdev_fix_features); |
5122 | 5268 | ||
5269 | void netdev_update_features(struct net_device *dev) | ||
5270 | { | ||
5271 | u32 features; | ||
5272 | int err = 0; | ||
5273 | |||
5274 | features = netdev_get_wanted_features(dev); | ||
5275 | |||
5276 | if (dev->netdev_ops->ndo_fix_features) | ||
5277 | features = dev->netdev_ops->ndo_fix_features(dev, features); | ||
5278 | |||
5279 | /* driver might be less strict about feature dependencies */ | ||
5280 | features = netdev_fix_features(dev, features); | ||
5281 | |||
5282 | if (dev->features == features) | ||
5283 | return; | ||
5284 | |||
5285 | netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", | ||
5286 | dev->features, features); | ||
5287 | |||
5288 | if (dev->netdev_ops->ndo_set_features) | ||
5289 | err = dev->netdev_ops->ndo_set_features(dev, features); | ||
5290 | |||
5291 | if (!err) | ||
5292 | dev->features = features; | ||
5293 | else if (err < 0) | ||
5294 | netdev_err(dev, | ||
5295 | "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", | ||
5296 | err, features, dev->features); | ||
5297 | } | ||
5298 | EXPORT_SYMBOL(netdev_update_features); | ||
5299 | |||
5123 | /** | 5300 | /** |
5124 | * netif_stacked_transfer_operstate - transfer operstate | 5301 | * netif_stacked_transfer_operstate - transfer operstate |
5125 | * @rootdev: the root or lower level device to transfer state from | 5302 | * @rootdev: the root or lower level device to transfer state from |
@@ -5254,27 +5431,19 @@ int register_netdevice(struct net_device *dev) | |||
5254 | if (dev->iflink == -1) | 5431 | if (dev->iflink == -1) |
5255 | dev->iflink = dev->ifindex; | 5432 | dev->iflink = dev->ifindex; |
5256 | 5433 | ||
5257 | /* Fix illegal checksum combinations */ | 5434 | /* Transfer changeable features to wanted_features and enable |
5258 | if ((dev->features & NETIF_F_HW_CSUM) && | 5435 | * software offloads (GSO and GRO). |
5259 | (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5436 | */ |
5260 | printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n", | 5437 | dev->hw_features |= NETIF_F_SOFT_FEATURES; |
5261 | dev->name); | 5438 | dev->features |= NETIF_F_SOFT_FEATURES; |
5262 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | 5439 | dev->wanted_features = dev->features & dev->hw_features; |
5263 | } | ||
5264 | 5440 | ||
5265 | if ((dev->features & NETIF_F_NO_CSUM) && | 5441 | /* Avoid warning from netdev_fix_features() for GSO without SG */ |
5266 | (dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5442 | if (!(dev->wanted_features & NETIF_F_SG)) { |
5267 | printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n", | 5443 | dev->wanted_features &= ~NETIF_F_GSO; |
5268 | dev->name); | 5444 | dev->features &= ~NETIF_F_GSO; |
5269 | dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | ||
5270 | } | 5445 | } |
5271 | 5446 | ||
5272 | dev->features = netdev_fix_features(dev->features, dev->name); | ||
5273 | |||
5274 | /* Enable software GSO if SG is supported. */ | ||
5275 | if (dev->features & NETIF_F_SG) | ||
5276 | dev->features |= NETIF_F_GSO; | ||
5277 | |||
5278 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, | 5447 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, |
5279 | * vlan_dev_init() will do the dev->features check, so these features | 5448 | * vlan_dev_init() will do the dev->features check, so these features |
5280 | * are enabled only if supported by underlying device. | 5449 | * are enabled only if supported by underlying device. |
@@ -5291,6 +5460,8 @@ int register_netdevice(struct net_device *dev) | |||
5291 | goto err_uninit; | 5460 | goto err_uninit; |
5292 | dev->reg_state = NETREG_REGISTERED; | 5461 | dev->reg_state = NETREG_REGISTERED; |
5293 | 5462 | ||
5463 | netdev_update_features(dev); | ||
5464 | |||
5294 | /* | 5465 | /* |
5295 | * Default initial state at registry is that the | 5466 | * Default initial state at registry is that the |
5296 | * device is present. | 5467 | * device is present. |
@@ -5695,6 +5866,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
5695 | #endif | 5866 | #endif |
5696 | 5867 | ||
5697 | strcpy(dev->name, name); | 5868 | strcpy(dev->name, name); |
5869 | dev->group = INIT_NETDEV_GROUP; | ||
5698 | return dev; | 5870 | return dev; |
5699 | 5871 | ||
5700 | free_all: | 5872 | free_all: |
@@ -6009,8 +6181,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
6009 | * @one to the master device with current feature set @all. Will not | 6181 | * @one to the master device with current feature set @all. Will not |
6010 | * enable anything that is off in @mask. Returns the new feature set. | 6182 | * enable anything that is off in @mask. Returns the new feature set. |
6011 | */ | 6183 | */ |
6012 | unsigned long netdev_increment_features(unsigned long all, unsigned long one, | 6184 | u32 netdev_increment_features(u32 all, u32 one, u32 mask) |
6013 | unsigned long mask) | ||
6014 | { | 6185 | { |
6015 | /* If device needs checksumming, downgrade to it. */ | 6186 | /* If device needs checksumming, downgrade to it. */ |
6016 | if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) | 6187 | if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) |
diff --git a/net/core/dst.c b/net/core/dst.c index b99c7c7ffce2..91104d35de7d 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -164,7 +164,9 @@ int dst_discard(struct sk_buff *skb) | |||
164 | } | 164 | } |
165 | EXPORT_SYMBOL(dst_discard); | 165 | EXPORT_SYMBOL(dst_discard); |
166 | 166 | ||
167 | void *dst_alloc(struct dst_ops *ops) | 167 | const u32 dst_default_metrics[RTAX_MAX]; |
168 | |||
169 | void *dst_alloc(struct dst_ops *ops, int initial_ref) | ||
168 | { | 170 | { |
169 | struct dst_entry *dst; | 171 | struct dst_entry *dst; |
170 | 172 | ||
@@ -175,11 +177,12 @@ void *dst_alloc(struct dst_ops *ops) | |||
175 | dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC); | 177 | dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC); |
176 | if (!dst) | 178 | if (!dst) |
177 | return NULL; | 179 | return NULL; |
178 | atomic_set(&dst->__refcnt, 0); | 180 | atomic_set(&dst->__refcnt, initial_ref); |
179 | dst->ops = ops; | 181 | dst->ops = ops; |
180 | dst->lastuse = jiffies; | 182 | dst->lastuse = jiffies; |
181 | dst->path = dst; | 183 | dst->path = dst; |
182 | dst->input = dst->output = dst_discard; | 184 | dst->input = dst->output = dst_discard; |
185 | dst_init_metrics(dst, dst_default_metrics, true); | ||
183 | #if RT_CACHE_DEBUG >= 2 | 186 | #if RT_CACHE_DEBUG >= 2 |
184 | atomic_inc(&dst_total); | 187 | atomic_inc(&dst_total); |
185 | #endif | 188 | #endif |
@@ -282,6 +285,42 @@ void dst_release(struct dst_entry *dst) | |||
282 | } | 285 | } |
283 | EXPORT_SYMBOL(dst_release); | 286 | EXPORT_SYMBOL(dst_release); |
284 | 287 | ||
288 | u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old) | ||
289 | { | ||
290 | u32 *p = kmalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC); | ||
291 | |||
292 | if (p) { | ||
293 | u32 *old_p = __DST_METRICS_PTR(old); | ||
294 | unsigned long prev, new; | ||
295 | |||
296 | memcpy(p, old_p, sizeof(u32) * RTAX_MAX); | ||
297 | |||
298 | new = (unsigned long) p; | ||
299 | prev = cmpxchg(&dst->_metrics, old, new); | ||
300 | |||
301 | if (prev != old) { | ||
302 | kfree(p); | ||
303 | p = __DST_METRICS_PTR(prev); | ||
304 | if (prev & DST_METRICS_READ_ONLY) | ||
305 | p = NULL; | ||
306 | } | ||
307 | } | ||
308 | return p; | ||
309 | } | ||
310 | EXPORT_SYMBOL(dst_cow_metrics_generic); | ||
311 | |||
312 | /* Caller asserts that dst_metrics_read_only(dst) is false. */ | ||
313 | void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) | ||
314 | { | ||
315 | unsigned long prev, new; | ||
316 | |||
317 | new = (unsigned long) dst_default_metrics; | ||
318 | prev = cmpxchg(&dst->_metrics, old, new); | ||
319 | if (prev == old) | ||
320 | kfree(__DST_METRICS_PTR(old)); | ||
321 | } | ||
322 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); | ||
323 | |||
285 | /** | 324 | /** |
286 | * skb_dst_set_noref - sets skb dst, without a reference | 325 | * skb_dst_set_noref - sets skb dst, without a reference |
287 | * @skb: buffer | 326 | * @skb: buffer |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index ff2302910b5e..c1a71bb738da 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -34,12 +34,6 @@ u32 ethtool_op_get_link(struct net_device *dev) | |||
34 | } | 34 | } |
35 | EXPORT_SYMBOL(ethtool_op_get_link); | 35 | EXPORT_SYMBOL(ethtool_op_get_link); |
36 | 36 | ||
37 | u32 ethtool_op_get_rx_csum(struct net_device *dev) | ||
38 | { | ||
39 | return (dev->features & NETIF_F_ALL_CSUM) != 0; | ||
40 | } | ||
41 | EXPORT_SYMBOL(ethtool_op_get_rx_csum); | ||
42 | |||
43 | u32 ethtool_op_get_tx_csum(struct net_device *dev) | 37 | u32 ethtool_op_get_tx_csum(struct net_device *dev) |
44 | { | 38 | { |
45 | return (dev->features & NETIF_F_ALL_CSUM) != 0; | 39 | return (dev->features & NETIF_F_ALL_CSUM) != 0; |
@@ -55,6 +49,7 @@ int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
55 | 49 | ||
56 | return 0; | 50 | return 0; |
57 | } | 51 | } |
52 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); | ||
58 | 53 | ||
59 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) | 54 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) |
60 | { | 55 | { |
@@ -171,6 +166,381 @@ EXPORT_SYMBOL(ethtool_ntuple_flush); | |||
171 | 166 | ||
172 | /* Handlers for each ethtool command */ | 167 | /* Handlers for each ethtool command */ |
173 | 168 | ||
169 | #define ETHTOOL_DEV_FEATURE_WORDS 1 | ||
170 | |||
171 | static void ethtool_get_features_compat(struct net_device *dev, | ||
172 | struct ethtool_get_features_block *features) | ||
173 | { | ||
174 | if (!dev->ethtool_ops) | ||
175 | return; | ||
176 | |||
177 | /* getting RX checksum */ | ||
178 | if (dev->ethtool_ops->get_rx_csum) | ||
179 | if (dev->ethtool_ops->get_rx_csum(dev)) | ||
180 | features[0].active |= NETIF_F_RXCSUM; | ||
181 | |||
182 | /* mark legacy-changeable features */ | ||
183 | if (dev->ethtool_ops->set_sg) | ||
184 | features[0].available |= NETIF_F_SG; | ||
185 | if (dev->ethtool_ops->set_tx_csum) | ||
186 | features[0].available |= NETIF_F_ALL_CSUM; | ||
187 | if (dev->ethtool_ops->set_tso) | ||
188 | features[0].available |= NETIF_F_ALL_TSO; | ||
189 | if (dev->ethtool_ops->set_rx_csum) | ||
190 | features[0].available |= NETIF_F_RXCSUM; | ||
191 | if (dev->ethtool_ops->set_flags) | ||
192 | features[0].available |= flags_dup_features; | ||
193 | } | ||
194 | |||
195 | static int ethtool_set_feature_compat(struct net_device *dev, | ||
196 | int (*legacy_set)(struct net_device *, u32), | ||
197 | struct ethtool_set_features_block *features, u32 mask) | ||
198 | { | ||
199 | u32 do_set; | ||
200 | |||
201 | if (!legacy_set) | ||
202 | return 0; | ||
203 | |||
204 | if (!(features[0].valid & mask)) | ||
205 | return 0; | ||
206 | |||
207 | features[0].valid &= ~mask; | ||
208 | |||
209 | do_set = !!(features[0].requested & mask); | ||
210 | |||
211 | if (legacy_set(dev, do_set) < 0) | ||
212 | netdev_info(dev, | ||
213 | "Legacy feature change (%s) failed for 0x%08x\n", | ||
214 | do_set ? "set" : "clear", mask); | ||
215 | |||
216 | return 1; | ||
217 | } | ||
218 | |||
219 | static int ethtool_set_features_compat(struct net_device *dev, | ||
220 | struct ethtool_set_features_block *features) | ||
221 | { | ||
222 | int compat; | ||
223 | |||
224 | if (!dev->ethtool_ops) | ||
225 | return 0; | ||
226 | |||
227 | compat = ethtool_set_feature_compat(dev, dev->ethtool_ops->set_sg, | ||
228 | features, NETIF_F_SG); | ||
229 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tx_csum, | ||
230 | features, NETIF_F_ALL_CSUM); | ||
231 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tso, | ||
232 | features, NETIF_F_ALL_TSO); | ||
233 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, | ||
234 | features, NETIF_F_RXCSUM); | ||
235 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags, | ||
236 | features, flags_dup_features); | ||
237 | |||
238 | return compat; | ||
239 | } | ||
240 | |||
241 | static int ethtool_get_features(struct net_device *dev, void __user *useraddr) | ||
242 | { | ||
243 | struct ethtool_gfeatures cmd = { | ||
244 | .cmd = ETHTOOL_GFEATURES, | ||
245 | .size = ETHTOOL_DEV_FEATURE_WORDS, | ||
246 | }; | ||
247 | struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS] = { | ||
248 | { | ||
249 | .available = dev->hw_features, | ||
250 | .requested = dev->wanted_features, | ||
251 | .active = dev->features, | ||
252 | .never_changed = NETIF_F_NEVER_CHANGE, | ||
253 | }, | ||
254 | }; | ||
255 | u32 __user *sizeaddr; | ||
256 | u32 copy_size; | ||
257 | |||
258 | ethtool_get_features_compat(dev, features); | ||
259 | |||
260 | sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size); | ||
261 | if (get_user(copy_size, sizeaddr)) | ||
262 | return -EFAULT; | ||
263 | |||
264 | if (copy_size > ETHTOOL_DEV_FEATURE_WORDS) | ||
265 | copy_size = ETHTOOL_DEV_FEATURE_WORDS; | ||
266 | |||
267 | if (copy_to_user(useraddr, &cmd, sizeof(cmd))) | ||
268 | return -EFAULT; | ||
269 | useraddr += sizeof(cmd); | ||
270 | if (copy_to_user(useraddr, features, copy_size * sizeof(*features))) | ||
271 | return -EFAULT; | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int ethtool_set_features(struct net_device *dev, void __user *useraddr) | ||
277 | { | ||
278 | struct ethtool_sfeatures cmd; | ||
279 | struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS]; | ||
280 | int ret = 0; | ||
281 | |||
282 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | ||
283 | return -EFAULT; | ||
284 | useraddr += sizeof(cmd); | ||
285 | |||
286 | if (cmd.size != ETHTOOL_DEV_FEATURE_WORDS) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (copy_from_user(features, useraddr, sizeof(features))) | ||
290 | return -EFAULT; | ||
291 | |||
292 | if (features[0].valid & ~NETIF_F_ETHTOOL_BITS) | ||
293 | return -EINVAL; | ||
294 | |||
295 | if (ethtool_set_features_compat(dev, features)) | ||
296 | ret |= ETHTOOL_F_COMPAT; | ||
297 | |||
298 | if (features[0].valid & ~dev->hw_features) { | ||
299 | features[0].valid &= dev->hw_features; | ||
300 | ret |= ETHTOOL_F_UNSUPPORTED; | ||
301 | } | ||
302 | |||
303 | dev->wanted_features &= ~features[0].valid; | ||
304 | dev->wanted_features |= features[0].valid & features[0].requested; | ||
305 | netdev_update_features(dev); | ||
306 | |||
307 | if ((dev->wanted_features ^ dev->features) & features[0].valid) | ||
308 | ret |= ETHTOOL_F_WISH; | ||
309 | |||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GSTRING_LEN] = { | ||
314 | /* NETIF_F_SG */ "tx-scatter-gather", | ||
315 | /* NETIF_F_IP_CSUM */ "tx-checksum-ipv4", | ||
316 | /* NETIF_F_NO_CSUM */ "tx-checksum-unneeded", | ||
317 | /* NETIF_F_HW_CSUM */ "tx-checksum-ip-generic", | ||
318 | /* NETIF_F_IPV6_CSUM */ "tx_checksum-ipv6", | ||
319 | /* NETIF_F_HIGHDMA */ "highdma", | ||
320 | /* NETIF_F_FRAGLIST */ "tx-scatter-gather-fraglist", | ||
321 | /* NETIF_F_HW_VLAN_TX */ "tx-vlan-hw-insert", | ||
322 | |||
323 | /* NETIF_F_HW_VLAN_RX */ "rx-vlan-hw-parse", | ||
324 | /* NETIF_F_HW_VLAN_FILTER */ "rx-vlan-filter", | ||
325 | /* NETIF_F_VLAN_CHALLENGED */ "vlan-challenged", | ||
326 | /* NETIF_F_GSO */ "tx-generic-segmentation", | ||
327 | /* NETIF_F_LLTX */ "tx-lockless", | ||
328 | /* NETIF_F_NETNS_LOCAL */ "netns-local", | ||
329 | /* NETIF_F_GRO */ "rx-gro", | ||
330 | /* NETIF_F_LRO */ "rx-lro", | ||
331 | |||
332 | /* NETIF_F_TSO */ "tx-tcp-segmentation", | ||
333 | /* NETIF_F_UFO */ "tx-udp-fragmentation", | ||
334 | /* NETIF_F_GSO_ROBUST */ "tx-gso-robust", | ||
335 | /* NETIF_F_TSO_ECN */ "tx-tcp-ecn-segmentation", | ||
336 | /* NETIF_F_TSO6 */ "tx-tcp6-segmentation", | ||
337 | /* NETIF_F_FSO */ "tx-fcoe-segmentation", | ||
338 | "", | ||
339 | "", | ||
340 | |||
341 | /* NETIF_F_FCOE_CRC */ "tx-checksum-fcoe-crc", | ||
342 | /* NETIF_F_SCTP_CSUM */ "tx-checksum-sctp", | ||
343 | /* NETIF_F_FCOE_MTU */ "fcoe-mtu", | ||
344 | /* NETIF_F_NTUPLE */ "rx-ntuple-filter", | ||
345 | /* NETIF_F_RXHASH */ "rx-hashing", | ||
346 | /* NETIF_F_RXCSUM */ "rx-checksum", | ||
347 | "", | ||
348 | "", | ||
349 | }; | ||
350 | |||
351 | static int __ethtool_get_sset_count(struct net_device *dev, int sset) | ||
352 | { | ||
353 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
354 | |||
355 | if (sset == ETH_SS_FEATURES) | ||
356 | return ARRAY_SIZE(netdev_features_strings); | ||
357 | |||
358 | if (ops && ops->get_sset_count && ops->get_strings) | ||
359 | return ops->get_sset_count(dev, sset); | ||
360 | else | ||
361 | return -EOPNOTSUPP; | ||
362 | } | ||
363 | |||
364 | static void __ethtool_get_strings(struct net_device *dev, | ||
365 | u32 stringset, u8 *data) | ||
366 | { | ||
367 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
368 | |||
369 | if (stringset == ETH_SS_FEATURES) | ||
370 | memcpy(data, netdev_features_strings, | ||
371 | sizeof(netdev_features_strings)); | ||
372 | else | ||
373 | /* ops->get_strings is valid because checked earlier */ | ||
374 | ops->get_strings(dev, stringset, data); | ||
375 | } | ||
376 | |||
377 | static u32 ethtool_get_feature_mask(u32 eth_cmd) | ||
378 | { | ||
379 | /* feature masks of legacy discrete ethtool ops */ | ||
380 | |||
381 | switch (eth_cmd) { | ||
382 | case ETHTOOL_GTXCSUM: | ||
383 | case ETHTOOL_STXCSUM: | ||
384 | return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM; | ||
385 | case ETHTOOL_GRXCSUM: | ||
386 | case ETHTOOL_SRXCSUM: | ||
387 | return NETIF_F_RXCSUM; | ||
388 | case ETHTOOL_GSG: | ||
389 | case ETHTOOL_SSG: | ||
390 | return NETIF_F_SG; | ||
391 | case ETHTOOL_GTSO: | ||
392 | case ETHTOOL_STSO: | ||
393 | return NETIF_F_ALL_TSO; | ||
394 | case ETHTOOL_GUFO: | ||
395 | case ETHTOOL_SUFO: | ||
396 | return NETIF_F_UFO; | ||
397 | case ETHTOOL_GGSO: | ||
398 | case ETHTOOL_SGSO: | ||
399 | return NETIF_F_GSO; | ||
400 | case ETHTOOL_GGRO: | ||
401 | case ETHTOOL_SGRO: | ||
402 | return NETIF_F_GRO; | ||
403 | default: | ||
404 | BUG(); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd) | ||
409 | { | ||
410 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
411 | |||
412 | if (!ops) | ||
413 | return NULL; | ||
414 | |||
415 | switch (ethcmd) { | ||
416 | case ETHTOOL_GTXCSUM: | ||
417 | return ops->get_tx_csum; | ||
418 | case ETHTOOL_GRXCSUM: | ||
419 | return ops->get_rx_csum; | ||
420 | case ETHTOOL_SSG: | ||
421 | return ops->get_sg; | ||
422 | case ETHTOOL_STSO: | ||
423 | return ops->get_tso; | ||
424 | case ETHTOOL_SUFO: | ||
425 | return ops->get_ufo; | ||
426 | default: | ||
427 | return NULL; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev) | ||
432 | { | ||
433 | return !!(dev->features & NETIF_F_ALL_CSUM); | ||
434 | } | ||
435 | |||
436 | static int ethtool_get_one_feature(struct net_device *dev, | ||
437 | char __user *useraddr, u32 ethcmd) | ||
438 | { | ||
439 | u32 mask = ethtool_get_feature_mask(ethcmd); | ||
440 | struct ethtool_value edata = { | ||
441 | .cmd = ethcmd, | ||
442 | .data = !!(dev->features & mask), | ||
443 | }; | ||
444 | |||
445 | /* compatibility with discrete get_ ops */ | ||
446 | if (!(dev->hw_features & mask)) { | ||
447 | u32 (*actor)(struct net_device *); | ||
448 | |||
449 | actor = __ethtool_get_one_feature_actor(dev, ethcmd); | ||
450 | |||
451 | /* bug compatibility with old get_rx_csum */ | ||
452 | if (ethcmd == ETHTOOL_GRXCSUM && !actor) | ||
453 | actor = __ethtool_get_rx_csum_oldbug; | ||
454 | |||
455 | if (actor) | ||
456 | edata.data = actor(dev); | ||
457 | } | ||
458 | |||
459 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
460 | return -EFAULT; | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int __ethtool_set_tx_csum(struct net_device *dev, u32 data); | ||
465 | static int __ethtool_set_rx_csum(struct net_device *dev, u32 data); | ||
466 | static int __ethtool_set_sg(struct net_device *dev, u32 data); | ||
467 | static int __ethtool_set_tso(struct net_device *dev, u32 data); | ||
468 | static int __ethtool_set_ufo(struct net_device *dev, u32 data); | ||
469 | |||
470 | static int ethtool_set_one_feature(struct net_device *dev, | ||
471 | void __user *useraddr, u32 ethcmd) | ||
472 | { | ||
473 | struct ethtool_value edata; | ||
474 | u32 mask; | ||
475 | |||
476 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
477 | return -EFAULT; | ||
478 | |||
479 | mask = ethtool_get_feature_mask(ethcmd); | ||
480 | mask &= dev->hw_features; | ||
481 | if (mask) { | ||
482 | if (edata.data) | ||
483 | dev->wanted_features |= mask; | ||
484 | else | ||
485 | dev->wanted_features &= ~mask; | ||
486 | |||
487 | netdev_update_features(dev); | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | /* Driver is not converted to ndo_fix_features or does not | ||
492 | * support changing this offload. In the latter case it won't | ||
493 | * have corresponding ethtool_ops field set. | ||
494 | * | ||
495 | * Following part is to be removed after all drivers advertise | ||
496 | * their changeable features in netdev->hw_features and stop | ||
497 | * using discrete offload setting ops. | ||
498 | */ | ||
499 | |||
500 | switch (ethcmd) { | ||
501 | case ETHTOOL_STXCSUM: | ||
502 | return __ethtool_set_tx_csum(dev, edata.data); | ||
503 | case ETHTOOL_SRXCSUM: | ||
504 | return __ethtool_set_rx_csum(dev, edata.data); | ||
505 | case ETHTOOL_SSG: | ||
506 | return __ethtool_set_sg(dev, edata.data); | ||
507 | case ETHTOOL_STSO: | ||
508 | return __ethtool_set_tso(dev, edata.data); | ||
509 | case ETHTOOL_SUFO: | ||
510 | return __ethtool_set_ufo(dev, edata.data); | ||
511 | default: | ||
512 | return -EOPNOTSUPP; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | static int __ethtool_set_flags(struct net_device *dev, u32 data) | ||
517 | { | ||
518 | u32 changed; | ||
519 | |||
520 | if (data & ~flags_dup_features) | ||
521 | return -EINVAL; | ||
522 | |||
523 | /* legacy set_flags() op */ | ||
524 | if (dev->ethtool_ops->set_flags) { | ||
525 | if (unlikely(dev->hw_features & flags_dup_features)) | ||
526 | netdev_warn(dev, | ||
527 | "driver BUG: mixed hw_features and set_flags()\n"); | ||
528 | return dev->ethtool_ops->set_flags(dev, data); | ||
529 | } | ||
530 | |||
531 | /* allow changing only bits set in hw_features */ | ||
532 | changed = (data ^ dev->wanted_features) & flags_dup_features; | ||
533 | if (changed & ~dev->hw_features) | ||
534 | return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP; | ||
535 | |||
536 | dev->wanted_features = | ||
537 | (dev->wanted_features & ~changed) | data; | ||
538 | |||
539 | netdev_update_features(dev); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
174 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | 544 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) |
175 | { | 545 | { |
176 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; | 546 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; |
@@ -251,14 +621,10 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev, | |||
251 | void __user *useraddr) | 621 | void __user *useraddr) |
252 | { | 622 | { |
253 | struct ethtool_sset_info info; | 623 | struct ethtool_sset_info info; |
254 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
255 | u64 sset_mask; | 624 | u64 sset_mask; |
256 | int i, idx = 0, n_bits = 0, ret, rc; | 625 | int i, idx = 0, n_bits = 0, ret, rc; |
257 | u32 *info_buf = NULL; | 626 | u32 *info_buf = NULL; |
258 | 627 | ||
259 | if (!ops->get_sset_count) | ||
260 | return -EOPNOTSUPP; | ||
261 | |||
262 | if (copy_from_user(&info, useraddr, sizeof(info))) | 628 | if (copy_from_user(&info, useraddr, sizeof(info))) |
263 | return -EFAULT; | 629 | return -EFAULT; |
264 | 630 | ||
@@ -285,7 +651,7 @@ static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev, | |||
285 | if (!(sset_mask & (1ULL << i))) | 651 | if (!(sset_mask & (1ULL << i))) |
286 | continue; | 652 | continue; |
287 | 653 | ||
288 | rc = ops->get_sset_count(dev, i); | 654 | rc = __ethtool_get_sset_count(dev, i); |
289 | if (rc >= 0) { | 655 | if (rc >= 0) { |
290 | info.sset_mask |= (1ULL << i); | 656 | info.sset_mask |= (1ULL << i); |
291 | info_buf[idx++] = rc; | 657 | info_buf[idx++] = rc; |
@@ -1091,6 +1457,9 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data) | |||
1091 | { | 1457 | { |
1092 | int err; | 1458 | int err; |
1093 | 1459 | ||
1460 | if (data && !(dev->features & NETIF_F_ALL_CSUM)) | ||
1461 | return -EINVAL; | ||
1462 | |||
1094 | if (!data && dev->ethtool_ops->set_tso) { | 1463 | if (!data && dev->ethtool_ops->set_tso) { |
1095 | err = dev->ethtool_ops->set_tso(dev, 0); | 1464 | err = dev->ethtool_ops->set_tso(dev, 0); |
1096 | if (err) | 1465 | if (err) |
@@ -1105,145 +1474,55 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data) | |||
1105 | return dev->ethtool_ops->set_sg(dev, data); | 1474 | return dev->ethtool_ops->set_sg(dev, data); |
1106 | } | 1475 | } |
1107 | 1476 | ||
1108 | static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) | 1477 | static int __ethtool_set_tx_csum(struct net_device *dev, u32 data) |
1109 | { | 1478 | { |
1110 | struct ethtool_value edata; | ||
1111 | int err; | 1479 | int err; |
1112 | 1480 | ||
1113 | if (!dev->ethtool_ops->set_tx_csum) | 1481 | if (!dev->ethtool_ops->set_tx_csum) |
1114 | return -EOPNOTSUPP; | 1482 | return -EOPNOTSUPP; |
1115 | 1483 | ||
1116 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | 1484 | if (!data && dev->ethtool_ops->set_sg) { |
1117 | return -EFAULT; | ||
1118 | |||
1119 | if (!edata.data && dev->ethtool_ops->set_sg) { | ||
1120 | err = __ethtool_set_sg(dev, 0); | 1485 | err = __ethtool_set_sg(dev, 0); |
1121 | if (err) | 1486 | if (err) |
1122 | return err; | 1487 | return err; |
1123 | } | 1488 | } |
1124 | 1489 | ||
1125 | return dev->ethtool_ops->set_tx_csum(dev, edata.data); | 1490 | return dev->ethtool_ops->set_tx_csum(dev, data); |
1126 | } | 1491 | } |
1127 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); | ||
1128 | 1492 | ||
1129 | static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr) | 1493 | static int __ethtool_set_rx_csum(struct net_device *dev, u32 data) |
1130 | { | 1494 | { |
1131 | struct ethtool_value edata; | ||
1132 | |||
1133 | if (!dev->ethtool_ops->set_rx_csum) | 1495 | if (!dev->ethtool_ops->set_rx_csum) |
1134 | return -EOPNOTSUPP; | 1496 | return -EOPNOTSUPP; |
1135 | 1497 | ||
1136 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | 1498 | if (!data) |
1137 | return -EFAULT; | ||
1138 | |||
1139 | if (!edata.data && dev->ethtool_ops->set_sg) | ||
1140 | dev->features &= ~NETIF_F_GRO; | 1499 | dev->features &= ~NETIF_F_GRO; |
1141 | 1500 | ||
1142 | return dev->ethtool_ops->set_rx_csum(dev, edata.data); | 1501 | return dev->ethtool_ops->set_rx_csum(dev, data); |
1143 | } | 1502 | } |
1144 | 1503 | ||
1145 | static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) | 1504 | static int __ethtool_set_tso(struct net_device *dev, u32 data) |
1146 | { | 1505 | { |
1147 | struct ethtool_value edata; | ||
1148 | |||
1149 | if (!dev->ethtool_ops->set_sg) | ||
1150 | return -EOPNOTSUPP; | ||
1151 | |||
1152 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
1153 | return -EFAULT; | ||
1154 | |||
1155 | if (edata.data && | ||
1156 | !(dev->features & NETIF_F_ALL_CSUM)) | ||
1157 | return -EINVAL; | ||
1158 | |||
1159 | return __ethtool_set_sg(dev, edata.data); | ||
1160 | } | ||
1161 | |||
1162 | static int ethtool_set_tso(struct net_device *dev, char __user *useraddr) | ||
1163 | { | ||
1164 | struct ethtool_value edata; | ||
1165 | |||
1166 | if (!dev->ethtool_ops->set_tso) | 1506 | if (!dev->ethtool_ops->set_tso) |
1167 | return -EOPNOTSUPP; | 1507 | return -EOPNOTSUPP; |
1168 | 1508 | ||
1169 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | 1509 | if (data && !(dev->features & NETIF_F_SG)) |
1170 | return -EFAULT; | ||
1171 | |||
1172 | if (edata.data && !(dev->features & NETIF_F_SG)) | ||
1173 | return -EINVAL; | 1510 | return -EINVAL; |
1174 | 1511 | ||
1175 | return dev->ethtool_ops->set_tso(dev, edata.data); | 1512 | return dev->ethtool_ops->set_tso(dev, data); |
1176 | } | 1513 | } |
1177 | 1514 | ||
1178 | static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) | 1515 | static int __ethtool_set_ufo(struct net_device *dev, u32 data) |
1179 | { | 1516 | { |
1180 | struct ethtool_value edata; | ||
1181 | |||
1182 | if (!dev->ethtool_ops->set_ufo) | 1517 | if (!dev->ethtool_ops->set_ufo) |
1183 | return -EOPNOTSUPP; | 1518 | return -EOPNOTSUPP; |
1184 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | 1519 | if (data && !(dev->features & NETIF_F_SG)) |
1185 | return -EFAULT; | ||
1186 | if (edata.data && !(dev->features & NETIF_F_SG)) | ||
1187 | return -EINVAL; | 1520 | return -EINVAL; |
1188 | if (edata.data && !((dev->features & NETIF_F_GEN_CSUM) || | 1521 | if (data && !((dev->features & NETIF_F_GEN_CSUM) || |
1189 | (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) | 1522 | (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) |
1190 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) | 1523 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) |
1191 | return -EINVAL; | 1524 | return -EINVAL; |
1192 | return dev->ethtool_ops->set_ufo(dev, edata.data); | 1525 | return dev->ethtool_ops->set_ufo(dev, data); |
1193 | } | ||
1194 | |||
1195 | static int ethtool_get_gso(struct net_device *dev, char __user *useraddr) | ||
1196 | { | ||
1197 | struct ethtool_value edata = { ETHTOOL_GGSO }; | ||
1198 | |||
1199 | edata.data = dev->features & NETIF_F_GSO; | ||
1200 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
1201 | return -EFAULT; | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | static int ethtool_set_gso(struct net_device *dev, char __user *useraddr) | ||
1206 | { | ||
1207 | struct ethtool_value edata; | ||
1208 | |||
1209 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
1210 | return -EFAULT; | ||
1211 | if (edata.data) | ||
1212 | dev->features |= NETIF_F_GSO; | ||
1213 | else | ||
1214 | dev->features &= ~NETIF_F_GSO; | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int ethtool_get_gro(struct net_device *dev, char __user *useraddr) | ||
1219 | { | ||
1220 | struct ethtool_value edata = { ETHTOOL_GGRO }; | ||
1221 | |||
1222 | edata.data = dev->features & NETIF_F_GRO; | ||
1223 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
1224 | return -EFAULT; | ||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | static int ethtool_set_gro(struct net_device *dev, char __user *useraddr) | ||
1229 | { | ||
1230 | struct ethtool_value edata; | ||
1231 | |||
1232 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
1233 | return -EFAULT; | ||
1234 | |||
1235 | if (edata.data) { | ||
1236 | u32 rxcsum = dev->ethtool_ops->get_rx_csum ? | ||
1237 | dev->ethtool_ops->get_rx_csum(dev) : | ||
1238 | ethtool_op_get_rx_csum(dev); | ||
1239 | |||
1240 | if (!rxcsum) | ||
1241 | return -EINVAL; | ||
1242 | dev->features |= NETIF_F_GRO; | ||
1243 | } else | ||
1244 | dev->features &= ~NETIF_F_GRO; | ||
1245 | |||
1246 | return 0; | ||
1247 | } | 1526 | } |
1248 | 1527 | ||
1249 | static int ethtool_self_test(struct net_device *dev, char __user *useraddr) | 1528 | static int ethtool_self_test(struct net_device *dev, char __user *useraddr) |
@@ -1287,17 +1566,13 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) | |||
1287 | static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) | 1566 | static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) |
1288 | { | 1567 | { |
1289 | struct ethtool_gstrings gstrings; | 1568 | struct ethtool_gstrings gstrings; |
1290 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
1291 | u8 *data; | 1569 | u8 *data; |
1292 | int ret; | 1570 | int ret; |
1293 | 1571 | ||
1294 | if (!ops->get_strings || !ops->get_sset_count) | ||
1295 | return -EOPNOTSUPP; | ||
1296 | |||
1297 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) | 1572 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) |
1298 | return -EFAULT; | 1573 | return -EFAULT; |
1299 | 1574 | ||
1300 | ret = ops->get_sset_count(dev, gstrings.string_set); | 1575 | ret = __ethtool_get_sset_count(dev, gstrings.string_set); |
1301 | if (ret < 0) | 1576 | if (ret < 0) |
1302 | return ret; | 1577 | return ret; |
1303 | 1578 | ||
@@ -1307,7 +1582,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) | |||
1307 | if (!data) | 1582 | if (!data) |
1308 | return -ENOMEM; | 1583 | return -ENOMEM; |
1309 | 1584 | ||
1310 | ops->get_strings(dev, gstrings.string_set, data); | 1585 | __ethtool_get_strings(dev, gstrings.string_set, data); |
1311 | 1586 | ||
1312 | ret = -EFAULT; | 1587 | ret = -EFAULT; |
1313 | if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) | 1588 | if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) |
@@ -1317,7 +1592,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) | |||
1317 | goto out; | 1592 | goto out; |
1318 | ret = 0; | 1593 | ret = 0; |
1319 | 1594 | ||
1320 | out: | 1595 | out: |
1321 | kfree(data); | 1596 | kfree(data); |
1322 | return ret; | 1597 | return ret; |
1323 | } | 1598 | } |
@@ -1458,7 +1733,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1458 | void __user *useraddr = ifr->ifr_data; | 1733 | void __user *useraddr = ifr->ifr_data; |
1459 | u32 ethcmd; | 1734 | u32 ethcmd; |
1460 | int rc; | 1735 | int rc; |
1461 | unsigned long old_features; | 1736 | u32 old_features; |
1462 | 1737 | ||
1463 | if (!dev || !netif_device_present(dev)) | 1738 | if (!dev || !netif_device_present(dev)) |
1464 | return -ENODEV; | 1739 | return -ENODEV; |
@@ -1500,6 +1775,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1500 | case ETHTOOL_GRXCLSRLCNT: | 1775 | case ETHTOOL_GRXCLSRLCNT: |
1501 | case ETHTOOL_GRXCLSRULE: | 1776 | case ETHTOOL_GRXCLSRULE: |
1502 | case ETHTOOL_GRXCLSRLALL: | 1777 | case ETHTOOL_GRXCLSRLALL: |
1778 | case ETHTOOL_GFEATURES: | ||
1503 | break; | 1779 | break; |
1504 | default: | 1780 | default: |
1505 | if (!capable(CAP_NET_ADMIN)) | 1781 | if (!capable(CAP_NET_ADMIN)) |
@@ -1570,42 +1846,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1570 | case ETHTOOL_SPAUSEPARAM: | 1846 | case ETHTOOL_SPAUSEPARAM: |
1571 | rc = ethtool_set_pauseparam(dev, useraddr); | 1847 | rc = ethtool_set_pauseparam(dev, useraddr); |
1572 | break; | 1848 | break; |
1573 | case ETHTOOL_GRXCSUM: | ||
1574 | rc = ethtool_get_value(dev, useraddr, ethcmd, | ||
1575 | (dev->ethtool_ops->get_rx_csum ? | ||
1576 | dev->ethtool_ops->get_rx_csum : | ||
1577 | ethtool_op_get_rx_csum)); | ||
1578 | break; | ||
1579 | case ETHTOOL_SRXCSUM: | ||
1580 | rc = ethtool_set_rx_csum(dev, useraddr); | ||
1581 | break; | ||
1582 | case ETHTOOL_GTXCSUM: | ||
1583 | rc = ethtool_get_value(dev, useraddr, ethcmd, | ||
1584 | (dev->ethtool_ops->get_tx_csum ? | ||
1585 | dev->ethtool_ops->get_tx_csum : | ||
1586 | ethtool_op_get_tx_csum)); | ||
1587 | break; | ||
1588 | case ETHTOOL_STXCSUM: | ||
1589 | rc = ethtool_set_tx_csum(dev, useraddr); | ||
1590 | break; | ||
1591 | case ETHTOOL_GSG: | ||
1592 | rc = ethtool_get_value(dev, useraddr, ethcmd, | ||
1593 | (dev->ethtool_ops->get_sg ? | ||
1594 | dev->ethtool_ops->get_sg : | ||
1595 | ethtool_op_get_sg)); | ||
1596 | break; | ||
1597 | case ETHTOOL_SSG: | ||
1598 | rc = ethtool_set_sg(dev, useraddr); | ||
1599 | break; | ||
1600 | case ETHTOOL_GTSO: | ||
1601 | rc = ethtool_get_value(dev, useraddr, ethcmd, | ||
1602 | (dev->ethtool_ops->get_tso ? | ||
1603 | dev->ethtool_ops->get_tso : | ||
1604 | ethtool_op_get_tso)); | ||
1605 | break; | ||
1606 | case ETHTOOL_STSO: | ||
1607 | rc = ethtool_set_tso(dev, useraddr); | ||
1608 | break; | ||
1609 | case ETHTOOL_TEST: | 1849 | case ETHTOOL_TEST: |
1610 | rc = ethtool_self_test(dev, useraddr); | 1850 | rc = ethtool_self_test(dev, useraddr); |
1611 | break; | 1851 | break; |
@@ -1621,21 +1861,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1621 | case ETHTOOL_GPERMADDR: | 1861 | case ETHTOOL_GPERMADDR: |
1622 | rc = ethtool_get_perm_addr(dev, useraddr); | 1862 | rc = ethtool_get_perm_addr(dev, useraddr); |
1623 | break; | 1863 | break; |
1624 | case ETHTOOL_GUFO: | ||
1625 | rc = ethtool_get_value(dev, useraddr, ethcmd, | ||
1626 | (dev->ethtool_ops->get_ufo ? | ||
1627 | dev->ethtool_ops->get_ufo : | ||
1628 | ethtool_op_get_ufo)); | ||
1629 | break; | ||
1630 | case ETHTOOL_SUFO: | ||
1631 | rc = ethtool_set_ufo(dev, useraddr); | ||
1632 | break; | ||
1633 | case ETHTOOL_GGSO: | ||
1634 | rc = ethtool_get_gso(dev, useraddr); | ||
1635 | break; | ||
1636 | case ETHTOOL_SGSO: | ||
1637 | rc = ethtool_set_gso(dev, useraddr); | ||
1638 | break; | ||
1639 | case ETHTOOL_GFLAGS: | 1864 | case ETHTOOL_GFLAGS: |
1640 | rc = ethtool_get_value(dev, useraddr, ethcmd, | 1865 | rc = ethtool_get_value(dev, useraddr, ethcmd, |
1641 | (dev->ethtool_ops->get_flags ? | 1866 | (dev->ethtool_ops->get_flags ? |
@@ -1643,8 +1868,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1643 | ethtool_op_get_flags)); | 1868 | ethtool_op_get_flags)); |
1644 | break; | 1869 | break; |
1645 | case ETHTOOL_SFLAGS: | 1870 | case ETHTOOL_SFLAGS: |
1646 | rc = ethtool_set_value(dev, useraddr, | 1871 | rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags); |
1647 | dev->ethtool_ops->set_flags); | ||
1648 | break; | 1872 | break; |
1649 | case ETHTOOL_GPFLAGS: | 1873 | case ETHTOOL_GPFLAGS: |
1650 | rc = ethtool_get_value(dev, useraddr, ethcmd, | 1874 | rc = ethtool_get_value(dev, useraddr, ethcmd, |
@@ -1666,12 +1890,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1666 | case ETHTOOL_SRXCLSRLINS: | 1890 | case ETHTOOL_SRXCLSRLINS: |
1667 | rc = ethtool_set_rxnfc(dev, ethcmd, useraddr); | 1891 | rc = ethtool_set_rxnfc(dev, ethcmd, useraddr); |
1668 | break; | 1892 | break; |
1669 | case ETHTOOL_GGRO: | ||
1670 | rc = ethtool_get_gro(dev, useraddr); | ||
1671 | break; | ||
1672 | case ETHTOOL_SGRO: | ||
1673 | rc = ethtool_set_gro(dev, useraddr); | ||
1674 | break; | ||
1675 | case ETHTOOL_FLASHDEV: | 1893 | case ETHTOOL_FLASHDEV: |
1676 | rc = ethtool_flash_device(dev, useraddr); | 1894 | rc = ethtool_flash_device(dev, useraddr); |
1677 | break; | 1895 | break; |
@@ -1693,6 +1911,30 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1693 | case ETHTOOL_SRXFHINDIR: | 1911 | case ETHTOOL_SRXFHINDIR: |
1694 | rc = ethtool_set_rxfh_indir(dev, useraddr); | 1912 | rc = ethtool_set_rxfh_indir(dev, useraddr); |
1695 | break; | 1913 | break; |
1914 | case ETHTOOL_GFEATURES: | ||
1915 | rc = ethtool_get_features(dev, useraddr); | ||
1916 | break; | ||
1917 | case ETHTOOL_SFEATURES: | ||
1918 | rc = ethtool_set_features(dev, useraddr); | ||
1919 | break; | ||
1920 | case ETHTOOL_GTXCSUM: | ||
1921 | case ETHTOOL_GRXCSUM: | ||
1922 | case ETHTOOL_GSG: | ||
1923 | case ETHTOOL_GTSO: | ||
1924 | case ETHTOOL_GUFO: | ||
1925 | case ETHTOOL_GGSO: | ||
1926 | case ETHTOOL_GGRO: | ||
1927 | rc = ethtool_get_one_feature(dev, useraddr, ethcmd); | ||
1928 | break; | ||
1929 | case ETHTOOL_STXCSUM: | ||
1930 | case ETHTOOL_SRXCSUM: | ||
1931 | case ETHTOOL_SSG: | ||
1932 | case ETHTOOL_STSO: | ||
1933 | case ETHTOOL_SUFO: | ||
1934 | case ETHTOOL_SGSO: | ||
1935 | case ETHTOOL_SGRO: | ||
1936 | rc = ethtool_set_one_feature(dev, useraddr, ethcmd); | ||
1937 | break; | ||
1696 | default: | 1938 | default: |
1697 | rc = -EOPNOTSUPP; | 1939 | rc = -EOPNOTSUPP; |
1698 | } | 1940 | } |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index a20e5d3bbfa0..8248ebb5891d 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -181,13 +181,13 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, | |||
181 | { | 181 | { |
182 | int ret = 0; | 182 | int ret = 0; |
183 | 183 | ||
184 | if (rule->iifindex && (rule->iifindex != fl->iif)) | 184 | if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) |
185 | goto out; | 185 | goto out; |
186 | 186 | ||
187 | if (rule->oifindex && (rule->oifindex != fl->oif)) | 187 | if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) |
188 | goto out; | 188 | goto out; |
189 | 189 | ||
190 | if ((rule->mark ^ fl->mark) & rule->mark_mask) | 190 | if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) |
191 | goto out; | 191 | goto out; |
192 | 192 | ||
193 | ret = ops->match(rule, fl, flags); | 193 | ret = ops->match(rule, fl, flags); |
diff --git a/net/core/filter.c b/net/core/filter.c index afc58374ca96..232b1873bb28 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -142,14 +142,14 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) | |||
142 | if (err) | 142 | if (err) |
143 | return err; | 143 | return err; |
144 | 144 | ||
145 | rcu_read_lock_bh(); | 145 | rcu_read_lock(); |
146 | filter = rcu_dereference_bh(sk->sk_filter); | 146 | filter = rcu_dereference(sk->sk_filter); |
147 | if (filter) { | 147 | if (filter) { |
148 | unsigned int pkt_len = sk_run_filter(skb, filter->insns); | 148 | unsigned int pkt_len = sk_run_filter(skb, filter->insns); |
149 | 149 | ||
150 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; | 150 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; |
151 | } | 151 | } |
152 | rcu_read_unlock_bh(); | 152 | rcu_read_unlock(); |
153 | 153 | ||
154 | return err; | 154 | return err; |
155 | } | 155 | } |
diff --git a/net/core/flow.c b/net/core/flow.c index 127c8a7ffd61..990703b8863b 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -172,9 +172,9 @@ static void flow_new_hash_rnd(struct flow_cache *fc, | |||
172 | 172 | ||
173 | static u32 flow_hash_code(struct flow_cache *fc, | 173 | static u32 flow_hash_code(struct flow_cache *fc, |
174 | struct flow_cache_percpu *fcp, | 174 | struct flow_cache_percpu *fcp, |
175 | struct flowi *key) | 175 | const struct flowi *key) |
176 | { | 176 | { |
177 | u32 *k = (u32 *) key; | 177 | const u32 *k = (const u32 *) key; |
178 | 178 | ||
179 | return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) | 179 | return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) |
180 | & (flow_cache_hash_size(fc) - 1); | 180 | & (flow_cache_hash_size(fc) - 1); |
@@ -186,17 +186,17 @@ typedef unsigned long flow_compare_t; | |||
186 | * important assumptions that we can here, such as alignment and | 186 | * important assumptions that we can here, such as alignment and |
187 | * constant size. | 187 | * constant size. |
188 | */ | 188 | */ |
189 | static int flow_key_compare(struct flowi *key1, struct flowi *key2) | 189 | static int flow_key_compare(const struct flowi *key1, const struct flowi *key2) |
190 | { | 190 | { |
191 | flow_compare_t *k1, *k1_lim, *k2; | 191 | const flow_compare_t *k1, *k1_lim, *k2; |
192 | const int n_elem = sizeof(struct flowi) / sizeof(flow_compare_t); | 192 | const int n_elem = sizeof(struct flowi) / sizeof(flow_compare_t); |
193 | 193 | ||
194 | BUILD_BUG_ON(sizeof(struct flowi) % sizeof(flow_compare_t)); | 194 | BUILD_BUG_ON(sizeof(struct flowi) % sizeof(flow_compare_t)); |
195 | 195 | ||
196 | k1 = (flow_compare_t *) key1; | 196 | k1 = (const flow_compare_t *) key1; |
197 | k1_lim = k1 + n_elem; | 197 | k1_lim = k1 + n_elem; |
198 | 198 | ||
199 | k2 = (flow_compare_t *) key2; | 199 | k2 = (const flow_compare_t *) key2; |
200 | 200 | ||
201 | do { | 201 | do { |
202 | if (*k1++ != *k2++) | 202 | if (*k1++ != *k2++) |
@@ -207,7 +207,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | struct flow_cache_object * | 209 | struct flow_cache_object * |
210 | flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir, | 210 | flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, |
211 | flow_resolve_t resolver, void *ctx) | 211 | flow_resolve_t resolver, void *ctx) |
212 | { | 212 | { |
213 | struct flow_cache *fc = &flow_cache_global; | 213 | struct flow_cache *fc = &flow_cache_global; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 60a902913429..799f06e03a22 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -316,7 +316,7 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) | |||
316 | { | 316 | { |
317 | size_t size = entries * sizeof(struct neighbour *); | 317 | size_t size = entries * sizeof(struct neighbour *); |
318 | struct neigh_hash_table *ret; | 318 | struct neigh_hash_table *ret; |
319 | struct neighbour **buckets; | 319 | struct neighbour __rcu **buckets; |
320 | 320 | ||
321 | ret = kmalloc(sizeof(*ret), GFP_ATOMIC); | 321 | ret = kmalloc(sizeof(*ret), GFP_ATOMIC); |
322 | if (!ret) | 322 | if (!ret) |
@@ -324,14 +324,14 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) | |||
324 | if (size <= PAGE_SIZE) | 324 | if (size <= PAGE_SIZE) |
325 | buckets = kzalloc(size, GFP_ATOMIC); | 325 | buckets = kzalloc(size, GFP_ATOMIC); |
326 | else | 326 | else |
327 | buckets = (struct neighbour **) | 327 | buckets = (struct neighbour __rcu **) |
328 | __get_free_pages(GFP_ATOMIC | __GFP_ZERO, | 328 | __get_free_pages(GFP_ATOMIC | __GFP_ZERO, |
329 | get_order(size)); | 329 | get_order(size)); |
330 | if (!buckets) { | 330 | if (!buckets) { |
331 | kfree(ret); | 331 | kfree(ret); |
332 | return NULL; | 332 | return NULL; |
333 | } | 333 | } |
334 | rcu_assign_pointer(ret->hash_buckets, buckets); | 334 | ret->hash_buckets = buckets; |
335 | ret->hash_mask = entries - 1; | 335 | ret->hash_mask = entries - 1; |
336 | get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); | 336 | get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); |
337 | return ret; | 337 | return ret; |
@@ -343,7 +343,7 @@ static void neigh_hash_free_rcu(struct rcu_head *head) | |||
343 | struct neigh_hash_table, | 343 | struct neigh_hash_table, |
344 | rcu); | 344 | rcu); |
345 | size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); | 345 | size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); |
346 | struct neighbour **buckets = nht->hash_buckets; | 346 | struct neighbour __rcu **buckets = nht->hash_buckets; |
347 | 347 | ||
348 | if (size <= PAGE_SIZE) | 348 | if (size <= PAGE_SIZE) |
349 | kfree(buckets); | 349 | kfree(buckets); |
@@ -1540,7 +1540,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1540 | panic("cannot create neighbour proc dir entry"); | 1540 | panic("cannot create neighbour proc dir entry"); |
1541 | #endif | 1541 | #endif |
1542 | 1542 | ||
1543 | tbl->nht = neigh_hash_alloc(8); | 1543 | RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(8)); |
1544 | 1544 | ||
1545 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); | 1545 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); |
1546 | tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); | 1546 | tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); |
@@ -1602,7 +1602,8 @@ int neigh_table_clear(struct neigh_table *tbl) | |||
1602 | } | 1602 | } |
1603 | write_unlock(&neigh_tbl_lock); | 1603 | write_unlock(&neigh_tbl_lock); |
1604 | 1604 | ||
1605 | call_rcu(&tbl->nht->rcu, neigh_hash_free_rcu); | 1605 | call_rcu(&rcu_dereference_protected(tbl->nht, 1)->rcu, |
1606 | neigh_hash_free_rcu); | ||
1606 | tbl->nht = NULL; | 1607 | tbl->nht = NULL; |
1607 | 1608 | ||
1608 | kfree(tbl->phash_buckets); | 1609 | kfree(tbl->phash_buckets); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index e23c01be5a5b..5ceb257e860c 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -99,7 +99,7 @@ NETDEVICE_SHOW(addr_assign_type, fmt_dec); | |||
99 | NETDEVICE_SHOW(addr_len, fmt_dec); | 99 | NETDEVICE_SHOW(addr_len, fmt_dec); |
100 | NETDEVICE_SHOW(iflink, fmt_dec); | 100 | NETDEVICE_SHOW(iflink, fmt_dec); |
101 | NETDEVICE_SHOW(ifindex, fmt_dec); | 101 | NETDEVICE_SHOW(ifindex, fmt_dec); |
102 | NETDEVICE_SHOW(features, fmt_long_hex); | 102 | NETDEVICE_SHOW(features, fmt_hex); |
103 | NETDEVICE_SHOW(type, fmt_dec); | 103 | NETDEVICE_SHOW(type, fmt_dec); |
104 | NETDEVICE_SHOW(link_mode, fmt_dec); | 104 | NETDEVICE_SHOW(link_mode, fmt_dec); |
105 | 105 | ||
@@ -295,6 +295,20 @@ static ssize_t show_ifalias(struct device *dev, | |||
295 | return ret; | 295 | return ret; |
296 | } | 296 | } |
297 | 297 | ||
298 | NETDEVICE_SHOW(group, fmt_dec); | ||
299 | |||
300 | static int change_group(struct net_device *net, unsigned long new_group) | ||
301 | { | ||
302 | dev_set_group(net, (int) new_group); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static ssize_t store_group(struct device *dev, struct device_attribute *attr, | ||
307 | const char *buf, size_t len) | ||
308 | { | ||
309 | return netdev_store(dev, attr, buf, len, change_group); | ||
310 | } | ||
311 | |||
298 | static struct device_attribute net_class_attributes[] = { | 312 | static struct device_attribute net_class_attributes[] = { |
299 | __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), | 313 | __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), |
300 | __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), | 314 | __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), |
@@ -316,6 +330,7 @@ static struct device_attribute net_class_attributes[] = { | |||
316 | __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), | 330 | __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), |
317 | __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, | 331 | __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, |
318 | store_tx_queue_len), | 332 | store_tx_queue_len), |
333 | __ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group), | ||
319 | {} | 334 | {} |
320 | }; | 335 | }; |
321 | 336 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 02dc2cbcbe86..06be2431753e 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -193,6 +193,17 @@ void netpoll_poll_dev(struct net_device *dev) | |||
193 | 193 | ||
194 | poll_napi(dev); | 194 | poll_napi(dev); |
195 | 195 | ||
196 | if (dev->priv_flags & IFF_SLAVE) { | ||
197 | if (dev->npinfo) { | ||
198 | struct net_device *bond_dev = dev->master; | ||
199 | struct sk_buff *skb; | ||
200 | while ((skb = skb_dequeue(&dev->npinfo->arp_tx))) { | ||
201 | skb->dev = bond_dev; | ||
202 | skb_queue_tail(&bond_dev->npinfo->arp_tx, skb); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
196 | service_arp_queue(dev->npinfo); | 207 | service_arp_queue(dev->npinfo); |
197 | 208 | ||
198 | zap_completion_queue(); | 209 | zap_completion_queue(); |
@@ -313,9 +324,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
313 | tries > 0; --tries) { | 324 | tries > 0; --tries) { |
314 | if (__netif_tx_trylock(txq)) { | 325 | if (__netif_tx_trylock(txq)) { |
315 | if (!netif_tx_queue_stopped(txq)) { | 326 | if (!netif_tx_queue_stopped(txq)) { |
316 | dev->priv_flags |= IFF_IN_NETPOLL; | ||
317 | status = ops->ndo_start_xmit(skb, dev); | 327 | status = ops->ndo_start_xmit(skb, dev); |
318 | dev->priv_flags &= ~IFF_IN_NETPOLL; | ||
319 | if (status == NETDEV_TX_OK) | 328 | if (status == NETDEV_TX_OK) |
320 | txq_trans_update(txq); | 329 | txq_trans_update(txq); |
321 | } | 330 | } |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b5bada92f637..0c55eaa70e39 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -251,6 +251,7 @@ struct pktgen_dev { | |||
251 | int max_pkt_size; /* = ETH_ZLEN; */ | 251 | int max_pkt_size; /* = ETH_ZLEN; */ |
252 | int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ | 252 | int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ |
253 | int nfrags; | 253 | int nfrags; |
254 | struct page *page; | ||
254 | u64 delay; /* nano-seconds */ | 255 | u64 delay; /* nano-seconds */ |
255 | 256 | ||
256 | __u64 count; /* Default No packets to send */ | 257 | __u64 count; /* Default No packets to send */ |
@@ -1134,6 +1135,10 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1134 | if (node_possible(value)) { | 1135 | if (node_possible(value)) { |
1135 | pkt_dev->node = value; | 1136 | pkt_dev->node = value; |
1136 | sprintf(pg_result, "OK: node=%d", pkt_dev->node); | 1137 | sprintf(pg_result, "OK: node=%d", pkt_dev->node); |
1138 | if (pkt_dev->page) { | ||
1139 | put_page(pkt_dev->page); | ||
1140 | pkt_dev->page = NULL; | ||
1141 | } | ||
1137 | } | 1142 | } |
1138 | else | 1143 | else |
1139 | sprintf(pg_result, "ERROR: node not possible"); | 1144 | sprintf(pg_result, "ERROR: node not possible"); |
@@ -2605,6 +2610,89 @@ static inline __be16 build_tci(unsigned int id, unsigned int cfi, | |||
2605 | return htons(id | (cfi << 12) | (prio << 13)); | 2610 | return htons(id | (cfi << 12) | (prio << 13)); |
2606 | } | 2611 | } |
2607 | 2612 | ||
2613 | static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb, | ||
2614 | int datalen) | ||
2615 | { | ||
2616 | struct timeval timestamp; | ||
2617 | struct pktgen_hdr *pgh; | ||
2618 | |||
2619 | pgh = (struct pktgen_hdr *)skb_put(skb, sizeof(*pgh)); | ||
2620 | datalen -= sizeof(*pgh); | ||
2621 | |||
2622 | if (pkt_dev->nfrags <= 0) { | ||
2623 | memset(skb_put(skb, datalen), 0, datalen); | ||
2624 | } else { | ||
2625 | int frags = pkt_dev->nfrags; | ||
2626 | int i, len; | ||
2627 | |||
2628 | |||
2629 | if (frags > MAX_SKB_FRAGS) | ||
2630 | frags = MAX_SKB_FRAGS; | ||
2631 | len = datalen - frags * PAGE_SIZE; | ||
2632 | if (len > 0) { | ||
2633 | memset(skb_put(skb, len), 0, len); | ||
2634 | datalen = frags * PAGE_SIZE; | ||
2635 | } | ||
2636 | |||
2637 | i = 0; | ||
2638 | while (datalen > 0) { | ||
2639 | if (unlikely(!pkt_dev->page)) { | ||
2640 | int node = numa_node_id(); | ||
2641 | |||
2642 | if (pkt_dev->node >= 0 && (pkt_dev->flags & F_NODE)) | ||
2643 | node = pkt_dev->node; | ||
2644 | pkt_dev->page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0); | ||
2645 | if (!pkt_dev->page) | ||
2646 | break; | ||
2647 | } | ||
2648 | skb_shinfo(skb)->frags[i].page = pkt_dev->page; | ||
2649 | get_page(pkt_dev->page); | ||
2650 | skb_shinfo(skb)->frags[i].page_offset = 0; | ||
2651 | skb_shinfo(skb)->frags[i].size = | ||
2652 | (datalen < PAGE_SIZE ? datalen : PAGE_SIZE); | ||
2653 | datalen -= skb_shinfo(skb)->frags[i].size; | ||
2654 | skb->len += skb_shinfo(skb)->frags[i].size; | ||
2655 | skb->data_len += skb_shinfo(skb)->frags[i].size; | ||
2656 | i++; | ||
2657 | skb_shinfo(skb)->nr_frags = i; | ||
2658 | } | ||
2659 | |||
2660 | while (i < frags) { | ||
2661 | int rem; | ||
2662 | |||
2663 | if (i == 0) | ||
2664 | break; | ||
2665 | |||
2666 | rem = skb_shinfo(skb)->frags[i - 1].size / 2; | ||
2667 | if (rem == 0) | ||
2668 | break; | ||
2669 | |||
2670 | skb_shinfo(skb)->frags[i - 1].size -= rem; | ||
2671 | |||
2672 | skb_shinfo(skb)->frags[i] = | ||
2673 | skb_shinfo(skb)->frags[i - 1]; | ||
2674 | get_page(skb_shinfo(skb)->frags[i].page); | ||
2675 | skb_shinfo(skb)->frags[i].page = | ||
2676 | skb_shinfo(skb)->frags[i - 1].page; | ||
2677 | skb_shinfo(skb)->frags[i].page_offset += | ||
2678 | skb_shinfo(skb)->frags[i - 1].size; | ||
2679 | skb_shinfo(skb)->frags[i].size = rem; | ||
2680 | i++; | ||
2681 | skb_shinfo(skb)->nr_frags = i; | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | /* Stamp the time, and sequence number, | ||
2686 | * convert them to network byte order | ||
2687 | */ | ||
2688 | pgh->pgh_magic = htonl(PKTGEN_MAGIC); | ||
2689 | pgh->seq_num = htonl(pkt_dev->seq_num); | ||
2690 | |||
2691 | do_gettimeofday(×tamp); | ||
2692 | pgh->tv_sec = htonl(timestamp.tv_sec); | ||
2693 | pgh->tv_usec = htonl(timestamp.tv_usec); | ||
2694 | } | ||
2695 | |||
2608 | static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | 2696 | static struct sk_buff *fill_packet_ipv4(struct net_device *odev, |
2609 | struct pktgen_dev *pkt_dev) | 2697 | struct pktgen_dev *pkt_dev) |
2610 | { | 2698 | { |
@@ -2613,7 +2701,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2613 | struct udphdr *udph; | 2701 | struct udphdr *udph; |
2614 | int datalen, iplen; | 2702 | int datalen, iplen; |
2615 | struct iphdr *iph; | 2703 | struct iphdr *iph; |
2616 | struct pktgen_hdr *pgh = NULL; | ||
2617 | __be16 protocol = htons(ETH_P_IP); | 2704 | __be16 protocol = htons(ETH_P_IP); |
2618 | __be32 *mpls; | 2705 | __be32 *mpls; |
2619 | __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */ | 2706 | __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */ |
@@ -2729,76 +2816,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2729 | pkt_dev->pkt_overhead); | 2816 | pkt_dev->pkt_overhead); |
2730 | skb->dev = odev; | 2817 | skb->dev = odev; |
2731 | skb->pkt_type = PACKET_HOST; | 2818 | skb->pkt_type = PACKET_HOST; |
2732 | 2819 | pktgen_finalize_skb(pkt_dev, skb, datalen); | |
2733 | if (pkt_dev->nfrags <= 0) { | ||
2734 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); | ||
2735 | memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr)); | ||
2736 | } else { | ||
2737 | int frags = pkt_dev->nfrags; | ||
2738 | int i, len; | ||
2739 | |||
2740 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); | ||
2741 | |||
2742 | if (frags > MAX_SKB_FRAGS) | ||
2743 | frags = MAX_SKB_FRAGS; | ||
2744 | if (datalen > frags * PAGE_SIZE) { | ||
2745 | len = datalen - frags * PAGE_SIZE; | ||
2746 | memset(skb_put(skb, len), 0, len); | ||
2747 | datalen = frags * PAGE_SIZE; | ||
2748 | } | ||
2749 | |||
2750 | i = 0; | ||
2751 | while (datalen > 0) { | ||
2752 | struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); | ||
2753 | skb_shinfo(skb)->frags[i].page = page; | ||
2754 | skb_shinfo(skb)->frags[i].page_offset = 0; | ||
2755 | skb_shinfo(skb)->frags[i].size = | ||
2756 | (datalen < PAGE_SIZE ? datalen : PAGE_SIZE); | ||
2757 | datalen -= skb_shinfo(skb)->frags[i].size; | ||
2758 | skb->len += skb_shinfo(skb)->frags[i].size; | ||
2759 | skb->data_len += skb_shinfo(skb)->frags[i].size; | ||
2760 | i++; | ||
2761 | skb_shinfo(skb)->nr_frags = i; | ||
2762 | } | ||
2763 | |||
2764 | while (i < frags) { | ||
2765 | int rem; | ||
2766 | |||
2767 | if (i == 0) | ||
2768 | break; | ||
2769 | |||
2770 | rem = skb_shinfo(skb)->frags[i - 1].size / 2; | ||
2771 | if (rem == 0) | ||
2772 | break; | ||
2773 | |||
2774 | skb_shinfo(skb)->frags[i - 1].size -= rem; | ||
2775 | |||
2776 | skb_shinfo(skb)->frags[i] = | ||
2777 | skb_shinfo(skb)->frags[i - 1]; | ||
2778 | get_page(skb_shinfo(skb)->frags[i].page); | ||
2779 | skb_shinfo(skb)->frags[i].page = | ||
2780 | skb_shinfo(skb)->frags[i - 1].page; | ||
2781 | skb_shinfo(skb)->frags[i].page_offset += | ||
2782 | skb_shinfo(skb)->frags[i - 1].size; | ||
2783 | skb_shinfo(skb)->frags[i].size = rem; | ||
2784 | i++; | ||
2785 | skb_shinfo(skb)->nr_frags = i; | ||
2786 | } | ||
2787 | } | ||
2788 | |||
2789 | /* Stamp the time, and sequence number, | ||
2790 | * convert them to network byte order | ||
2791 | */ | ||
2792 | if (pgh) { | ||
2793 | struct timeval timestamp; | ||
2794 | |||
2795 | pgh->pgh_magic = htonl(PKTGEN_MAGIC); | ||
2796 | pgh->seq_num = htonl(pkt_dev->seq_num); | ||
2797 | |||
2798 | do_gettimeofday(×tamp); | ||
2799 | pgh->tv_sec = htonl(timestamp.tv_sec); | ||
2800 | pgh->tv_usec = htonl(timestamp.tv_usec); | ||
2801 | } | ||
2802 | 2820 | ||
2803 | #ifdef CONFIG_XFRM | 2821 | #ifdef CONFIG_XFRM |
2804 | if (!process_ipsec(pkt_dev, skb, protocol)) | 2822 | if (!process_ipsec(pkt_dev, skb, protocol)) |
@@ -2980,7 +2998,6 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2980 | struct udphdr *udph; | 2998 | struct udphdr *udph; |
2981 | int datalen; | 2999 | int datalen; |
2982 | struct ipv6hdr *iph; | 3000 | struct ipv6hdr *iph; |
2983 | struct pktgen_hdr *pgh = NULL; | ||
2984 | __be16 protocol = htons(ETH_P_IPV6); | 3001 | __be16 protocol = htons(ETH_P_IPV6); |
2985 | __be32 *mpls; | 3002 | __be32 *mpls; |
2986 | __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */ | 3003 | __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */ |
@@ -3083,75 +3100,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
3083 | skb->dev = odev; | 3100 | skb->dev = odev; |
3084 | skb->pkt_type = PACKET_HOST; | 3101 | skb->pkt_type = PACKET_HOST; |
3085 | 3102 | ||
3086 | if (pkt_dev->nfrags <= 0) | 3103 | pktgen_finalize_skb(pkt_dev, skb, datalen); |
3087 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); | ||
3088 | else { | ||
3089 | int frags = pkt_dev->nfrags; | ||
3090 | int i; | ||
3091 | |||
3092 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); | ||
3093 | |||
3094 | if (frags > MAX_SKB_FRAGS) | ||
3095 | frags = MAX_SKB_FRAGS; | ||
3096 | if (datalen > frags * PAGE_SIZE) { | ||
3097 | skb_put(skb, datalen - frags * PAGE_SIZE); | ||
3098 | datalen = frags * PAGE_SIZE; | ||
3099 | } | ||
3100 | |||
3101 | i = 0; | ||
3102 | while (datalen > 0) { | ||
3103 | struct page *page = alloc_pages(GFP_KERNEL, 0); | ||
3104 | skb_shinfo(skb)->frags[i].page = page; | ||
3105 | skb_shinfo(skb)->frags[i].page_offset = 0; | ||
3106 | skb_shinfo(skb)->frags[i].size = | ||
3107 | (datalen < PAGE_SIZE ? datalen : PAGE_SIZE); | ||
3108 | datalen -= skb_shinfo(skb)->frags[i].size; | ||
3109 | skb->len += skb_shinfo(skb)->frags[i].size; | ||
3110 | skb->data_len += skb_shinfo(skb)->frags[i].size; | ||
3111 | i++; | ||
3112 | skb_shinfo(skb)->nr_frags = i; | ||
3113 | } | ||
3114 | |||
3115 | while (i < frags) { | ||
3116 | int rem; | ||
3117 | |||
3118 | if (i == 0) | ||
3119 | break; | ||
3120 | |||
3121 | rem = skb_shinfo(skb)->frags[i - 1].size / 2; | ||
3122 | if (rem == 0) | ||
3123 | break; | ||
3124 | |||
3125 | skb_shinfo(skb)->frags[i - 1].size -= rem; | ||
3126 | |||
3127 | skb_shinfo(skb)->frags[i] = | ||
3128 | skb_shinfo(skb)->frags[i - 1]; | ||
3129 | get_page(skb_shinfo(skb)->frags[i].page); | ||
3130 | skb_shinfo(skb)->frags[i].page = | ||
3131 | skb_shinfo(skb)->frags[i - 1].page; | ||
3132 | skb_shinfo(skb)->frags[i].page_offset += | ||
3133 | skb_shinfo(skb)->frags[i - 1].size; | ||
3134 | skb_shinfo(skb)->frags[i].size = rem; | ||
3135 | i++; | ||
3136 | skb_shinfo(skb)->nr_frags = i; | ||
3137 | } | ||
3138 | } | ||
3139 | |||
3140 | /* Stamp the time, and sequence number, | ||
3141 | * convert them to network byte order | ||
3142 | * should we update cloned packets too ? | ||
3143 | */ | ||
3144 | if (pgh) { | ||
3145 | struct timeval timestamp; | ||
3146 | |||
3147 | pgh->pgh_magic = htonl(PKTGEN_MAGIC); | ||
3148 | pgh->seq_num = htonl(pkt_dev->seq_num); | ||
3149 | |||
3150 | do_gettimeofday(×tamp); | ||
3151 | pgh->tv_sec = htonl(timestamp.tv_sec); | ||
3152 | pgh->tv_usec = htonl(timestamp.tv_usec); | ||
3153 | } | ||
3154 | /* pkt_dev->seq_num++; FF: you really mean this? */ | ||
3155 | 3104 | ||
3156 | return skb; | 3105 | return skb; |
3157 | } | 3106 | } |
@@ -3884,6 +3833,8 @@ static int pktgen_remove_device(struct pktgen_thread *t, | |||
3884 | free_SAs(pkt_dev); | 3833 | free_SAs(pkt_dev); |
3885 | #endif | 3834 | #endif |
3886 | vfree(pkt_dev->flows); | 3835 | vfree(pkt_dev->flows); |
3836 | if (pkt_dev->page) | ||
3837 | put_page(pkt_dev->page); | ||
3887 | kfree(pkt_dev); | 3838 | kfree(pkt_dev); |
3888 | return 0; | 3839 | return 0; |
3889 | } | 3840 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 2d65c6bb24c1..49f7ea5b4c75 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -868,6 +868,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
868 | netif_running(dev) ? dev->operstate : IF_OPER_DOWN); | 868 | netif_running(dev) ? dev->operstate : IF_OPER_DOWN); |
869 | NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode); | 869 | NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode); |
870 | NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); | 870 | NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); |
871 | NLA_PUT_U32(skb, IFLA_GROUP, dev->group); | ||
871 | 872 | ||
872 | if (dev->ifindex != dev->iflink) | 873 | if (dev->ifindex != dev->iflink) |
873 | NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); | 874 | NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); |
@@ -1035,6 +1036,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
1035 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | 1036 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, |
1036 | [IFLA_MTU] = { .type = NLA_U32 }, | 1037 | [IFLA_MTU] = { .type = NLA_U32 }, |
1037 | [IFLA_LINK] = { .type = NLA_U32 }, | 1038 | [IFLA_LINK] = { .type = NLA_U32 }, |
1039 | [IFLA_MASTER] = { .type = NLA_U32 }, | ||
1038 | [IFLA_TXQLEN] = { .type = NLA_U32 }, | 1040 | [IFLA_TXQLEN] = { .type = NLA_U32 }, |
1039 | [IFLA_WEIGHT] = { .type = NLA_U32 }, | 1041 | [IFLA_WEIGHT] = { .type = NLA_U32 }, |
1040 | [IFLA_OPERSTATE] = { .type = NLA_U8 }, | 1042 | [IFLA_OPERSTATE] = { .type = NLA_U8 }, |
@@ -1177,6 +1179,41 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) | |||
1177 | return err; | 1179 | return err; |
1178 | } | 1180 | } |
1179 | 1181 | ||
1182 | static int do_set_master(struct net_device *dev, int ifindex) | ||
1183 | { | ||
1184 | struct net_device *master_dev; | ||
1185 | const struct net_device_ops *ops; | ||
1186 | int err; | ||
1187 | |||
1188 | if (dev->master) { | ||
1189 | if (dev->master->ifindex == ifindex) | ||
1190 | return 0; | ||
1191 | ops = dev->master->netdev_ops; | ||
1192 | if (ops->ndo_del_slave) { | ||
1193 | err = ops->ndo_del_slave(dev->master, dev); | ||
1194 | if (err) | ||
1195 | return err; | ||
1196 | } else { | ||
1197 | return -EOPNOTSUPP; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | if (ifindex) { | ||
1202 | master_dev = __dev_get_by_index(dev_net(dev), ifindex); | ||
1203 | if (!master_dev) | ||
1204 | return -EINVAL; | ||
1205 | ops = master_dev->netdev_ops; | ||
1206 | if (ops->ndo_add_slave) { | ||
1207 | err = ops->ndo_add_slave(master_dev, dev); | ||
1208 | if (err) | ||
1209 | return err; | ||
1210 | } else { | ||
1211 | return -EOPNOTSUPP; | ||
1212 | } | ||
1213 | } | ||
1214 | return 0; | ||
1215 | } | ||
1216 | |||
1180 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 1217 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, |
1181 | struct nlattr **tb, char *ifname, int modified) | 1218 | struct nlattr **tb, char *ifname, int modified) |
1182 | { | 1219 | { |
@@ -1264,6 +1301,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1264 | modified = 1; | 1301 | modified = 1; |
1265 | } | 1302 | } |
1266 | 1303 | ||
1304 | if (tb[IFLA_GROUP]) { | ||
1305 | dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); | ||
1306 | modified = 1; | ||
1307 | } | ||
1308 | |||
1267 | /* | 1309 | /* |
1268 | * Interface selected by interface index but interface | 1310 | * Interface selected by interface index but interface |
1269 | * name provided implies that a name change has been | 1311 | * name provided implies that a name change has been |
@@ -1295,6 +1337,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1295 | goto errout; | 1337 | goto errout; |
1296 | } | 1338 | } |
1297 | 1339 | ||
1340 | if (tb[IFLA_MASTER]) { | ||
1341 | err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER])); | ||
1342 | if (err) | ||
1343 | goto errout; | ||
1344 | modified = 1; | ||
1345 | } | ||
1346 | |||
1298 | if (tb[IFLA_TXQLEN]) | 1347 | if (tb[IFLA_TXQLEN]) |
1299 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); | 1348 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); |
1300 | 1349 | ||
@@ -1541,6 +1590,8 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | |||
1541 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); | 1590 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); |
1542 | if (tb[IFLA_LINKMODE]) | 1591 | if (tb[IFLA_LINKMODE]) |
1543 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); | 1592 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); |
1593 | if (tb[IFLA_GROUP]) | ||
1594 | dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); | ||
1544 | 1595 | ||
1545 | return dev; | 1596 | return dev; |
1546 | 1597 | ||
@@ -1551,6 +1602,24 @@ err: | |||
1551 | } | 1602 | } |
1552 | EXPORT_SYMBOL(rtnl_create_link); | 1603 | EXPORT_SYMBOL(rtnl_create_link); |
1553 | 1604 | ||
1605 | static int rtnl_group_changelink(struct net *net, int group, | ||
1606 | struct ifinfomsg *ifm, | ||
1607 | struct nlattr **tb) | ||
1608 | { | ||
1609 | struct net_device *dev; | ||
1610 | int err; | ||
1611 | |||
1612 | for_each_netdev(net, dev) { | ||
1613 | if (dev->group == group) { | ||
1614 | err = do_setlink(dev, ifm, tb, NULL, 0); | ||
1615 | if (err < 0) | ||
1616 | return err; | ||
1617 | } | ||
1618 | } | ||
1619 | |||
1620 | return 0; | ||
1621 | } | ||
1622 | |||
1554 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1623 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
1555 | { | 1624 | { |
1556 | struct net *net = sock_net(skb->sk); | 1625 | struct net *net = sock_net(skb->sk); |
@@ -1578,10 +1647,12 @@ replay: | |||
1578 | ifm = nlmsg_data(nlh); | 1647 | ifm = nlmsg_data(nlh); |
1579 | if (ifm->ifi_index > 0) | 1648 | if (ifm->ifi_index > 0) |
1580 | dev = __dev_get_by_index(net, ifm->ifi_index); | 1649 | dev = __dev_get_by_index(net, ifm->ifi_index); |
1581 | else if (ifname[0]) | 1650 | else { |
1582 | dev = __dev_get_by_name(net, ifname); | 1651 | if (ifname[0]) |
1583 | else | 1652 | dev = __dev_get_by_name(net, ifname); |
1584 | dev = NULL; | 1653 | else |
1654 | dev = NULL; | ||
1655 | } | ||
1585 | 1656 | ||
1586 | err = validate_linkmsg(dev, tb); | 1657 | err = validate_linkmsg(dev, tb); |
1587 | if (err < 0) | 1658 | if (err < 0) |
@@ -1645,8 +1716,13 @@ replay: | |||
1645 | return do_setlink(dev, ifm, tb, ifname, modified); | 1716 | return do_setlink(dev, ifm, tb, ifname, modified); |
1646 | } | 1717 | } |
1647 | 1718 | ||
1648 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) | 1719 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
1720 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | ||
1721 | return rtnl_group_changelink(net, | ||
1722 | nla_get_u32(tb[IFLA_GROUP]), | ||
1723 | ifm, tb); | ||
1649 | return -ENODEV; | 1724 | return -ENODEV; |
1725 | } | ||
1650 | 1726 | ||
1651 | if (ifm->ifi_index) | 1727 | if (ifm->ifi_index) |
1652 | return -EOPNOTSUPP; | 1728 | return -EOPNOTSUPP; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d883dcc78b6b..801dd08908f9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -523,7 +523,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
523 | new->ip_summed = old->ip_summed; | 523 | new->ip_summed = old->ip_summed; |
524 | skb_copy_queue_mapping(new, old); | 524 | skb_copy_queue_mapping(new, old); |
525 | new->priority = old->priority; | 525 | new->priority = old->priority; |
526 | new->deliver_no_wcard = old->deliver_no_wcard; | ||
527 | #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) | 526 | #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) |
528 | new->ipvs_property = old->ipvs_property; | 527 | new->ipvs_property = old->ipvs_property; |
529 | #endif | 528 | #endif |
@@ -2434,8 +2433,6 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | |||
2434 | return -ENOMEM; | 2433 | return -ENOMEM; |
2435 | 2434 | ||
2436 | /* initialize the next frag */ | 2435 | /* initialize the next frag */ |
2437 | sk->sk_sndmsg_page = page; | ||
2438 | sk->sk_sndmsg_off = 0; | ||
2439 | skb_fill_page_desc(skb, frg_cnt, page, 0, 0); | 2436 | skb_fill_page_desc(skb, frg_cnt, page, 0, 0); |
2440 | skb->truesize += PAGE_SIZE; | 2437 | skb->truesize += PAGE_SIZE; |
2441 | atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); | 2438 | atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc); |
@@ -2455,7 +2452,6 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | |||
2455 | return -EFAULT; | 2452 | return -EFAULT; |
2456 | 2453 | ||
2457 | /* copy was successful so update the size parameters */ | 2454 | /* copy was successful so update the size parameters */ |
2458 | sk->sk_sndmsg_off += copy; | ||
2459 | frag->size += copy; | 2455 | frag->size += copy; |
2460 | skb->len += copy; | 2456 | skb->len += copy; |
2461 | skb->data_len += copy; | 2457 | skb->data_len += copy; |
@@ -2498,7 +2494,7 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum); | |||
2498 | * a pointer to the first in a list of new skbs for the segments. | 2494 | * a pointer to the first in a list of new skbs for the segments. |
2499 | * In case of error it returns ERR_PTR(err). | 2495 | * In case of error it returns ERR_PTR(err). |
2500 | */ | 2496 | */ |
2501 | struct sk_buff *skb_segment(struct sk_buff *skb, int features) | 2497 | struct sk_buff *skb_segment(struct sk_buff *skb, u32 features) |
2502 | { | 2498 | { |
2503 | struct sk_buff *segs = NULL; | 2499 | struct sk_buff *segs = NULL; |
2504 | struct sk_buff *tail = NULL; | 2500 | struct sk_buff *tail = NULL; |
@@ -2508,7 +2504,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2508 | unsigned int offset = doffset; | 2504 | unsigned int offset = doffset; |
2509 | unsigned int headroom; | 2505 | unsigned int headroom; |
2510 | unsigned int len; | 2506 | unsigned int len; |
2511 | int sg = features & NETIF_F_SG; | 2507 | int sg = !!(features & NETIF_F_SG); |
2512 | int nfrags = skb_shinfo(skb)->nr_frags; | 2508 | int nfrags = skb_shinfo(skb)->nr_frags; |
2513 | int err = -ENOMEM; | 2509 | int err = -ENOMEM; |
2514 | int i = 0; | 2510 | int i = 0; |