diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/Makefile | 2 | ||||
-rw-r--r-- | net/core/datagram.c | 8 | ||||
-rw-r--r-- | net/core/dev.c | 408 | ||||
-rw-r--r-- | net/core/drop_monitor.c | 33 | ||||
-rw-r--r-- | net/core/dst.c | 2 | ||||
-rw-r--r-- | net/core/ethtool.c | 108 | ||||
-rw-r--r-- | net/core/filter.c | 212 | ||||
-rw-r--r-- | net/core/flow.c | 9 | ||||
-rw-r--r-- | net/core/gen_estimator.c | 1 | ||||
-rw-r--r-- | net/core/gen_stats.c | 14 | ||||
-rw-r--r-- | net/core/iovec.c | 9 | ||||
-rw-r--r-- | net/core/link_watch.c | 1 | ||||
-rw-r--r-- | net/core/neighbour.c | 5 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 19 | ||||
-rw-r--r-- | net/core/netevent.c | 5 | ||||
-rw-r--r-- | net/core/netpoll.c | 182 | ||||
-rw-r--r-- | net/core/pktgen.c | 212 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 11 | ||||
-rw-r--r-- | net/core/scm.c | 33 | ||||
-rw-r--r-- | net/core/skbuff.c | 10 | ||||
-rw-r--r-- | net/core/sock.c | 49 | ||||
-rw-r--r-- | net/core/stream.c | 6 | ||||
-rw-r--r-- | net/core/timestamping.c | 126 | ||||
-rw-r--r-- | net/core/utils.c | 3 |
24 files changed, 974 insertions, 494 deletions
diff --git a/net/core/Makefile b/net/core/Makefile index 51c3eec850ef..8a04dd22cf77 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -18,4 +18,4 @@ obj-$(CONFIG_NET_DMA) += user_dma.o | |||
18 | obj-$(CONFIG_FIB_RULES) += fib_rules.o | 18 | obj-$(CONFIG_FIB_RULES) += fib_rules.o |
19 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o | 19 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o |
20 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o | 20 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o |
21 | 21 | obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o | |
diff --git a/net/core/datagram.c b/net/core/datagram.c index f5b6f43a4c2e..251997a95483 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -219,6 +219,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, | |||
219 | return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), | 219 | return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
220 | &peeked, err); | 220 | &peeked, err); |
221 | } | 221 | } |
222 | EXPORT_SYMBOL(skb_recv_datagram); | ||
222 | 223 | ||
223 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | 224 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb) |
224 | { | 225 | { |
@@ -288,7 +289,6 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) | |||
288 | 289 | ||
289 | return err; | 290 | return err; |
290 | } | 291 | } |
291 | |||
292 | EXPORT_SYMBOL(skb_kill_datagram); | 292 | EXPORT_SYMBOL(skb_kill_datagram); |
293 | 293 | ||
294 | /** | 294 | /** |
@@ -373,6 +373,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
373 | fault: | 373 | fault: |
374 | return -EFAULT; | 374 | return -EFAULT; |
375 | } | 375 | } |
376 | EXPORT_SYMBOL(skb_copy_datagram_iovec); | ||
376 | 377 | ||
377 | /** | 378 | /** |
378 | * skb_copy_datagram_const_iovec - Copy a datagram to an iovec. | 379 | * skb_copy_datagram_const_iovec - Copy a datagram to an iovec. |
@@ -716,6 +717,7 @@ csum_error: | |||
716 | fault: | 717 | fault: |
717 | return -EFAULT; | 718 | return -EFAULT; |
718 | } | 719 | } |
720 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); | ||
719 | 721 | ||
720 | /** | 722 | /** |
721 | * datagram_poll - generic datagram poll | 723 | * datagram_poll - generic datagram poll |
@@ -770,8 +772,4 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
770 | 772 | ||
771 | return mask; | 773 | return mask; |
772 | } | 774 | } |
773 | |||
774 | EXPORT_SYMBOL(datagram_poll); | 775 | EXPORT_SYMBOL(datagram_poll); |
775 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); | ||
776 | EXPORT_SYMBOL(skb_copy_datagram_iovec); | ||
777 | EXPORT_SYMBOL(skb_recv_datagram); | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 723a34710ad4..e1c1cdcc2bb0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -101,8 +101,6 @@ | |||
101 | #include <linux/proc_fs.h> | 101 | #include <linux/proc_fs.h> |
102 | #include <linux/seq_file.h> | 102 | #include <linux/seq_file.h> |
103 | #include <linux/stat.h> | 103 | #include <linux/stat.h> |
104 | #include <linux/if_bridge.h> | ||
105 | #include <linux/if_macvlan.h> | ||
106 | #include <net/dst.h> | 104 | #include <net/dst.h> |
107 | #include <net/pkt_sched.h> | 105 | #include <net/pkt_sched.h> |
108 | #include <net/checksum.h> | 106 | #include <net/checksum.h> |
@@ -803,35 +801,31 @@ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type) | |||
803 | EXPORT_SYMBOL(dev_getfirstbyhwtype); | 801 | EXPORT_SYMBOL(dev_getfirstbyhwtype); |
804 | 802 | ||
805 | /** | 803 | /** |
806 | * dev_get_by_flags - find any device with given flags | 804 | * dev_get_by_flags_rcu - find any device with given flags |
807 | * @net: the applicable net namespace | 805 | * @net: the applicable net namespace |
808 | * @if_flags: IFF_* values | 806 | * @if_flags: IFF_* values |
809 | * @mask: bitmask of bits in if_flags to check | 807 | * @mask: bitmask of bits in if_flags to check |
810 | * | 808 | * |
811 | * Search for any interface with the given flags. Returns NULL if a device | 809 | * Search for any interface with the given flags. Returns NULL if a device |
812 | * is not found or a pointer to the device. The device returned has | 810 | * is not found or a pointer to the device. Must be called inside |
813 | * had a reference added and the pointer is safe until the user calls | 811 | * rcu_read_lock(), and result refcount is unchanged. |
814 | * dev_put to indicate they have finished with it. | ||
815 | */ | 812 | */ |
816 | 813 | ||
817 | struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags, | 814 | struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short if_flags, |
818 | unsigned short mask) | 815 | unsigned short mask) |
819 | { | 816 | { |
820 | struct net_device *dev, *ret; | 817 | struct net_device *dev, *ret; |
821 | 818 | ||
822 | ret = NULL; | 819 | ret = NULL; |
823 | rcu_read_lock(); | ||
824 | for_each_netdev_rcu(net, dev) { | 820 | for_each_netdev_rcu(net, dev) { |
825 | if (((dev->flags ^ if_flags) & mask) == 0) { | 821 | if (((dev->flags ^ if_flags) & mask) == 0) { |
826 | dev_hold(dev); | ||
827 | ret = dev; | 822 | ret = dev; |
828 | break; | 823 | break; |
829 | } | 824 | } |
830 | } | 825 | } |
831 | rcu_read_unlock(); | ||
832 | return ret; | 826 | return ret; |
833 | } | 827 | } |
834 | EXPORT_SYMBOL(dev_get_by_flags); | 828 | EXPORT_SYMBOL(dev_get_by_flags_rcu); |
835 | 829 | ||
836 | /** | 830 | /** |
837 | * dev_valid_name - check if name is okay for network device | 831 | * dev_valid_name - check if name is okay for network device |
@@ -1488,6 +1482,7 @@ static inline void net_timestamp_check(struct sk_buff *skb) | |||
1488 | int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | 1482 | int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) |
1489 | { | 1483 | { |
1490 | skb_orphan(skb); | 1484 | skb_orphan(skb); |
1485 | nf_reset(skb); | ||
1491 | 1486 | ||
1492 | if (!(dev->flags & IFF_UP) || | 1487 | if (!(dev->flags & IFF_UP) || |
1493 | (skb->len > (dev->mtu + dev->hard_header_len))) { | 1488 | (skb->len > (dev->mtu + dev->hard_header_len))) { |
@@ -1541,7 +1536,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1541 | if (net_ratelimit()) | 1536 | if (net_ratelimit()) |
1542 | printk(KERN_CRIT "protocol %04x is " | 1537 | printk(KERN_CRIT "protocol %04x is " |
1543 | "buggy, dev %s\n", | 1538 | "buggy, dev %s\n", |
1544 | skb2->protocol, dev->name); | 1539 | ntohs(skb2->protocol), |
1540 | dev->name); | ||
1545 | skb_reset_network_header(skb2); | 1541 | skb_reset_network_header(skb2); |
1546 | } | 1542 | } |
1547 | 1543 | ||
@@ -1911,8 +1907,32 @@ static int dev_gso_segment(struct sk_buff *skb) | |||
1911 | */ | 1907 | */ |
1912 | static inline void skb_orphan_try(struct sk_buff *skb) | 1908 | static inline void skb_orphan_try(struct sk_buff *skb) |
1913 | { | 1909 | { |
1914 | if (!skb_tx(skb)->flags) | 1910 | struct sock *sk = skb->sk; |
1911 | |||
1912 | if (sk && !skb_tx(skb)->flags) { | ||
1913 | /* skb_tx_hash() wont be able to get sk. | ||
1914 | * We copy sk_hash into skb->rxhash | ||
1915 | */ | ||
1916 | if (!skb->rxhash) | ||
1917 | skb->rxhash = sk->sk_hash; | ||
1915 | skb_orphan(skb); | 1918 | skb_orphan(skb); |
1919 | } | ||
1920 | } | ||
1921 | |||
1922 | /* | ||
1923 | * Returns true if either: | ||
1924 | * 1. skb has frag_list and the device doesn't support FRAGLIST, or | ||
1925 | * 2. skb is fragmented and the device does not support SG, or if | ||
1926 | * at least one of fragments is in highmem and device does not | ||
1927 | * support DMA from it. | ||
1928 | */ | ||
1929 | static inline int skb_needs_linearize(struct sk_buff *skb, | ||
1930 | struct net_device *dev) | ||
1931 | { | ||
1932 | return skb_is_nonlinear(skb) && | ||
1933 | ((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) || | ||
1934 | (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || | ||
1935 | illegal_highdma(dev, skb)))); | ||
1916 | } | 1936 | } |
1917 | 1937 | ||
1918 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 1938 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
@@ -1939,6 +1959,22 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
1939 | goto out_kfree_skb; | 1959 | goto out_kfree_skb; |
1940 | if (skb->next) | 1960 | if (skb->next) |
1941 | goto gso; | 1961 | goto gso; |
1962 | } else { | ||
1963 | if (skb_needs_linearize(skb, dev) && | ||
1964 | __skb_linearize(skb)) | ||
1965 | goto out_kfree_skb; | ||
1966 | |||
1967 | /* If packet is not checksummed and device does not | ||
1968 | * support checksumming for this protocol, complete | ||
1969 | * checksumming here. | ||
1970 | */ | ||
1971 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1972 | skb_set_transport_header(skb, skb->csum_start - | ||
1973 | skb_headroom(skb)); | ||
1974 | if (!dev_can_checksum(dev, skb) && | ||
1975 | skb_checksum_help(skb)) | ||
1976 | goto out_kfree_skb; | ||
1977 | } | ||
1942 | } | 1978 | } |
1943 | 1979 | ||
1944 | rc = ops->ndo_start_xmit(skb, dev); | 1980 | rc = ops->ndo_start_xmit(skb, dev); |
@@ -1998,8 +2034,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) | |||
1998 | if (skb->sk && skb->sk->sk_hash) | 2034 | if (skb->sk && skb->sk->sk_hash) |
1999 | hash = skb->sk->sk_hash; | 2035 | hash = skb->sk->sk_hash; |
2000 | else | 2036 | else |
2001 | hash = (__force u16) skb->protocol; | 2037 | hash = (__force u16) skb->protocol ^ skb->rxhash; |
2002 | |||
2003 | hash = jhash_1word(hash, hashrnd); | 2038 | hash = jhash_1word(hash, hashrnd); |
2004 | 2039 | ||
2005 | return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); | 2040 | return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); |
@@ -2022,12 +2057,11 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) | |||
2022 | static struct netdev_queue *dev_pick_tx(struct net_device *dev, | 2057 | static struct netdev_queue *dev_pick_tx(struct net_device *dev, |
2023 | struct sk_buff *skb) | 2058 | struct sk_buff *skb) |
2024 | { | 2059 | { |
2025 | u16 queue_index; | 2060 | int queue_index; |
2026 | struct sock *sk = skb->sk; | 2061 | struct sock *sk = skb->sk; |
2027 | 2062 | ||
2028 | if (sk_tx_queue_recorded(sk)) { | 2063 | queue_index = sk_tx_queue_get(sk); |
2029 | queue_index = sk_tx_queue_get(sk); | 2064 | if (queue_index < 0) { |
2030 | } else { | ||
2031 | const struct net_device_ops *ops = dev->netdev_ops; | 2065 | const struct net_device_ops *ops = dev->netdev_ops; |
2032 | 2066 | ||
2033 | if (ops->ndo_select_queue) { | 2067 | if (ops->ndo_select_queue) { |
@@ -2056,14 +2090,24 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2056 | struct netdev_queue *txq) | 2090 | struct netdev_queue *txq) |
2057 | { | 2091 | { |
2058 | spinlock_t *root_lock = qdisc_lock(q); | 2092 | spinlock_t *root_lock = qdisc_lock(q); |
2093 | bool contended = qdisc_is_running(q); | ||
2059 | int rc; | 2094 | int rc; |
2060 | 2095 | ||
2096 | /* | ||
2097 | * Heuristic to force contended enqueues to serialize on a | ||
2098 | * separate lock before trying to get qdisc main lock. | ||
2099 | * This permits __QDISC_STATE_RUNNING owner to get the lock more often | ||
2100 | * and dequeue packets faster. | ||
2101 | */ | ||
2102 | if (unlikely(contended)) | ||
2103 | spin_lock(&q->busylock); | ||
2104 | |||
2061 | spin_lock(root_lock); | 2105 | spin_lock(root_lock); |
2062 | if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) { | 2106 | if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) { |
2063 | kfree_skb(skb); | 2107 | kfree_skb(skb); |
2064 | rc = NET_XMIT_DROP; | 2108 | rc = NET_XMIT_DROP; |
2065 | } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) && | 2109 | } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) && |
2066 | !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) { | 2110 | qdisc_run_begin(q)) { |
2067 | /* | 2111 | /* |
2068 | * This is a work-conserving queue; there are no old skbs | 2112 | * This is a work-conserving queue; there are no old skbs |
2069 | * waiting to be sent out; and the qdisc is not running - | 2113 | * waiting to be sent out; and the qdisc is not running - |
@@ -2072,37 +2116,33 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2072 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) | 2116 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) |
2073 | skb_dst_force(skb); | 2117 | skb_dst_force(skb); |
2074 | __qdisc_update_bstats(q, skb->len); | 2118 | __qdisc_update_bstats(q, skb->len); |
2075 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) | 2119 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) { |
2120 | if (unlikely(contended)) { | ||
2121 | spin_unlock(&q->busylock); | ||
2122 | contended = false; | ||
2123 | } | ||
2076 | __qdisc_run(q); | 2124 | __qdisc_run(q); |
2077 | else | 2125 | } else |
2078 | clear_bit(__QDISC_STATE_RUNNING, &q->state); | 2126 | qdisc_run_end(q); |
2079 | 2127 | ||
2080 | rc = NET_XMIT_SUCCESS; | 2128 | rc = NET_XMIT_SUCCESS; |
2081 | } else { | 2129 | } else { |
2082 | skb_dst_force(skb); | 2130 | skb_dst_force(skb); |
2083 | rc = qdisc_enqueue_root(skb, q); | 2131 | rc = qdisc_enqueue_root(skb, q); |
2084 | qdisc_run(q); | 2132 | if (qdisc_run_begin(q)) { |
2133 | if (unlikely(contended)) { | ||
2134 | spin_unlock(&q->busylock); | ||
2135 | contended = false; | ||
2136 | } | ||
2137 | __qdisc_run(q); | ||
2138 | } | ||
2085 | } | 2139 | } |
2086 | spin_unlock(root_lock); | 2140 | spin_unlock(root_lock); |
2087 | 2141 | if (unlikely(contended)) | |
2142 | spin_unlock(&q->busylock); | ||
2088 | return rc; | 2143 | return rc; |
2089 | } | 2144 | } |
2090 | 2145 | ||
2091 | /* | ||
2092 | * Returns true if either: | ||
2093 | * 1. skb has frag_list and the device doesn't support FRAGLIST, or | ||
2094 | * 2. skb is fragmented and the device does not support SG, or if | ||
2095 | * at least one of fragments is in highmem and device does not | ||
2096 | * support DMA from it. | ||
2097 | */ | ||
2098 | static inline int skb_needs_linearize(struct sk_buff *skb, | ||
2099 | struct net_device *dev) | ||
2100 | { | ||
2101 | return (skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) || | ||
2102 | (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || | ||
2103 | illegal_highdma(dev, skb))); | ||
2104 | } | ||
2105 | |||
2106 | /** | 2146 | /** |
2107 | * dev_queue_xmit - transmit a buffer | 2147 | * dev_queue_xmit - transmit a buffer |
2108 | * @skb: buffer to transmit | 2148 | * @skb: buffer to transmit |
@@ -2135,25 +2175,6 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
2135 | struct Qdisc *q; | 2175 | struct Qdisc *q; |
2136 | int rc = -ENOMEM; | 2176 | int rc = -ENOMEM; |
2137 | 2177 | ||
2138 | /* GSO will handle the following emulations directly. */ | ||
2139 | if (netif_needs_gso(dev, skb)) | ||
2140 | goto gso; | ||
2141 | |||
2142 | /* Convert a paged skb to linear, if required */ | ||
2143 | if (skb_needs_linearize(skb, dev) && __skb_linearize(skb)) | ||
2144 | goto out_kfree_skb; | ||
2145 | |||
2146 | /* If packet is not checksummed and device does not support | ||
2147 | * checksumming for this protocol, complete checksumming here. | ||
2148 | */ | ||
2149 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
2150 | skb_set_transport_header(skb, skb->csum_start - | ||
2151 | skb_headroom(skb)); | ||
2152 | if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb)) | ||
2153 | goto out_kfree_skb; | ||
2154 | } | ||
2155 | |||
2156 | gso: | ||
2157 | /* Disable soft irqs for various locks below. Also | 2178 | /* Disable soft irqs for various locks below. Also |
2158 | * stops preemption for RCU. | 2179 | * stops preemption for RCU. |
2159 | */ | 2180 | */ |
@@ -2212,7 +2233,6 @@ gso: | |||
2212 | rc = -ENETDOWN; | 2233 | rc = -ENETDOWN; |
2213 | rcu_read_unlock_bh(); | 2234 | rcu_read_unlock_bh(); |
2214 | 2235 | ||
2215 | out_kfree_skb: | ||
2216 | kfree_skb(skb); | 2236 | kfree_skb(skb); |
2217 | return rc; | 2237 | return rc; |
2218 | out: | 2238 | out: |
@@ -2597,70 +2617,14 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
2597 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 2617 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
2598 | } | 2618 | } |
2599 | 2619 | ||
2600 | #if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE) | 2620 | #if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \ |
2601 | 2621 | (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)) | |
2602 | #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) | ||
2603 | /* This hook is defined here for ATM LANE */ | 2622 | /* This hook is defined here for ATM LANE */ |
2604 | int (*br_fdb_test_addr_hook)(struct net_device *dev, | 2623 | int (*br_fdb_test_addr_hook)(struct net_device *dev, |
2605 | unsigned char *addr) __read_mostly; | 2624 | unsigned char *addr) __read_mostly; |
2606 | EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); | 2625 | EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); |
2607 | #endif | 2626 | #endif |
2608 | 2627 | ||
2609 | /* | ||
2610 | * If bridge module is loaded call bridging hook. | ||
2611 | * returns NULL if packet was consumed. | ||
2612 | */ | ||
2613 | struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p, | ||
2614 | struct sk_buff *skb) __read_mostly; | ||
2615 | EXPORT_SYMBOL_GPL(br_handle_frame_hook); | ||
2616 | |||
2617 | static inline struct sk_buff *handle_bridge(struct sk_buff *skb, | ||
2618 | struct packet_type **pt_prev, int *ret, | ||
2619 | struct net_device *orig_dev) | ||
2620 | { | ||
2621 | struct net_bridge_port *port; | ||
2622 | |||
2623 | if (skb->pkt_type == PACKET_LOOPBACK || | ||
2624 | (port = rcu_dereference(skb->dev->br_port)) == NULL) | ||
2625 | return skb; | ||
2626 | |||
2627 | if (*pt_prev) { | ||
2628 | *ret = deliver_skb(skb, *pt_prev, orig_dev); | ||
2629 | *pt_prev = NULL; | ||
2630 | } | ||
2631 | |||
2632 | return br_handle_frame_hook(port, skb); | ||
2633 | } | ||
2634 | #else | ||
2635 | #define handle_bridge(skb, pt_prev, ret, orig_dev) (skb) | ||
2636 | #endif | ||
2637 | |||
2638 | #if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE) | ||
2639 | struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *p, | ||
2640 | struct sk_buff *skb) __read_mostly; | ||
2641 | EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook); | ||
2642 | |||
2643 | static inline struct sk_buff *handle_macvlan(struct sk_buff *skb, | ||
2644 | struct packet_type **pt_prev, | ||
2645 | int *ret, | ||
2646 | struct net_device *orig_dev) | ||
2647 | { | ||
2648 | struct macvlan_port *port; | ||
2649 | |||
2650 | port = rcu_dereference(skb->dev->macvlan_port); | ||
2651 | if (!port) | ||
2652 | return skb; | ||
2653 | |||
2654 | if (*pt_prev) { | ||
2655 | *ret = deliver_skb(skb, *pt_prev, orig_dev); | ||
2656 | *pt_prev = NULL; | ||
2657 | } | ||
2658 | return macvlan_handle_frame_hook(port, skb); | ||
2659 | } | ||
2660 | #else | ||
2661 | #define handle_macvlan(skb, pt_prev, ret, orig_dev) (skb) | ||
2662 | #endif | ||
2663 | |||
2664 | #ifdef CONFIG_NET_CLS_ACT | 2628 | #ifdef CONFIG_NET_CLS_ACT |
2665 | /* TODO: Maybe we should just force sch_ingress to be compiled in | 2629 | /* TODO: Maybe we should just force sch_ingress to be compiled in |
2666 | * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions | 2630 | * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions |
@@ -2678,10 +2642,10 @@ static int ing_filter(struct sk_buff *skb) | |||
2678 | int result = TC_ACT_OK; | 2642 | int result = TC_ACT_OK; |
2679 | struct Qdisc *q; | 2643 | struct Qdisc *q; |
2680 | 2644 | ||
2681 | if (MAX_RED_LOOP < ttl++) { | 2645 | if (unlikely(MAX_RED_LOOP < ttl++)) { |
2682 | printk(KERN_WARNING | 2646 | if (net_ratelimit()) |
2683 | "Redir loop detected Dropping packet (%d->%d)\n", | 2647 | pr_warning( "Redir loop detected Dropping packet (%d->%d)\n", |
2684 | skb->skb_iif, dev->ifindex); | 2648 | skb->skb_iif, dev->ifindex); |
2685 | return TC_ACT_SHOT; | 2649 | return TC_ACT_SHOT; |
2686 | } | 2650 | } |
2687 | 2651 | ||
@@ -2711,9 +2675,6 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, | |||
2711 | if (*pt_prev) { | 2675 | if (*pt_prev) { |
2712 | *ret = deliver_skb(skb, *pt_prev, orig_dev); | 2676 | *ret = deliver_skb(skb, *pt_prev, orig_dev); |
2713 | *pt_prev = NULL; | 2677 | *pt_prev = NULL; |
2714 | } else { | ||
2715 | /* Huh? Why does turning on AF_PACKET affect this? */ | ||
2716 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); | ||
2717 | } | 2678 | } |
2718 | 2679 | ||
2719 | switch (ing_filter(skb)) { | 2680 | switch (ing_filter(skb)) { |
@@ -2756,6 +2717,51 @@ void netif_nit_deliver(struct sk_buff *skb) | |||
2756 | rcu_read_unlock(); | 2717 | rcu_read_unlock(); |
2757 | } | 2718 | } |
2758 | 2719 | ||
2720 | /** | ||
2721 | * netdev_rx_handler_register - register receive handler | ||
2722 | * @dev: device to register a handler for | ||
2723 | * @rx_handler: receive handler to register | ||
2724 | * @rx_handler_data: data pointer that is used by rx handler | ||
2725 | * | ||
2726 | * Register a receive hander for a device. This handler will then be | ||
2727 | * called from __netif_receive_skb. A negative errno code is returned | ||
2728 | * on a failure. | ||
2729 | * | ||
2730 | * The caller must hold the rtnl_mutex. | ||
2731 | */ | ||
2732 | int netdev_rx_handler_register(struct net_device *dev, | ||
2733 | rx_handler_func_t *rx_handler, | ||
2734 | void *rx_handler_data) | ||
2735 | { | ||
2736 | ASSERT_RTNL(); | ||
2737 | |||
2738 | if (dev->rx_handler) | ||
2739 | return -EBUSY; | ||
2740 | |||
2741 | rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); | ||
2742 | rcu_assign_pointer(dev->rx_handler, rx_handler); | ||
2743 | |||
2744 | return 0; | ||
2745 | } | ||
2746 | EXPORT_SYMBOL_GPL(netdev_rx_handler_register); | ||
2747 | |||
2748 | /** | ||
2749 | * netdev_rx_handler_unregister - unregister receive handler | ||
2750 | * @dev: device to unregister a handler from | ||
2751 | * | ||
2752 | * Unregister a receive hander from a device. | ||
2753 | * | ||
2754 | * The caller must hold the rtnl_mutex. | ||
2755 | */ | ||
2756 | void netdev_rx_handler_unregister(struct net_device *dev) | ||
2757 | { | ||
2758 | |||
2759 | ASSERT_RTNL(); | ||
2760 | rcu_assign_pointer(dev->rx_handler, NULL); | ||
2761 | rcu_assign_pointer(dev->rx_handler_data, NULL); | ||
2762 | } | ||
2763 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); | ||
2764 | |||
2759 | static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, | 2765 | static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, |
2760 | struct net_device *master) | 2766 | struct net_device *master) |
2761 | { | 2767 | { |
@@ -2777,7 +2783,8 @@ int __skb_bond_should_drop(struct sk_buff *skb, struct net_device *master) | |||
2777 | if (master->priv_flags & IFF_MASTER_ARPMON) | 2783 | if (master->priv_flags & IFF_MASTER_ARPMON) |
2778 | dev->last_rx = jiffies; | 2784 | dev->last_rx = jiffies; |
2779 | 2785 | ||
2780 | if ((master->priv_flags & IFF_MASTER_ALB) && master->br_port) { | 2786 | if ((master->priv_flags & IFF_MASTER_ALB) && |
2787 | (master->priv_flags & IFF_BRIDGE_PORT)) { | ||
2781 | /* Do address unmangle. The local destination address | 2788 | /* Do address unmangle. The local destination address |
2782 | * will be always the one master has. Provides the right | 2789 | * will be always the one master has. Provides the right |
2783 | * functionality in a bridge. | 2790 | * functionality in a bridge. |
@@ -2808,6 +2815,7 @@ EXPORT_SYMBOL(__skb_bond_should_drop); | |||
2808 | static int __netif_receive_skb(struct sk_buff *skb) | 2815 | static int __netif_receive_skb(struct sk_buff *skb) |
2809 | { | 2816 | { |
2810 | struct packet_type *ptype, *pt_prev; | 2817 | struct packet_type *ptype, *pt_prev; |
2818 | rx_handler_func_t *rx_handler; | ||
2811 | struct net_device *orig_dev; | 2819 | struct net_device *orig_dev; |
2812 | struct net_device *master; | 2820 | struct net_device *master; |
2813 | struct net_device *null_or_orig; | 2821 | struct net_device *null_or_orig; |
@@ -2849,8 +2857,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2849 | skb->dev = master; | 2857 | skb->dev = master; |
2850 | } | 2858 | } |
2851 | 2859 | ||
2852 | __get_cpu_var(softnet_data).processed++; | 2860 | __this_cpu_inc(softnet_data.processed); |
2853 | |||
2854 | skb_reset_network_header(skb); | 2861 | skb_reset_network_header(skb); |
2855 | skb_reset_transport_header(skb); | 2862 | skb_reset_transport_header(skb); |
2856 | skb->mac_len = skb->network_header - skb->mac_header; | 2863 | skb->mac_len = skb->network_header - skb->mac_header; |
@@ -2882,12 +2889,17 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2882 | ncls: | 2889 | ncls: |
2883 | #endif | 2890 | #endif |
2884 | 2891 | ||
2885 | skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); | 2892 | /* Handle special case of bridge or macvlan */ |
2886 | if (!skb) | 2893 | rx_handler = rcu_dereference(skb->dev->rx_handler); |
2887 | goto out; | 2894 | if (rx_handler) { |
2888 | skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev); | 2895 | if (pt_prev) { |
2889 | if (!skb) | 2896 | ret = deliver_skb(skb, pt_prev, orig_dev); |
2890 | goto out; | 2897 | pt_prev = NULL; |
2898 | } | ||
2899 | skb = rx_handler(skb); | ||
2900 | if (!skb) | ||
2901 | goto out; | ||
2902 | } | ||
2891 | 2903 | ||
2892 | /* | 2904 | /* |
2893 | * Make sure frames received on VLAN interfaces stacked on | 2905 | * Make sure frames received on VLAN interfaces stacked on |
@@ -2948,6 +2960,9 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2948 | if (netdev_tstamp_prequeue) | 2960 | if (netdev_tstamp_prequeue) |
2949 | net_timestamp_check(skb); | 2961 | net_timestamp_check(skb); |
2950 | 2962 | ||
2963 | if (skb_defer_rx_timestamp(skb)) | ||
2964 | return NET_RX_SUCCESS; | ||
2965 | |||
2951 | #ifdef CONFIG_RPS | 2966 | #ifdef CONFIG_RPS |
2952 | { | 2967 | { |
2953 | struct rps_dev_flow voidflow, *rflow = &voidflow; | 2968 | struct rps_dev_flow voidflow, *rflow = &voidflow; |
@@ -3712,10 +3727,11 @@ void dev_seq_stop(struct seq_file *seq, void *v) | |||
3712 | 3727 | ||
3713 | static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) | 3728 | static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) |
3714 | { | 3729 | { |
3715 | const struct net_device_stats *stats = dev_get_stats(dev); | 3730 | struct rtnl_link_stats64 temp; |
3731 | const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp); | ||
3716 | 3732 | ||
3717 | seq_printf(seq, "%6s: %7lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " | 3733 | seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu " |
3718 | "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", | 3734 | "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n", |
3719 | dev->name, stats->rx_bytes, stats->rx_packets, | 3735 | dev->name, stats->rx_bytes, stats->rx_packets, |
3720 | stats->rx_errors, | 3736 | stats->rx_errors, |
3721 | stats->rx_dropped + stats->rx_missed_errors, | 3737 | stats->rx_dropped + stats->rx_missed_errors, |
@@ -5264,20 +5280,22 @@ void netdev_run_todo(void) | |||
5264 | /** | 5280 | /** |
5265 | * dev_txq_stats_fold - fold tx_queues stats | 5281 | * dev_txq_stats_fold - fold tx_queues stats |
5266 | * @dev: device to get statistics from | 5282 | * @dev: device to get statistics from |
5267 | * @stats: struct net_device_stats to hold results | 5283 | * @stats: struct rtnl_link_stats64 to hold results |
5268 | */ | 5284 | */ |
5269 | void dev_txq_stats_fold(const struct net_device *dev, | 5285 | void dev_txq_stats_fold(const struct net_device *dev, |
5270 | struct net_device_stats *stats) | 5286 | struct rtnl_link_stats64 *stats) |
5271 | { | 5287 | { |
5272 | unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0; | 5288 | u64 tx_bytes = 0, tx_packets = 0, tx_dropped = 0; |
5273 | unsigned int i; | 5289 | unsigned int i; |
5274 | struct netdev_queue *txq; | 5290 | struct netdev_queue *txq; |
5275 | 5291 | ||
5276 | for (i = 0; i < dev->num_tx_queues; i++) { | 5292 | for (i = 0; i < dev->num_tx_queues; i++) { |
5277 | txq = netdev_get_tx_queue(dev, i); | 5293 | txq = netdev_get_tx_queue(dev, i); |
5294 | spin_lock_bh(&txq->_xmit_lock); | ||
5278 | tx_bytes += txq->tx_bytes; | 5295 | tx_bytes += txq->tx_bytes; |
5279 | tx_packets += txq->tx_packets; | 5296 | tx_packets += txq->tx_packets; |
5280 | tx_dropped += txq->tx_dropped; | 5297 | tx_dropped += txq->tx_dropped; |
5298 | spin_unlock_bh(&txq->_xmit_lock); | ||
5281 | } | 5299 | } |
5282 | if (tx_bytes || tx_packets || tx_dropped) { | 5300 | if (tx_bytes || tx_packets || tx_dropped) { |
5283 | stats->tx_bytes = tx_bytes; | 5301 | stats->tx_bytes = tx_bytes; |
@@ -5287,23 +5305,53 @@ void dev_txq_stats_fold(const struct net_device *dev, | |||
5287 | } | 5305 | } |
5288 | EXPORT_SYMBOL(dev_txq_stats_fold); | 5306 | EXPORT_SYMBOL(dev_txq_stats_fold); |
5289 | 5307 | ||
5308 | /* Convert net_device_stats to rtnl_link_stats64. They have the same | ||
5309 | * fields in the same order, with only the type differing. | ||
5310 | */ | ||
5311 | static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, | ||
5312 | const struct net_device_stats *netdev_stats) | ||
5313 | { | ||
5314 | #if BITS_PER_LONG == 64 | ||
5315 | BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats)); | ||
5316 | memcpy(stats64, netdev_stats, sizeof(*stats64)); | ||
5317 | #else | ||
5318 | size_t i, n = sizeof(*stats64) / sizeof(u64); | ||
5319 | const unsigned long *src = (const unsigned long *)netdev_stats; | ||
5320 | u64 *dst = (u64 *)stats64; | ||
5321 | |||
5322 | BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) != | ||
5323 | sizeof(*stats64) / sizeof(u64)); | ||
5324 | for (i = 0; i < n; i++) | ||
5325 | dst[i] = src[i]; | ||
5326 | #endif | ||
5327 | } | ||
5328 | |||
5290 | /** | 5329 | /** |
5291 | * dev_get_stats - get network device statistics | 5330 | * dev_get_stats - get network device statistics |
5292 | * @dev: device to get statistics from | 5331 | * @dev: device to get statistics from |
5332 | * @storage: place to store stats | ||
5293 | * | 5333 | * |
5294 | * Get network statistics from device. The device driver may provide | 5334 | * Get network statistics from device. Return @storage. |
5295 | * its own method by setting dev->netdev_ops->get_stats; otherwise | 5335 | * The device driver may provide its own method by setting |
5296 | * the internal statistics structure is used. | 5336 | * dev->netdev_ops->get_stats64 or dev->netdev_ops->get_stats; |
5337 | * otherwise the internal statistics structure is used. | ||
5297 | */ | 5338 | */ |
5298 | const struct net_device_stats *dev_get_stats(struct net_device *dev) | 5339 | struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, |
5340 | struct rtnl_link_stats64 *storage) | ||
5299 | { | 5341 | { |
5300 | const struct net_device_ops *ops = dev->netdev_ops; | 5342 | const struct net_device_ops *ops = dev->netdev_ops; |
5301 | 5343 | ||
5302 | if (ops->ndo_get_stats) | 5344 | if (ops->ndo_get_stats64) { |
5303 | return ops->ndo_get_stats(dev); | 5345 | memset(storage, 0, sizeof(*storage)); |
5304 | 5346 | return ops->ndo_get_stats64(dev, storage); | |
5305 | dev_txq_stats_fold(dev, &dev->stats); | 5347 | } |
5306 | return &dev->stats; | 5348 | if (ops->ndo_get_stats) { |
5349 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); | ||
5350 | return storage; | ||
5351 | } | ||
5352 | netdev_stats_to_stats64(storage, &dev->stats); | ||
5353 | dev_txq_stats_fold(dev, storage); | ||
5354 | return storage; | ||
5307 | } | 5355 | } |
5308 | EXPORT_SYMBOL(dev_get_stats); | 5356 | EXPORT_SYMBOL(dev_get_stats); |
5309 | 5357 | ||
@@ -5808,6 +5856,68 @@ char *netdev_drivername(const struct net_device *dev, char *buffer, int len) | |||
5808 | return buffer; | 5856 | return buffer; |
5809 | } | 5857 | } |
5810 | 5858 | ||
5859 | static int __netdev_printk(const char *level, const struct net_device *dev, | ||
5860 | struct va_format *vaf) | ||
5861 | { | ||
5862 | int r; | ||
5863 | |||
5864 | if (dev && dev->dev.parent) | ||
5865 | r = dev_printk(level, dev->dev.parent, "%s: %pV", | ||
5866 | netdev_name(dev), vaf); | ||
5867 | else if (dev) | ||
5868 | r = printk("%s%s: %pV", level, netdev_name(dev), vaf); | ||
5869 | else | ||
5870 | r = printk("%s(NULL net_device): %pV", level, vaf); | ||
5871 | |||
5872 | return r; | ||
5873 | } | ||
5874 | |||
5875 | int netdev_printk(const char *level, const struct net_device *dev, | ||
5876 | const char *format, ...) | ||
5877 | { | ||
5878 | struct va_format vaf; | ||
5879 | va_list args; | ||
5880 | int r; | ||
5881 | |||
5882 | va_start(args, format); | ||
5883 | |||
5884 | vaf.fmt = format; | ||
5885 | vaf.va = &args; | ||
5886 | |||
5887 | r = __netdev_printk(level, dev, &vaf); | ||
5888 | va_end(args); | ||
5889 | |||
5890 | return r; | ||
5891 | } | ||
5892 | EXPORT_SYMBOL(netdev_printk); | ||
5893 | |||
5894 | #define define_netdev_printk_level(func, level) \ | ||
5895 | int func(const struct net_device *dev, const char *fmt, ...) \ | ||
5896 | { \ | ||
5897 | int r; \ | ||
5898 | struct va_format vaf; \ | ||
5899 | va_list args; \ | ||
5900 | \ | ||
5901 | va_start(args, fmt); \ | ||
5902 | \ | ||
5903 | vaf.fmt = fmt; \ | ||
5904 | vaf.va = &args; \ | ||
5905 | \ | ||
5906 | r = __netdev_printk(level, dev, &vaf); \ | ||
5907 | va_end(args); \ | ||
5908 | \ | ||
5909 | return r; \ | ||
5910 | } \ | ||
5911 | EXPORT_SYMBOL(func); | ||
5912 | |||
5913 | define_netdev_printk_level(netdev_emerg, KERN_EMERG); | ||
5914 | define_netdev_printk_level(netdev_alert, KERN_ALERT); | ||
5915 | define_netdev_printk_level(netdev_crit, KERN_CRIT); | ||
5916 | define_netdev_printk_level(netdev_err, KERN_ERR); | ||
5917 | define_netdev_printk_level(netdev_warn, KERN_WARNING); | ||
5918 | define_netdev_printk_level(netdev_notice, KERN_NOTICE); | ||
5919 | define_netdev_printk_level(netdev_info, KERN_INFO); | ||
5920 | |||
5811 | static void __net_exit netdev_exit(struct net *net) | 5921 | static void __net_exit netdev_exit(struct net *net) |
5812 | { | 5922 | { |
5813 | kfree(net->dev_name_head); | 5923 | kfree(net->dev_name_head); |
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index ad41529fb60f..36e603c78ce9 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
@@ -223,6 +223,11 @@ static int set_all_monitor_traces(int state) | |||
223 | 223 | ||
224 | spin_lock(&trace_state_lock); | 224 | spin_lock(&trace_state_lock); |
225 | 225 | ||
226 | if (state == trace_state) { | ||
227 | rc = -EAGAIN; | ||
228 | goto out_unlock; | ||
229 | } | ||
230 | |||
226 | switch (state) { | 231 | switch (state) { |
227 | case TRACE_ON: | 232 | case TRACE_ON: |
228 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL); | 233 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL); |
@@ -251,11 +256,12 @@ static int set_all_monitor_traces(int state) | |||
251 | 256 | ||
252 | if (!rc) | 257 | if (!rc) |
253 | trace_state = state; | 258 | trace_state = state; |
259 | else | ||
260 | rc = -EINPROGRESS; | ||
254 | 261 | ||
262 | out_unlock: | ||
255 | spin_unlock(&trace_state_lock); | 263 | spin_unlock(&trace_state_lock); |
256 | 264 | ||
257 | if (rc) | ||
258 | return -EINPROGRESS; | ||
259 | return rc; | 265 | return rc; |
260 | } | 266 | } |
261 | 267 | ||
@@ -341,9 +347,9 @@ static struct notifier_block dropmon_net_notifier = { | |||
341 | 347 | ||
342 | static int __init init_net_drop_monitor(void) | 348 | static int __init init_net_drop_monitor(void) |
343 | { | 349 | { |
344 | int cpu; | ||
345 | int rc, i, ret; | ||
346 | struct per_cpu_dm_data *data; | 350 | struct per_cpu_dm_data *data; |
351 | int cpu, rc; | ||
352 | |||
347 | printk(KERN_INFO "Initalizing network drop monitor service\n"); | 353 | printk(KERN_INFO "Initalizing network drop monitor service\n"); |
348 | 354 | ||
349 | if (sizeof(void *) > 8) { | 355 | if (sizeof(void *) > 8) { |
@@ -351,21 +357,12 @@ static int __init init_net_drop_monitor(void) | |||
351 | return -ENOSPC; | 357 | return -ENOSPC; |
352 | } | 358 | } |
353 | 359 | ||
354 | if (genl_register_family(&net_drop_monitor_family) < 0) { | 360 | rc = genl_register_family_with_ops(&net_drop_monitor_family, |
361 | dropmon_ops, | ||
362 | ARRAY_SIZE(dropmon_ops)); | ||
363 | if (rc) { | ||
355 | printk(KERN_ERR "Could not create drop monitor netlink family\n"); | 364 | printk(KERN_ERR "Could not create drop monitor netlink family\n"); |
356 | return -EFAULT; | 365 | return rc; |
357 | } | ||
358 | |||
359 | rc = -EFAULT; | ||
360 | |||
361 | for (i = 0; i < ARRAY_SIZE(dropmon_ops); i++) { | ||
362 | ret = genl_register_ops(&net_drop_monitor_family, | ||
363 | &dropmon_ops[i]); | ||
364 | if (ret) { | ||
365 | printk(KERN_CRIT "Failed to register operation %d\n", | ||
366 | dropmon_ops[i].cmd); | ||
367 | goto out_unreg; | ||
368 | } | ||
369 | } | 366 | } |
370 | 367 | ||
371 | rc = register_netdevice_notifier(&dropmon_net_notifier); | 368 | rc = register_netdevice_notifier(&dropmon_net_notifier); |
diff --git a/net/core/dst.c b/net/core/dst.c index 9920722cc82b..6c41b1fac3db 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -197,7 +197,6 @@ static void ___dst_free(struct dst_entry *dst) | |||
197 | dst->input = dst->output = dst_discard; | 197 | dst->input = dst->output = dst_discard; |
198 | dst->obsolete = 2; | 198 | dst->obsolete = 2; |
199 | } | 199 | } |
200 | EXPORT_SYMBOL(__dst_free); | ||
201 | 200 | ||
202 | void __dst_free(struct dst_entry *dst) | 201 | void __dst_free(struct dst_entry *dst) |
203 | { | 202 | { |
@@ -213,6 +212,7 @@ void __dst_free(struct dst_entry *dst) | |||
213 | } | 212 | } |
214 | spin_unlock_bh(&dst_garbage.lock); | 213 | spin_unlock_bh(&dst_garbage.lock); |
215 | } | 214 | } |
215 | EXPORT_SYMBOL(__dst_free); | ||
216 | 216 | ||
217 | struct dst_entry *dst_destroy(struct dst_entry * dst) | 217 | struct dst_entry *dst_destroy(struct dst_entry * dst) |
218 | { | 218 | { |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 75e4ffeb8cc9..7a85367b3c2f 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -144,31 +144,13 @@ u32 ethtool_op_get_flags(struct net_device *dev) | |||
144 | } | 144 | } |
145 | EXPORT_SYMBOL(ethtool_op_get_flags); | 145 | EXPORT_SYMBOL(ethtool_op_get_flags); |
146 | 146 | ||
147 | int ethtool_op_set_flags(struct net_device *dev, u32 data) | 147 | int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) |
148 | { | 148 | { |
149 | const struct ethtool_ops *ops = dev->ethtool_ops; | 149 | if (data & ~supported) |
150 | unsigned long features = dev->features; | 150 | return -EINVAL; |
151 | |||
152 | if (data & ETH_FLAG_LRO) | ||
153 | features |= NETIF_F_LRO; | ||
154 | else | ||
155 | features &= ~NETIF_F_LRO; | ||
156 | |||
157 | if (data & ETH_FLAG_NTUPLE) { | ||
158 | if (!ops->set_rx_ntuple) | ||
159 | return -EOPNOTSUPP; | ||
160 | features |= NETIF_F_NTUPLE; | ||
161 | } else { | ||
162 | /* safe to clear regardless */ | ||
163 | features &= ~NETIF_F_NTUPLE; | ||
164 | } | ||
165 | |||
166 | if (data & ETH_FLAG_RXHASH) | ||
167 | features |= NETIF_F_RXHASH; | ||
168 | else | ||
169 | features &= ~NETIF_F_RXHASH; | ||
170 | 151 | ||
171 | dev->features = features; | 152 | dev->features = ((dev->features & ~flags_dup_features) | |
153 | (data & flags_dup_features)); | ||
172 | return 0; | 154 | return 0; |
173 | } | 155 | } |
174 | EXPORT_SYMBOL(ethtool_op_set_flags); | 156 | EXPORT_SYMBOL(ethtool_op_set_flags); |
@@ -395,6 +377,80 @@ err_out: | |||
395 | return ret; | 377 | return ret; |
396 | } | 378 | } |
397 | 379 | ||
380 | static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, | ||
381 | void __user *useraddr) | ||
382 | { | ||
383 | struct ethtool_rxfh_indir *indir; | ||
384 | u32 table_size; | ||
385 | size_t full_size; | ||
386 | int ret; | ||
387 | |||
388 | if (!dev->ethtool_ops->get_rxfh_indir) | ||
389 | return -EOPNOTSUPP; | ||
390 | |||
391 | if (copy_from_user(&table_size, | ||
392 | useraddr + offsetof(struct ethtool_rxfh_indir, size), | ||
393 | sizeof(table_size))) | ||
394 | return -EFAULT; | ||
395 | |||
396 | if (table_size > | ||
397 | (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index)) | ||
398 | return -ENOMEM; | ||
399 | full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size; | ||
400 | indir = kmalloc(full_size, GFP_USER); | ||
401 | if (!indir) | ||
402 | return -ENOMEM; | ||
403 | |||
404 | indir->cmd = ETHTOOL_GRXFHINDIR; | ||
405 | indir->size = table_size; | ||
406 | ret = dev->ethtool_ops->get_rxfh_indir(dev, indir); | ||
407 | if (ret) | ||
408 | goto out; | ||
409 | |||
410 | if (copy_to_user(useraddr, indir, full_size)) | ||
411 | ret = -EFAULT; | ||
412 | |||
413 | out: | ||
414 | kfree(indir); | ||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev, | ||
419 | void __user *useraddr) | ||
420 | { | ||
421 | struct ethtool_rxfh_indir *indir; | ||
422 | u32 table_size; | ||
423 | size_t full_size; | ||
424 | int ret; | ||
425 | |||
426 | if (!dev->ethtool_ops->set_rxfh_indir) | ||
427 | return -EOPNOTSUPP; | ||
428 | |||
429 | if (copy_from_user(&table_size, | ||
430 | useraddr + offsetof(struct ethtool_rxfh_indir, size), | ||
431 | sizeof(table_size))) | ||
432 | return -EFAULT; | ||
433 | |||
434 | if (table_size > | ||
435 | (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index)) | ||
436 | return -ENOMEM; | ||
437 | full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size; | ||
438 | indir = kmalloc(full_size, GFP_USER); | ||
439 | if (!indir) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | if (copy_from_user(indir, useraddr, full_size)) { | ||
443 | ret = -EFAULT; | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | ret = dev->ethtool_ops->set_rxfh_indir(dev, indir); | ||
448 | |||
449 | out: | ||
450 | kfree(indir); | ||
451 | return ret; | ||
452 | } | ||
453 | |||
398 | static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, | 454 | static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, |
399 | struct ethtool_rx_ntuple_flow_spec *spec, | 455 | struct ethtool_rx_ntuple_flow_spec *spec, |
400 | struct ethtool_rx_ntuple_flow_spec_container *fsc) | 456 | struct ethtool_rx_ntuple_flow_spec_container *fsc) |
@@ -1563,6 +1619,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1563 | case ETHTOOL_GSSET_INFO: | 1619 | case ETHTOOL_GSSET_INFO: |
1564 | rc = ethtool_get_sset_info(dev, useraddr); | 1620 | rc = ethtool_get_sset_info(dev, useraddr); |
1565 | break; | 1621 | break; |
1622 | case ETHTOOL_GRXFHINDIR: | ||
1623 | rc = ethtool_get_rxfh_indir(dev, useraddr); | ||
1624 | break; | ||
1625 | case ETHTOOL_SRXFHINDIR: | ||
1626 | rc = ethtool_set_rxfh_indir(dev, useraddr); | ||
1627 | break; | ||
1566 | default: | 1628 | default: |
1567 | rc = -EOPNOTSUPP; | 1629 | rc = -EOPNOTSUPP; |
1568 | } | 1630 | } |
diff --git a/net/core/filter.c b/net/core/filter.c index da69fb728d32..52b051f82a01 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -128,87 +128,87 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int | |||
128 | fentry = &filter[pc]; | 128 | fentry = &filter[pc]; |
129 | 129 | ||
130 | switch (fentry->code) { | 130 | switch (fentry->code) { |
131 | case BPF_ALU|BPF_ADD|BPF_X: | 131 | case BPF_S_ALU_ADD_X: |
132 | A += X; | 132 | A += X; |
133 | continue; | 133 | continue; |
134 | case BPF_ALU|BPF_ADD|BPF_K: | 134 | case BPF_S_ALU_ADD_K: |
135 | A += fentry->k; | 135 | A += fentry->k; |
136 | continue; | 136 | continue; |
137 | case BPF_ALU|BPF_SUB|BPF_X: | 137 | case BPF_S_ALU_SUB_X: |
138 | A -= X; | 138 | A -= X; |
139 | continue; | 139 | continue; |
140 | case BPF_ALU|BPF_SUB|BPF_K: | 140 | case BPF_S_ALU_SUB_K: |
141 | A -= fentry->k; | 141 | A -= fentry->k; |
142 | continue; | 142 | continue; |
143 | case BPF_ALU|BPF_MUL|BPF_X: | 143 | case BPF_S_ALU_MUL_X: |
144 | A *= X; | 144 | A *= X; |
145 | continue; | 145 | continue; |
146 | case BPF_ALU|BPF_MUL|BPF_K: | 146 | case BPF_S_ALU_MUL_K: |
147 | A *= fentry->k; | 147 | A *= fentry->k; |
148 | continue; | 148 | continue; |
149 | case BPF_ALU|BPF_DIV|BPF_X: | 149 | case BPF_S_ALU_DIV_X: |
150 | if (X == 0) | 150 | if (X == 0) |
151 | return 0; | 151 | return 0; |
152 | A /= X; | 152 | A /= X; |
153 | continue; | 153 | continue; |
154 | case BPF_ALU|BPF_DIV|BPF_K: | 154 | case BPF_S_ALU_DIV_K: |
155 | A /= fentry->k; | 155 | A /= fentry->k; |
156 | continue; | 156 | continue; |
157 | case BPF_ALU|BPF_AND|BPF_X: | 157 | case BPF_S_ALU_AND_X: |
158 | A &= X; | 158 | A &= X; |
159 | continue; | 159 | continue; |
160 | case BPF_ALU|BPF_AND|BPF_K: | 160 | case BPF_S_ALU_AND_K: |
161 | A &= fentry->k; | 161 | A &= fentry->k; |
162 | continue; | 162 | continue; |
163 | case BPF_ALU|BPF_OR|BPF_X: | 163 | case BPF_S_ALU_OR_X: |
164 | A |= X; | 164 | A |= X; |
165 | continue; | 165 | continue; |
166 | case BPF_ALU|BPF_OR|BPF_K: | 166 | case BPF_S_ALU_OR_K: |
167 | A |= fentry->k; | 167 | A |= fentry->k; |
168 | continue; | 168 | continue; |
169 | case BPF_ALU|BPF_LSH|BPF_X: | 169 | case BPF_S_ALU_LSH_X: |
170 | A <<= X; | 170 | A <<= X; |
171 | continue; | 171 | continue; |
172 | case BPF_ALU|BPF_LSH|BPF_K: | 172 | case BPF_S_ALU_LSH_K: |
173 | A <<= fentry->k; | 173 | A <<= fentry->k; |
174 | continue; | 174 | continue; |
175 | case BPF_ALU|BPF_RSH|BPF_X: | 175 | case BPF_S_ALU_RSH_X: |
176 | A >>= X; | 176 | A >>= X; |
177 | continue; | 177 | continue; |
178 | case BPF_ALU|BPF_RSH|BPF_K: | 178 | case BPF_S_ALU_RSH_K: |
179 | A >>= fentry->k; | 179 | A >>= fentry->k; |
180 | continue; | 180 | continue; |
181 | case BPF_ALU|BPF_NEG: | 181 | case BPF_S_ALU_NEG: |
182 | A = -A; | 182 | A = -A; |
183 | continue; | 183 | continue; |
184 | case BPF_JMP|BPF_JA: | 184 | case BPF_S_JMP_JA: |
185 | pc += fentry->k; | 185 | pc += fentry->k; |
186 | continue; | 186 | continue; |
187 | case BPF_JMP|BPF_JGT|BPF_K: | 187 | case BPF_S_JMP_JGT_K: |
188 | pc += (A > fentry->k) ? fentry->jt : fentry->jf; | 188 | pc += (A > fentry->k) ? fentry->jt : fentry->jf; |
189 | continue; | 189 | continue; |
190 | case BPF_JMP|BPF_JGE|BPF_K: | 190 | case BPF_S_JMP_JGE_K: |
191 | pc += (A >= fentry->k) ? fentry->jt : fentry->jf; | 191 | pc += (A >= fentry->k) ? fentry->jt : fentry->jf; |
192 | continue; | 192 | continue; |
193 | case BPF_JMP|BPF_JEQ|BPF_K: | 193 | case BPF_S_JMP_JEQ_K: |
194 | pc += (A == fentry->k) ? fentry->jt : fentry->jf; | 194 | pc += (A == fentry->k) ? fentry->jt : fentry->jf; |
195 | continue; | 195 | continue; |
196 | case BPF_JMP|BPF_JSET|BPF_K: | 196 | case BPF_S_JMP_JSET_K: |
197 | pc += (A & fentry->k) ? fentry->jt : fentry->jf; | 197 | pc += (A & fentry->k) ? fentry->jt : fentry->jf; |
198 | continue; | 198 | continue; |
199 | case BPF_JMP|BPF_JGT|BPF_X: | 199 | case BPF_S_JMP_JGT_X: |
200 | pc += (A > X) ? fentry->jt : fentry->jf; | 200 | pc += (A > X) ? fentry->jt : fentry->jf; |
201 | continue; | 201 | continue; |
202 | case BPF_JMP|BPF_JGE|BPF_X: | 202 | case BPF_S_JMP_JGE_X: |
203 | pc += (A >= X) ? fentry->jt : fentry->jf; | 203 | pc += (A >= X) ? fentry->jt : fentry->jf; |
204 | continue; | 204 | continue; |
205 | case BPF_JMP|BPF_JEQ|BPF_X: | 205 | case BPF_S_JMP_JEQ_X: |
206 | pc += (A == X) ? fentry->jt : fentry->jf; | 206 | pc += (A == X) ? fentry->jt : fentry->jf; |
207 | continue; | 207 | continue; |
208 | case BPF_JMP|BPF_JSET|BPF_X: | 208 | case BPF_S_JMP_JSET_X: |
209 | pc += (A & X) ? fentry->jt : fentry->jf; | 209 | pc += (A & X) ? fentry->jt : fentry->jf; |
210 | continue; | 210 | continue; |
211 | case BPF_LD|BPF_W|BPF_ABS: | 211 | case BPF_S_LD_W_ABS: |
212 | k = fentry->k; | 212 | k = fentry->k; |
213 | load_w: | 213 | load_w: |
214 | ptr = load_pointer(skb, k, 4, &tmp); | 214 | ptr = load_pointer(skb, k, 4, &tmp); |
@@ -217,7 +217,7 @@ load_w: | |||
217 | continue; | 217 | continue; |
218 | } | 218 | } |
219 | break; | 219 | break; |
220 | case BPF_LD|BPF_H|BPF_ABS: | 220 | case BPF_S_LD_H_ABS: |
221 | k = fentry->k; | 221 | k = fentry->k; |
222 | load_h: | 222 | load_h: |
223 | ptr = load_pointer(skb, k, 2, &tmp); | 223 | ptr = load_pointer(skb, k, 2, &tmp); |
@@ -226,7 +226,7 @@ load_h: | |||
226 | continue; | 226 | continue; |
227 | } | 227 | } |
228 | break; | 228 | break; |
229 | case BPF_LD|BPF_B|BPF_ABS: | 229 | case BPF_S_LD_B_ABS: |
230 | k = fentry->k; | 230 | k = fentry->k; |
231 | load_b: | 231 | load_b: |
232 | ptr = load_pointer(skb, k, 1, &tmp); | 232 | ptr = load_pointer(skb, k, 1, &tmp); |
@@ -235,54 +235,54 @@ load_b: | |||
235 | continue; | 235 | continue; |
236 | } | 236 | } |
237 | break; | 237 | break; |
238 | case BPF_LD|BPF_W|BPF_LEN: | 238 | case BPF_S_LD_W_LEN: |
239 | A = skb->len; | 239 | A = skb->len; |
240 | continue; | 240 | continue; |
241 | case BPF_LDX|BPF_W|BPF_LEN: | 241 | case BPF_S_LDX_W_LEN: |
242 | X = skb->len; | 242 | X = skb->len; |
243 | continue; | 243 | continue; |
244 | case BPF_LD|BPF_W|BPF_IND: | 244 | case BPF_S_LD_W_IND: |
245 | k = X + fentry->k; | 245 | k = X + fentry->k; |
246 | goto load_w; | 246 | goto load_w; |
247 | case BPF_LD|BPF_H|BPF_IND: | 247 | case BPF_S_LD_H_IND: |
248 | k = X + fentry->k; | 248 | k = X + fentry->k; |
249 | goto load_h; | 249 | goto load_h; |
250 | case BPF_LD|BPF_B|BPF_IND: | 250 | case BPF_S_LD_B_IND: |
251 | k = X + fentry->k; | 251 | k = X + fentry->k; |
252 | goto load_b; | 252 | goto load_b; |
253 | case BPF_LDX|BPF_B|BPF_MSH: | 253 | case BPF_S_LDX_B_MSH: |
254 | ptr = load_pointer(skb, fentry->k, 1, &tmp); | 254 | ptr = load_pointer(skb, fentry->k, 1, &tmp); |
255 | if (ptr != NULL) { | 255 | if (ptr != NULL) { |
256 | X = (*(u8 *)ptr & 0xf) << 2; | 256 | X = (*(u8 *)ptr & 0xf) << 2; |
257 | continue; | 257 | continue; |
258 | } | 258 | } |
259 | return 0; | 259 | return 0; |
260 | case BPF_LD|BPF_IMM: | 260 | case BPF_S_LD_IMM: |
261 | A = fentry->k; | 261 | A = fentry->k; |
262 | continue; | 262 | continue; |
263 | case BPF_LDX|BPF_IMM: | 263 | case BPF_S_LDX_IMM: |
264 | X = fentry->k; | 264 | X = fentry->k; |
265 | continue; | 265 | continue; |
266 | case BPF_LD|BPF_MEM: | 266 | case BPF_S_LD_MEM: |
267 | A = mem[fentry->k]; | 267 | A = mem[fentry->k]; |
268 | continue; | 268 | continue; |
269 | case BPF_LDX|BPF_MEM: | 269 | case BPF_S_LDX_MEM: |
270 | X = mem[fentry->k]; | 270 | X = mem[fentry->k]; |
271 | continue; | 271 | continue; |
272 | case BPF_MISC|BPF_TAX: | 272 | case BPF_S_MISC_TAX: |
273 | X = A; | 273 | X = A; |
274 | continue; | 274 | continue; |
275 | case BPF_MISC|BPF_TXA: | 275 | case BPF_S_MISC_TXA: |
276 | A = X; | 276 | A = X; |
277 | continue; | 277 | continue; |
278 | case BPF_RET|BPF_K: | 278 | case BPF_S_RET_K: |
279 | return fentry->k; | 279 | return fentry->k; |
280 | case BPF_RET|BPF_A: | 280 | case BPF_S_RET_A: |
281 | return A; | 281 | return A; |
282 | case BPF_ST: | 282 | case BPF_S_ST: |
283 | mem[fentry->k] = A; | 283 | mem[fentry->k] = A; |
284 | continue; | 284 | continue; |
285 | case BPF_STX: | 285 | case BPF_S_STX: |
286 | mem[fentry->k] = X; | 286 | mem[fentry->k] = X; |
287 | continue; | 287 | continue; |
288 | default: | 288 | default: |
@@ -390,53 +390,128 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
390 | /* Only allow valid instructions */ | 390 | /* Only allow valid instructions */ |
391 | switch (ftest->code) { | 391 | switch (ftest->code) { |
392 | case BPF_ALU|BPF_ADD|BPF_K: | 392 | case BPF_ALU|BPF_ADD|BPF_K: |
393 | ftest->code = BPF_S_ALU_ADD_K; | ||
394 | break; | ||
393 | case BPF_ALU|BPF_ADD|BPF_X: | 395 | case BPF_ALU|BPF_ADD|BPF_X: |
396 | ftest->code = BPF_S_ALU_ADD_X; | ||
397 | break; | ||
394 | case BPF_ALU|BPF_SUB|BPF_K: | 398 | case BPF_ALU|BPF_SUB|BPF_K: |
399 | ftest->code = BPF_S_ALU_SUB_K; | ||
400 | break; | ||
395 | case BPF_ALU|BPF_SUB|BPF_X: | 401 | case BPF_ALU|BPF_SUB|BPF_X: |
402 | ftest->code = BPF_S_ALU_SUB_X; | ||
403 | break; | ||
396 | case BPF_ALU|BPF_MUL|BPF_K: | 404 | case BPF_ALU|BPF_MUL|BPF_K: |
405 | ftest->code = BPF_S_ALU_MUL_K; | ||
406 | break; | ||
397 | case BPF_ALU|BPF_MUL|BPF_X: | 407 | case BPF_ALU|BPF_MUL|BPF_X: |
408 | ftest->code = BPF_S_ALU_MUL_X; | ||
409 | break; | ||
398 | case BPF_ALU|BPF_DIV|BPF_X: | 410 | case BPF_ALU|BPF_DIV|BPF_X: |
411 | ftest->code = BPF_S_ALU_DIV_X; | ||
412 | break; | ||
399 | case BPF_ALU|BPF_AND|BPF_K: | 413 | case BPF_ALU|BPF_AND|BPF_K: |
414 | ftest->code = BPF_S_ALU_AND_K; | ||
415 | break; | ||
400 | case BPF_ALU|BPF_AND|BPF_X: | 416 | case BPF_ALU|BPF_AND|BPF_X: |
417 | ftest->code = BPF_S_ALU_AND_X; | ||
418 | break; | ||
401 | case BPF_ALU|BPF_OR|BPF_K: | 419 | case BPF_ALU|BPF_OR|BPF_K: |
420 | ftest->code = BPF_S_ALU_OR_K; | ||
421 | break; | ||
402 | case BPF_ALU|BPF_OR|BPF_X: | 422 | case BPF_ALU|BPF_OR|BPF_X: |
423 | ftest->code = BPF_S_ALU_OR_X; | ||
424 | break; | ||
403 | case BPF_ALU|BPF_LSH|BPF_K: | 425 | case BPF_ALU|BPF_LSH|BPF_K: |
426 | ftest->code = BPF_S_ALU_LSH_K; | ||
427 | break; | ||
404 | case BPF_ALU|BPF_LSH|BPF_X: | 428 | case BPF_ALU|BPF_LSH|BPF_X: |
429 | ftest->code = BPF_S_ALU_LSH_X; | ||
430 | break; | ||
405 | case BPF_ALU|BPF_RSH|BPF_K: | 431 | case BPF_ALU|BPF_RSH|BPF_K: |
432 | ftest->code = BPF_S_ALU_RSH_K; | ||
433 | break; | ||
406 | case BPF_ALU|BPF_RSH|BPF_X: | 434 | case BPF_ALU|BPF_RSH|BPF_X: |
435 | ftest->code = BPF_S_ALU_RSH_X; | ||
436 | break; | ||
407 | case BPF_ALU|BPF_NEG: | 437 | case BPF_ALU|BPF_NEG: |
438 | ftest->code = BPF_S_ALU_NEG; | ||
439 | break; | ||
408 | case BPF_LD|BPF_W|BPF_ABS: | 440 | case BPF_LD|BPF_W|BPF_ABS: |
441 | ftest->code = BPF_S_LD_W_ABS; | ||
442 | break; | ||
409 | case BPF_LD|BPF_H|BPF_ABS: | 443 | case BPF_LD|BPF_H|BPF_ABS: |
444 | ftest->code = BPF_S_LD_H_ABS; | ||
445 | break; | ||
410 | case BPF_LD|BPF_B|BPF_ABS: | 446 | case BPF_LD|BPF_B|BPF_ABS: |
447 | ftest->code = BPF_S_LD_B_ABS; | ||
448 | break; | ||
411 | case BPF_LD|BPF_W|BPF_LEN: | 449 | case BPF_LD|BPF_W|BPF_LEN: |
450 | ftest->code = BPF_S_LD_W_LEN; | ||
451 | break; | ||
412 | case BPF_LD|BPF_W|BPF_IND: | 452 | case BPF_LD|BPF_W|BPF_IND: |
453 | ftest->code = BPF_S_LD_W_IND; | ||
454 | break; | ||
413 | case BPF_LD|BPF_H|BPF_IND: | 455 | case BPF_LD|BPF_H|BPF_IND: |
456 | ftest->code = BPF_S_LD_H_IND; | ||
457 | break; | ||
414 | case BPF_LD|BPF_B|BPF_IND: | 458 | case BPF_LD|BPF_B|BPF_IND: |
459 | ftest->code = BPF_S_LD_B_IND; | ||
460 | break; | ||
415 | case BPF_LD|BPF_IMM: | 461 | case BPF_LD|BPF_IMM: |
462 | ftest->code = BPF_S_LD_IMM; | ||
463 | break; | ||
416 | case BPF_LDX|BPF_W|BPF_LEN: | 464 | case BPF_LDX|BPF_W|BPF_LEN: |
465 | ftest->code = BPF_S_LDX_W_LEN; | ||
466 | break; | ||
417 | case BPF_LDX|BPF_B|BPF_MSH: | 467 | case BPF_LDX|BPF_B|BPF_MSH: |
468 | ftest->code = BPF_S_LDX_B_MSH; | ||
469 | break; | ||
418 | case BPF_LDX|BPF_IMM: | 470 | case BPF_LDX|BPF_IMM: |
471 | ftest->code = BPF_S_LDX_IMM; | ||
472 | break; | ||
419 | case BPF_MISC|BPF_TAX: | 473 | case BPF_MISC|BPF_TAX: |
474 | ftest->code = BPF_S_MISC_TAX; | ||
475 | break; | ||
420 | case BPF_MISC|BPF_TXA: | 476 | case BPF_MISC|BPF_TXA: |
477 | ftest->code = BPF_S_MISC_TXA; | ||
478 | break; | ||
421 | case BPF_RET|BPF_K: | 479 | case BPF_RET|BPF_K: |
480 | ftest->code = BPF_S_RET_K; | ||
481 | break; | ||
422 | case BPF_RET|BPF_A: | 482 | case BPF_RET|BPF_A: |
483 | ftest->code = BPF_S_RET_A; | ||
423 | break; | 484 | break; |
424 | 485 | ||
425 | /* Some instructions need special checks */ | 486 | /* Some instructions need special checks */ |
426 | 487 | ||
427 | case BPF_ALU|BPF_DIV|BPF_K: | ||
428 | /* check for division by zero */ | 488 | /* check for division by zero */ |
489 | case BPF_ALU|BPF_DIV|BPF_K: | ||
429 | if (ftest->k == 0) | 490 | if (ftest->k == 0) |
430 | return -EINVAL; | 491 | return -EINVAL; |
492 | ftest->code = BPF_S_ALU_DIV_K; | ||
431 | break; | 493 | break; |
432 | 494 | ||
495 | /* check for invalid memory addresses */ | ||
433 | case BPF_LD|BPF_MEM: | 496 | case BPF_LD|BPF_MEM: |
497 | if (ftest->k >= BPF_MEMWORDS) | ||
498 | return -EINVAL; | ||
499 | ftest->code = BPF_S_LD_MEM; | ||
500 | break; | ||
434 | case BPF_LDX|BPF_MEM: | 501 | case BPF_LDX|BPF_MEM: |
502 | if (ftest->k >= BPF_MEMWORDS) | ||
503 | return -EINVAL; | ||
504 | ftest->code = BPF_S_LDX_MEM; | ||
505 | break; | ||
435 | case BPF_ST: | 506 | case BPF_ST: |
507 | if (ftest->k >= BPF_MEMWORDS) | ||
508 | return -EINVAL; | ||
509 | ftest->code = BPF_S_ST; | ||
510 | break; | ||
436 | case BPF_STX: | 511 | case BPF_STX: |
437 | /* check for invalid memory addresses */ | ||
438 | if (ftest->k >= BPF_MEMWORDS) | 512 | if (ftest->k >= BPF_MEMWORDS) |
439 | return -EINVAL; | 513 | return -EINVAL; |
514 | ftest->code = BPF_S_STX; | ||
440 | break; | 515 | break; |
441 | 516 | ||
442 | case BPF_JMP|BPF_JA: | 517 | case BPF_JMP|BPF_JA: |
@@ -447,28 +522,63 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
447 | */ | 522 | */ |
448 | if (ftest->k >= (unsigned)(flen-pc-1)) | 523 | if (ftest->k >= (unsigned)(flen-pc-1)) |
449 | return -EINVAL; | 524 | return -EINVAL; |
525 | ftest->code = BPF_S_JMP_JA; | ||
450 | break; | 526 | break; |
451 | 527 | ||
452 | case BPF_JMP|BPF_JEQ|BPF_K: | 528 | case BPF_JMP|BPF_JEQ|BPF_K: |
529 | ftest->code = BPF_S_JMP_JEQ_K; | ||
530 | break; | ||
453 | case BPF_JMP|BPF_JEQ|BPF_X: | 531 | case BPF_JMP|BPF_JEQ|BPF_X: |
532 | ftest->code = BPF_S_JMP_JEQ_X; | ||
533 | break; | ||
454 | case BPF_JMP|BPF_JGE|BPF_K: | 534 | case BPF_JMP|BPF_JGE|BPF_K: |
535 | ftest->code = BPF_S_JMP_JGE_K; | ||
536 | break; | ||
455 | case BPF_JMP|BPF_JGE|BPF_X: | 537 | case BPF_JMP|BPF_JGE|BPF_X: |
538 | ftest->code = BPF_S_JMP_JGE_X; | ||
539 | break; | ||
456 | case BPF_JMP|BPF_JGT|BPF_K: | 540 | case BPF_JMP|BPF_JGT|BPF_K: |
541 | ftest->code = BPF_S_JMP_JGT_K; | ||
542 | break; | ||
457 | case BPF_JMP|BPF_JGT|BPF_X: | 543 | case BPF_JMP|BPF_JGT|BPF_X: |
544 | ftest->code = BPF_S_JMP_JGT_X; | ||
545 | break; | ||
458 | case BPF_JMP|BPF_JSET|BPF_K: | 546 | case BPF_JMP|BPF_JSET|BPF_K: |
547 | ftest->code = BPF_S_JMP_JSET_K; | ||
548 | break; | ||
459 | case BPF_JMP|BPF_JSET|BPF_X: | 549 | case BPF_JMP|BPF_JSET|BPF_X: |
550 | ftest->code = BPF_S_JMP_JSET_X; | ||
551 | break; | ||
552 | |||
553 | default: | ||
554 | return -EINVAL; | ||
555 | } | ||
556 | |||
460 | /* for conditionals both must be safe */ | 557 | /* for conditionals both must be safe */ |
558 | switch (ftest->code) { | ||
559 | case BPF_S_JMP_JEQ_K: | ||
560 | case BPF_S_JMP_JEQ_X: | ||
561 | case BPF_S_JMP_JGE_K: | ||
562 | case BPF_S_JMP_JGE_X: | ||
563 | case BPF_S_JMP_JGT_K: | ||
564 | case BPF_S_JMP_JGT_X: | ||
565 | case BPF_S_JMP_JSET_X: | ||
566 | case BPF_S_JMP_JSET_K: | ||
461 | if (pc + ftest->jt + 1 >= flen || | 567 | if (pc + ftest->jt + 1 >= flen || |
462 | pc + ftest->jf + 1 >= flen) | 568 | pc + ftest->jf + 1 >= flen) |
463 | return -EINVAL; | 569 | return -EINVAL; |
464 | break; | 570 | } |
571 | } | ||
465 | 572 | ||
573 | /* last instruction must be a RET code */ | ||
574 | switch (filter[flen - 1].code) { | ||
575 | case BPF_S_RET_K: | ||
576 | case BPF_S_RET_A: | ||
577 | return 0; | ||
578 | break; | ||
466 | default: | 579 | default: |
467 | return -EINVAL; | 580 | return -EINVAL; |
468 | } | 581 | } |
469 | } | ||
470 | |||
471 | return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL; | ||
472 | } | 582 | } |
473 | EXPORT_SYMBOL(sk_chk_filter); | 583 | EXPORT_SYMBOL(sk_chk_filter); |
474 | 584 | ||
diff --git a/net/core/flow.c b/net/core/flow.c index 161900674009..f67dcbfe54ef 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -62,6 +62,7 @@ struct flow_cache { | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | atomic_t flow_cache_genid = ATOMIC_INIT(0); | 64 | atomic_t flow_cache_genid = ATOMIC_INIT(0); |
65 | EXPORT_SYMBOL(flow_cache_genid); | ||
65 | static struct flow_cache flow_cache_global; | 66 | static struct flow_cache flow_cache_global; |
66 | static struct kmem_cache *flow_cachep; | 67 | static struct kmem_cache *flow_cachep; |
67 | 68 | ||
@@ -222,7 +223,7 @@ flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir, | |||
222 | unsigned int hash; | 223 | unsigned int hash; |
223 | 224 | ||
224 | local_bh_disable(); | 225 | local_bh_disable(); |
225 | fcp = per_cpu_ptr(fc->percpu, smp_processor_id()); | 226 | fcp = this_cpu_ptr(fc->percpu); |
226 | 227 | ||
227 | fle = NULL; | 228 | fle = NULL; |
228 | flo = NULL; | 229 | flo = NULL; |
@@ -291,6 +292,7 @@ ret_object: | |||
291 | local_bh_enable(); | 292 | local_bh_enable(); |
292 | return flo; | 293 | return flo; |
293 | } | 294 | } |
295 | EXPORT_SYMBOL(flow_cache_lookup); | ||
294 | 296 | ||
295 | static void flow_cache_flush_tasklet(unsigned long data) | 297 | static void flow_cache_flush_tasklet(unsigned long data) |
296 | { | 298 | { |
@@ -302,7 +304,7 @@ static void flow_cache_flush_tasklet(unsigned long data) | |||
302 | LIST_HEAD(gc_list); | 304 | LIST_HEAD(gc_list); |
303 | int i, deleted = 0; | 305 | int i, deleted = 0; |
304 | 306 | ||
305 | fcp = per_cpu_ptr(fc->percpu, smp_processor_id()); | 307 | fcp = this_cpu_ptr(fc->percpu); |
306 | for (i = 0; i < flow_cache_hash_size(fc); i++) { | 308 | for (i = 0; i < flow_cache_hash_size(fc); i++) { |
307 | hlist_for_each_entry_safe(fle, entry, tmp, | 309 | hlist_for_each_entry_safe(fle, entry, tmp, |
308 | &fcp->hash_table[i], u.hlist) { | 310 | &fcp->hash_table[i], u.hlist) { |
@@ -424,6 +426,3 @@ static int __init flow_cache_init_global(void) | |||
424 | } | 426 | } |
425 | 427 | ||
426 | module_init(flow_cache_init_global); | 428 | module_init(flow_cache_init_global); |
427 | |||
428 | EXPORT_SYMBOL(flow_cache_genid); | ||
429 | EXPORT_SYMBOL(flow_cache_lookup); | ||
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 785e5276a300..9fbe7f7429b0 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -263,6 +263,7 @@ static void __gen_kill_estimator(struct rcu_head *head) | |||
263 | * | 263 | * |
264 | * Removes the rate estimator specified by &bstats and &rate_est. | 264 | * Removes the rate estimator specified by &bstats and &rate_est. |
265 | * | 265 | * |
266 | * Note : Caller should respect an RCU grace period before freeing stats_lock | ||
266 | */ | 267 | */ |
267 | void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | 268 | void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, |
268 | struct gnet_stats_rate_est *rate_est) | 269 | struct gnet_stats_rate_est *rate_est) |
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index 393b1d8618e2..0452eb27a272 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c | |||
@@ -73,6 +73,7 @@ gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type, | |||
73 | 73 | ||
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | EXPORT_SYMBOL(gnet_stats_start_copy_compat); | ||
76 | 77 | ||
77 | /** | 78 | /** |
78 | * gnet_stats_start_copy_compat - start dumping procedure in compatibility mode | 79 | * gnet_stats_start_copy_compat - start dumping procedure in compatibility mode |
@@ -93,6 +94,7 @@ gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock, | |||
93 | { | 94 | { |
94 | return gnet_stats_start_copy_compat(skb, type, 0, 0, lock, d); | 95 | return gnet_stats_start_copy_compat(skb, type, 0, 0, lock, d); |
95 | } | 96 | } |
97 | EXPORT_SYMBOL(gnet_stats_start_copy); | ||
96 | 98 | ||
97 | /** | 99 | /** |
98 | * gnet_stats_copy_basic - copy basic statistics into statistic TLV | 100 | * gnet_stats_copy_basic - copy basic statistics into statistic TLV |
@@ -123,6 +125,7 @@ gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b) | |||
123 | } | 125 | } |
124 | return 0; | 126 | return 0; |
125 | } | 127 | } |
128 | EXPORT_SYMBOL(gnet_stats_copy_basic); | ||
126 | 129 | ||
127 | /** | 130 | /** |
128 | * gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV | 131 | * gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV |
@@ -154,6 +157,7 @@ gnet_stats_copy_rate_est(struct gnet_dump *d, | |||
154 | 157 | ||
155 | return 0; | 158 | return 0; |
156 | } | 159 | } |
160 | EXPORT_SYMBOL(gnet_stats_copy_rate_est); | ||
157 | 161 | ||
158 | /** | 162 | /** |
159 | * gnet_stats_copy_queue - copy queue statistics into statistics TLV | 163 | * gnet_stats_copy_queue - copy queue statistics into statistics TLV |
@@ -181,6 +185,7 @@ gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q) | |||
181 | 185 | ||
182 | return 0; | 186 | return 0; |
183 | } | 187 | } |
188 | EXPORT_SYMBOL(gnet_stats_copy_queue); | ||
184 | 189 | ||
185 | /** | 190 | /** |
186 | * gnet_stats_copy_app - copy application specific statistics into statistics TLV | 191 | * gnet_stats_copy_app - copy application specific statistics into statistics TLV |
@@ -208,6 +213,7 @@ gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) | |||
208 | 213 | ||
209 | return 0; | 214 | return 0; |
210 | } | 215 | } |
216 | EXPORT_SYMBOL(gnet_stats_copy_app); | ||
211 | 217 | ||
212 | /** | 218 | /** |
213 | * gnet_stats_finish_copy - finish dumping procedure | 219 | * gnet_stats_finish_copy - finish dumping procedure |
@@ -241,12 +247,4 @@ gnet_stats_finish_copy(struct gnet_dump *d) | |||
241 | spin_unlock_bh(d->lock); | 247 | spin_unlock_bh(d->lock); |
242 | return 0; | 248 | return 0; |
243 | } | 249 | } |
244 | |||
245 | |||
246 | EXPORT_SYMBOL(gnet_stats_start_copy); | ||
247 | EXPORT_SYMBOL(gnet_stats_start_copy_compat); | ||
248 | EXPORT_SYMBOL(gnet_stats_copy_basic); | ||
249 | EXPORT_SYMBOL(gnet_stats_copy_rate_est); | ||
250 | EXPORT_SYMBOL(gnet_stats_copy_queue); | ||
251 | EXPORT_SYMBOL(gnet_stats_copy_app); | ||
252 | EXPORT_SYMBOL(gnet_stats_finish_copy); | 250 | EXPORT_SYMBOL(gnet_stats_finish_copy); |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 1e7f4e91a935..1cd98df412df 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -95,6 +95,7 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) | |||
95 | 95 | ||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | EXPORT_SYMBOL(memcpy_toiovec); | ||
98 | 99 | ||
99 | /* | 100 | /* |
100 | * Copy kernel to iovec. Returns -EFAULT on error. | 101 | * Copy kernel to iovec. Returns -EFAULT on error. |
@@ -120,6 +121,7 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, | |||
120 | 121 | ||
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
124 | EXPORT_SYMBOL(memcpy_toiovecend); | ||
123 | 125 | ||
124 | /* | 126 | /* |
125 | * Copy iovec to kernel. Returns -EFAULT on error. | 127 | * Copy iovec to kernel. Returns -EFAULT on error. |
@@ -144,6 +146,7 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) | |||
144 | 146 | ||
145 | return 0; | 147 | return 0; |
146 | } | 148 | } |
149 | EXPORT_SYMBOL(memcpy_fromiovec); | ||
147 | 150 | ||
148 | /* | 151 | /* |
149 | * Copy iovec from kernel. Returns -EFAULT on error. | 152 | * Copy iovec from kernel. Returns -EFAULT on error. |
@@ -172,6 +175,7 @@ int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, | |||
172 | 175 | ||
173 | return 0; | 176 | return 0; |
174 | } | 177 | } |
178 | EXPORT_SYMBOL(memcpy_fromiovecend); | ||
175 | 179 | ||
176 | /* | 180 | /* |
177 | * And now for the all-in-one: copy and checksum from a user iovec | 181 | * And now for the all-in-one: copy and checksum from a user iovec |
@@ -256,9 +260,4 @@ out_fault: | |||
256 | err = -EFAULT; | 260 | err = -EFAULT; |
257 | goto out; | 261 | goto out; |
258 | } | 262 | } |
259 | |||
260 | EXPORT_SYMBOL(csum_partial_copy_fromiovecend); | 263 | EXPORT_SYMBOL(csum_partial_copy_fromiovecend); |
261 | EXPORT_SYMBOL(memcpy_fromiovec); | ||
262 | EXPORT_SYMBOL(memcpy_fromiovecend); | ||
263 | EXPORT_SYMBOL(memcpy_toiovec); | ||
264 | EXPORT_SYMBOL(memcpy_toiovecend); | ||
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index bdbce2f5875b..01a1101b5936 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -243,5 +243,4 @@ void linkwatch_fire_event(struct net_device *dev) | |||
243 | 243 | ||
244 | linkwatch_schedule_work(urgent); | 244 | linkwatch_schedule_work(urgent); |
245 | } | 245 | } |
246 | |||
247 | EXPORT_SYMBOL(linkwatch_fire_event); | 246 | EXPORT_SYMBOL(linkwatch_fire_event); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 6ba1c0eece03..a4e0a7482c2b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -949,7 +949,10 @@ static void neigh_update_hhs(struct neighbour *neigh) | |||
949 | { | 949 | { |
950 | struct hh_cache *hh; | 950 | struct hh_cache *hh; |
951 | void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) | 951 | void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) |
952 | = neigh->dev->header_ops->cache_update; | 952 | = NULL; |
953 | |||
954 | if (neigh->dev->header_ops) | ||
955 | update = neigh->dev->header_ops->cache_update; | ||
953 | 956 | ||
954 | if (update) { | 957 | if (update) { |
955 | for (hh = neigh->hh; hh; hh = hh->hh_next) { | 958 | for (hh = neigh->hh; hh; hh = hh->hh_next) { |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 99e7052d7323..af4dfbadf2a0 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -29,6 +29,7 @@ static const char fmt_hex[] = "%#x\n"; | |||
29 | static const char fmt_long_hex[] = "%#lx\n"; | 29 | static const char fmt_long_hex[] = "%#lx\n"; |
30 | static const char fmt_dec[] = "%d\n"; | 30 | static const char fmt_dec[] = "%d\n"; |
31 | static const char fmt_ulong[] = "%lu\n"; | 31 | static const char fmt_ulong[] = "%lu\n"; |
32 | static const char fmt_u64[] = "%llu\n"; | ||
32 | 33 | ||
33 | static inline int dev_isalive(const struct net_device *dev) | 34 | static inline int dev_isalive(const struct net_device *dev) |
34 | { | 35 | { |
@@ -94,6 +95,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, | |||
94 | } | 95 | } |
95 | 96 | ||
96 | NETDEVICE_SHOW(dev_id, fmt_hex); | 97 | NETDEVICE_SHOW(dev_id, fmt_hex); |
98 | NETDEVICE_SHOW(addr_assign_type, fmt_dec); | ||
97 | NETDEVICE_SHOW(addr_len, fmt_dec); | 99 | NETDEVICE_SHOW(addr_len, fmt_dec); |
98 | NETDEVICE_SHOW(iflink, fmt_dec); | 100 | NETDEVICE_SHOW(iflink, fmt_dec); |
99 | NETDEVICE_SHOW(ifindex, fmt_dec); | 101 | NETDEVICE_SHOW(ifindex, fmt_dec); |
@@ -294,6 +296,7 @@ static ssize_t show_ifalias(struct device *dev, | |||
294 | } | 296 | } |
295 | 297 | ||
296 | static struct device_attribute net_class_attributes[] = { | 298 | static struct device_attribute net_class_attributes[] = { |
299 | __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), | ||
297 | __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), | 300 | __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), |
298 | __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), | 301 | __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), |
299 | __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), | 302 | __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), |
@@ -324,14 +327,15 @@ static ssize_t netstat_show(const struct device *d, | |||
324 | struct net_device *dev = to_net_dev(d); | 327 | struct net_device *dev = to_net_dev(d); |
325 | ssize_t ret = -EINVAL; | 328 | ssize_t ret = -EINVAL; |
326 | 329 | ||
327 | WARN_ON(offset > sizeof(struct net_device_stats) || | 330 | WARN_ON(offset > sizeof(struct rtnl_link_stats64) || |
328 | offset % sizeof(unsigned long) != 0); | 331 | offset % sizeof(u64) != 0); |
329 | 332 | ||
330 | read_lock(&dev_base_lock); | 333 | read_lock(&dev_base_lock); |
331 | if (dev_isalive(dev)) { | 334 | if (dev_isalive(dev)) { |
332 | const struct net_device_stats *stats = dev_get_stats(dev); | 335 | struct rtnl_link_stats64 temp; |
333 | ret = sprintf(buf, fmt_ulong, | 336 | const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp); |
334 | *(unsigned long *)(((u8 *) stats) + offset)); | 337 | |
338 | ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *) stats) + offset)); | ||
335 | } | 339 | } |
336 | read_unlock(&dev_base_lock); | 340 | read_unlock(&dev_base_lock); |
337 | return ret; | 341 | return ret; |
@@ -343,7 +347,7 @@ static ssize_t show_##name(struct device *d, \ | |||
343 | struct device_attribute *attr, char *buf) \ | 347 | struct device_attribute *attr, char *buf) \ |
344 | { \ | 348 | { \ |
345 | return netstat_show(d, attr, buf, \ | 349 | return netstat_show(d, attr, buf, \ |
346 | offsetof(struct net_device_stats, name)); \ | 350 | offsetof(struct rtnl_link_stats64, name)); \ |
347 | } \ | 351 | } \ |
348 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | 352 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) |
349 | 353 | ||
@@ -922,13 +926,12 @@ int netdev_class_create_file(struct class_attribute *class_attr) | |||
922 | { | 926 | { |
923 | return class_create_file(&net_class, class_attr); | 927 | return class_create_file(&net_class, class_attr); |
924 | } | 928 | } |
929 | EXPORT_SYMBOL(netdev_class_create_file); | ||
925 | 930 | ||
926 | void netdev_class_remove_file(struct class_attribute *class_attr) | 931 | void netdev_class_remove_file(struct class_attribute *class_attr) |
927 | { | 932 | { |
928 | class_remove_file(&net_class, class_attr); | 933 | class_remove_file(&net_class, class_attr); |
929 | } | 934 | } |
930 | |||
931 | EXPORT_SYMBOL(netdev_class_create_file); | ||
932 | EXPORT_SYMBOL(netdev_class_remove_file); | 935 | EXPORT_SYMBOL(netdev_class_remove_file); |
933 | 936 | ||
934 | int netdev_kobject_init(void) | 937 | int netdev_kobject_init(void) |
diff --git a/net/core/netevent.c b/net/core/netevent.c index 95f81de87502..865f0ceb81fb 100644 --- a/net/core/netevent.c +++ b/net/core/netevent.c | |||
@@ -35,6 +35,7 @@ int register_netevent_notifier(struct notifier_block *nb) | |||
35 | err = atomic_notifier_chain_register(&netevent_notif_chain, nb); | 35 | err = atomic_notifier_chain_register(&netevent_notif_chain, nb); |
36 | return err; | 36 | return err; |
37 | } | 37 | } |
38 | EXPORT_SYMBOL_GPL(register_netevent_notifier); | ||
38 | 39 | ||
39 | /** | 40 | /** |
40 | * netevent_unregister_notifier - unregister a netevent notifier block | 41 | * netevent_unregister_notifier - unregister a netevent notifier block |
@@ -50,6 +51,7 @@ int unregister_netevent_notifier(struct notifier_block *nb) | |||
50 | { | 51 | { |
51 | return atomic_notifier_chain_unregister(&netevent_notif_chain, nb); | 52 | return atomic_notifier_chain_unregister(&netevent_notif_chain, nb); |
52 | } | 53 | } |
54 | EXPORT_SYMBOL_GPL(unregister_netevent_notifier); | ||
53 | 55 | ||
54 | /** | 56 | /** |
55 | * call_netevent_notifiers - call all netevent notifier blocks | 57 | * call_netevent_notifiers - call all netevent notifier blocks |
@@ -64,7 +66,4 @@ int call_netevent_notifiers(unsigned long val, void *v) | |||
64 | { | 66 | { |
65 | return atomic_notifier_call_chain(&netevent_notif_chain, val, v); | 67 | return atomic_notifier_call_chain(&netevent_notif_chain, val, v); |
66 | } | 68 | } |
67 | |||
68 | EXPORT_SYMBOL_GPL(register_netevent_notifier); | ||
69 | EXPORT_SYMBOL_GPL(unregister_netevent_notifier); | ||
70 | EXPORT_SYMBOL_GPL(call_netevent_notifiers); | 69 | EXPORT_SYMBOL_GPL(call_netevent_notifiers); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 94825b109551..537e01afd81b 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -199,11 +199,13 @@ void netpoll_poll_dev(struct net_device *dev) | |||
199 | 199 | ||
200 | zap_completion_queue(); | 200 | zap_completion_queue(); |
201 | } | 201 | } |
202 | EXPORT_SYMBOL(netpoll_poll_dev); | ||
202 | 203 | ||
203 | void netpoll_poll(struct netpoll *np) | 204 | void netpoll_poll(struct netpoll *np) |
204 | { | 205 | { |
205 | netpoll_poll_dev(np->dev); | 206 | netpoll_poll_dev(np->dev); |
206 | } | 207 | } |
208 | EXPORT_SYMBOL(netpoll_poll); | ||
207 | 209 | ||
208 | static void refill_skbs(void) | 210 | static void refill_skbs(void) |
209 | { | 211 | { |
@@ -292,6 +294,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | |||
292 | unsigned long tries; | 294 | unsigned long tries; |
293 | struct net_device *dev = np->dev; | 295 | struct net_device *dev = np->dev; |
294 | const struct net_device_ops *ops = dev->netdev_ops; | 296 | const struct net_device_ops *ops = dev->netdev_ops; |
297 | /* It is up to the caller to keep npinfo alive. */ | ||
295 | struct netpoll_info *npinfo = np->dev->npinfo; | 298 | struct netpoll_info *npinfo = np->dev->npinfo; |
296 | 299 | ||
297 | if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { | 300 | if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { |
@@ -343,6 +346,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | |||
343 | schedule_delayed_work(&npinfo->tx_work,0); | 346 | schedule_delayed_work(&npinfo->tx_work,0); |
344 | } | 347 | } |
345 | } | 348 | } |
349 | EXPORT_SYMBOL(netpoll_send_skb); | ||
346 | 350 | ||
347 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | 351 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) |
348 | { | 352 | { |
@@ -404,6 +408,7 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | |||
404 | 408 | ||
405 | netpoll_send_skb(np, skb); | 409 | netpoll_send_skb(np, skb); |
406 | } | 410 | } |
411 | EXPORT_SYMBOL(netpoll_send_udp); | ||
407 | 412 | ||
408 | static void arp_reply(struct sk_buff *skb) | 413 | static void arp_reply(struct sk_buff *skb) |
409 | { | 414 | { |
@@ -630,6 +635,7 @@ void netpoll_print_options(struct netpoll *np) | |||
630 | printk(KERN_INFO "%s: remote ethernet address %pM\n", | 635 | printk(KERN_INFO "%s: remote ethernet address %pM\n", |
631 | np->name, np->remote_mac); | 636 | np->name, np->remote_mac); |
632 | } | 637 | } |
638 | EXPORT_SYMBOL(netpoll_print_options); | ||
633 | 639 | ||
634 | int netpoll_parse_options(struct netpoll *np, char *opt) | 640 | int netpoll_parse_options(struct netpoll *np, char *opt) |
635 | { | 641 | { |
@@ -722,30 +728,29 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
722 | np->name, cur); | 728 | np->name, cur); |
723 | return -1; | 729 | return -1; |
724 | } | 730 | } |
731 | EXPORT_SYMBOL(netpoll_parse_options); | ||
725 | 732 | ||
726 | int netpoll_setup(struct netpoll *np) | 733 | int __netpoll_setup(struct netpoll *np) |
727 | { | 734 | { |
728 | struct net_device *ndev = NULL; | 735 | struct net_device *ndev = np->dev; |
729 | struct in_device *in_dev; | ||
730 | struct netpoll_info *npinfo; | 736 | struct netpoll_info *npinfo; |
731 | struct netpoll *npe, *tmp; | 737 | const struct net_device_ops *ops; |
732 | unsigned long flags; | 738 | unsigned long flags; |
733 | int err; | 739 | int err; |
734 | 740 | ||
735 | if (np->dev_name) | 741 | if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || |
736 | ndev = dev_get_by_name(&init_net, np->dev_name); | 742 | !ndev->netdev_ops->ndo_poll_controller) { |
737 | if (!ndev) { | 743 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
738 | printk(KERN_ERR "%s: %s doesn't exist, aborting.\n", | ||
739 | np->name, np->dev_name); | 744 | np->name, np->dev_name); |
740 | return -ENODEV; | 745 | err = -ENOTSUPP; |
746 | goto out; | ||
741 | } | 747 | } |
742 | 748 | ||
743 | np->dev = ndev; | ||
744 | if (!ndev->npinfo) { | 749 | if (!ndev->npinfo) { |
745 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); | 750 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); |
746 | if (!npinfo) { | 751 | if (!npinfo) { |
747 | err = -ENOMEM; | 752 | err = -ENOMEM; |
748 | goto put; | 753 | goto out; |
749 | } | 754 | } |
750 | 755 | ||
751 | npinfo->rx_flags = 0; | 756 | npinfo->rx_flags = 0; |
@@ -757,6 +762,13 @@ int netpoll_setup(struct netpoll *np) | |||
757 | INIT_DELAYED_WORK(&npinfo->tx_work, queue_process); | 762 | INIT_DELAYED_WORK(&npinfo->tx_work, queue_process); |
758 | 763 | ||
759 | atomic_set(&npinfo->refcnt, 1); | 764 | atomic_set(&npinfo->refcnt, 1); |
765 | |||
766 | ops = np->dev->netdev_ops; | ||
767 | if (ops->ndo_netpoll_setup) { | ||
768 | err = ops->ndo_netpoll_setup(ndev, npinfo); | ||
769 | if (err) | ||
770 | goto free_npinfo; | ||
771 | } | ||
760 | } else { | 772 | } else { |
761 | npinfo = ndev->npinfo; | 773 | npinfo = ndev->npinfo; |
762 | atomic_inc(&npinfo->refcnt); | 774 | atomic_inc(&npinfo->refcnt); |
@@ -764,12 +776,37 @@ int netpoll_setup(struct netpoll *np) | |||
764 | 776 | ||
765 | npinfo->netpoll = np; | 777 | npinfo->netpoll = np; |
766 | 778 | ||
767 | if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || | 779 | if (np->rx_hook) { |
768 | !ndev->netdev_ops->ndo_poll_controller) { | 780 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
769 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 781 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; |
782 | list_add_tail(&np->rx, &npinfo->rx_np); | ||
783 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
784 | } | ||
785 | |||
786 | /* last thing to do is link it to the net device structure */ | ||
787 | rcu_assign_pointer(ndev->npinfo, npinfo); | ||
788 | |||
789 | return 0; | ||
790 | |||
791 | free_npinfo: | ||
792 | kfree(npinfo); | ||
793 | out: | ||
794 | return err; | ||
795 | } | ||
796 | EXPORT_SYMBOL_GPL(__netpoll_setup); | ||
797 | |||
798 | int netpoll_setup(struct netpoll *np) | ||
799 | { | ||
800 | struct net_device *ndev = NULL; | ||
801 | struct in_device *in_dev; | ||
802 | int err; | ||
803 | |||
804 | if (np->dev_name) | ||
805 | ndev = dev_get_by_name(&init_net, np->dev_name); | ||
806 | if (!ndev) { | ||
807 | printk(KERN_ERR "%s: %s doesn't exist, aborting.\n", | ||
770 | np->name, np->dev_name); | 808 | np->name, np->dev_name); |
771 | err = -ENOTSUPP; | 809 | return -ENODEV; |
772 | goto release; | ||
773 | } | 810 | } |
774 | 811 | ||
775 | if (!netif_running(ndev)) { | 812 | if (!netif_running(ndev)) { |
@@ -785,7 +822,7 @@ int netpoll_setup(struct netpoll *np) | |||
785 | if (err) { | 822 | if (err) { |
786 | printk(KERN_ERR "%s: failed to open %s\n", | 823 | printk(KERN_ERR "%s: failed to open %s\n", |
787 | np->name, ndev->name); | 824 | np->name, ndev->name); |
788 | goto release; | 825 | goto put; |
789 | } | 826 | } |
790 | 827 | ||
791 | atleast = jiffies + HZ/10; | 828 | atleast = jiffies + HZ/10; |
@@ -822,7 +859,7 @@ int netpoll_setup(struct netpoll *np) | |||
822 | printk(KERN_ERR "%s: no IP address for %s, aborting\n", | 859 | printk(KERN_ERR "%s: no IP address for %s, aborting\n", |
823 | np->name, np->dev_name); | 860 | np->name, np->dev_name); |
824 | err = -EDESTADDRREQ; | 861 | err = -EDESTADDRREQ; |
825 | goto release; | 862 | goto put; |
826 | } | 863 | } |
827 | 864 | ||
828 | np->local_ip = in_dev->ifa_list->ifa_local; | 865 | np->local_ip = in_dev->ifa_list->ifa_local; |
@@ -830,38 +867,25 @@ int netpoll_setup(struct netpoll *np) | |||
830 | printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip); | 867 | printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip); |
831 | } | 868 | } |
832 | 869 | ||
833 | if (np->rx_hook) { | 870 | np->dev = ndev; |
834 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
835 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; | ||
836 | list_add_tail(&np->rx, &npinfo->rx_np); | ||
837 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
838 | } | ||
839 | 871 | ||
840 | /* fill up the skb queue */ | 872 | /* fill up the skb queue */ |
841 | refill_skbs(); | 873 | refill_skbs(); |
842 | 874 | ||
843 | /* last thing to do is link it to the net device structure */ | 875 | rtnl_lock(); |
844 | ndev->npinfo = npinfo; | 876 | err = __netpoll_setup(np); |
877 | rtnl_unlock(); | ||
845 | 878 | ||
846 | /* avoid racing with NAPI reading npinfo */ | 879 | if (err) |
847 | synchronize_rcu(); | 880 | goto put; |
848 | 881 | ||
849 | return 0; | 882 | return 0; |
850 | 883 | ||
851 | release: | ||
852 | if (!ndev->npinfo) { | ||
853 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
854 | list_for_each_entry_safe(npe, tmp, &npinfo->rx_np, rx) { | ||
855 | npe->dev = NULL; | ||
856 | } | ||
857 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
858 | |||
859 | kfree(npinfo); | ||
860 | } | ||
861 | put: | 884 | put: |
862 | dev_put(ndev); | 885 | dev_put(ndev); |
863 | return err; | 886 | return err; |
864 | } | 887 | } |
888 | EXPORT_SYMBOL(netpoll_setup); | ||
865 | 889 | ||
866 | static int __init netpoll_init(void) | 890 | static int __init netpoll_init(void) |
867 | { | 891 | { |
@@ -870,49 +894,65 @@ static int __init netpoll_init(void) | |||
870 | } | 894 | } |
871 | core_initcall(netpoll_init); | 895 | core_initcall(netpoll_init); |
872 | 896 | ||
873 | void netpoll_cleanup(struct netpoll *np) | 897 | void __netpoll_cleanup(struct netpoll *np) |
874 | { | 898 | { |
875 | struct netpoll_info *npinfo; | 899 | struct netpoll_info *npinfo; |
876 | unsigned long flags; | 900 | unsigned long flags; |
877 | 901 | ||
878 | if (np->dev) { | 902 | npinfo = np->dev->npinfo; |
879 | npinfo = np->dev->npinfo; | 903 | if (!npinfo) |
880 | if (npinfo) { | 904 | return; |
881 | if (!list_empty(&npinfo->rx_np)) { | ||
882 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
883 | list_del(&np->rx); | ||
884 | if (list_empty(&npinfo->rx_np)) | ||
885 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | ||
886 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
887 | } | ||
888 | 905 | ||
889 | if (atomic_dec_and_test(&npinfo->refcnt)) { | 906 | if (!list_empty(&npinfo->rx_np)) { |
890 | const struct net_device_ops *ops; | 907 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
891 | skb_queue_purge(&npinfo->arp_tx); | 908 | list_del(&np->rx); |
892 | skb_queue_purge(&npinfo->txq); | 909 | if (list_empty(&npinfo->rx_np)) |
893 | cancel_rearming_delayed_work(&npinfo->tx_work); | 910 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; |
894 | 911 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | |
895 | /* clean after last, unfinished work */ | 912 | } |
896 | __skb_queue_purge(&npinfo->txq); | 913 | |
897 | kfree(npinfo); | 914 | if (atomic_dec_and_test(&npinfo->refcnt)) { |
898 | ops = np->dev->netdev_ops; | 915 | const struct net_device_ops *ops; |
899 | if (ops->ndo_netpoll_cleanup) | 916 | |
900 | ops->ndo_netpoll_cleanup(np->dev); | 917 | ops = np->dev->netdev_ops; |
901 | else | 918 | if (ops->ndo_netpoll_cleanup) |
902 | np->dev->npinfo = NULL; | 919 | ops->ndo_netpoll_cleanup(np->dev); |
903 | } | 920 | |
904 | } | 921 | rcu_assign_pointer(np->dev->npinfo, NULL); |
922 | |||
923 | /* avoid racing with NAPI reading npinfo */ | ||
924 | synchronize_rcu_bh(); | ||
925 | |||
926 | skb_queue_purge(&npinfo->arp_tx); | ||
927 | skb_queue_purge(&npinfo->txq); | ||
928 | cancel_rearming_delayed_work(&npinfo->tx_work); | ||
905 | 929 | ||
906 | dev_put(np->dev); | 930 | /* clean after last, unfinished work */ |
931 | __skb_queue_purge(&npinfo->txq); | ||
932 | kfree(npinfo); | ||
907 | } | 933 | } |
934 | } | ||
935 | EXPORT_SYMBOL_GPL(__netpoll_cleanup); | ||
936 | |||
937 | void netpoll_cleanup(struct netpoll *np) | ||
938 | { | ||
939 | if (!np->dev) | ||
940 | return; | ||
908 | 941 | ||
942 | rtnl_lock(); | ||
943 | __netpoll_cleanup(np); | ||
944 | rtnl_unlock(); | ||
945 | |||
946 | dev_put(np->dev); | ||
909 | np->dev = NULL; | 947 | np->dev = NULL; |
910 | } | 948 | } |
949 | EXPORT_SYMBOL(netpoll_cleanup); | ||
911 | 950 | ||
912 | int netpoll_trap(void) | 951 | int netpoll_trap(void) |
913 | { | 952 | { |
914 | return atomic_read(&trapped); | 953 | return atomic_read(&trapped); |
915 | } | 954 | } |
955 | EXPORT_SYMBOL(netpoll_trap); | ||
916 | 956 | ||
917 | void netpoll_set_trap(int trap) | 957 | void netpoll_set_trap(int trap) |
918 | { | 958 | { |
@@ -921,14 +961,4 @@ void netpoll_set_trap(int trap) | |||
921 | else | 961 | else |
922 | atomic_dec(&trapped); | 962 | atomic_dec(&trapped); |
923 | } | 963 | } |
924 | |||
925 | EXPORT_SYMBOL(netpoll_send_skb); | ||
926 | EXPORT_SYMBOL(netpoll_set_trap); | 964 | EXPORT_SYMBOL(netpoll_set_trap); |
927 | EXPORT_SYMBOL(netpoll_trap); | ||
928 | EXPORT_SYMBOL(netpoll_print_options); | ||
929 | EXPORT_SYMBOL(netpoll_parse_options); | ||
930 | EXPORT_SYMBOL(netpoll_setup); | ||
931 | EXPORT_SYMBOL(netpoll_cleanup); | ||
932 | EXPORT_SYMBOL(netpoll_send_udp); | ||
933 | EXPORT_SYMBOL(netpoll_poll_dev); | ||
934 | EXPORT_SYMBOL(netpoll_poll); | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 1dacd7ba8dbb..10a1ea72010d 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -115,6 +115,9 @@ | |||
115 | * command by Adit Ranadive <adit.262@gmail.com> | 115 | * command by Adit Ranadive <adit.262@gmail.com> |
116 | * | 116 | * |
117 | */ | 117 | */ |
118 | |||
119 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
120 | |||
118 | #include <linux/sys.h> | 121 | #include <linux/sys.h> |
119 | #include <linux/types.h> | 122 | #include <linux/types.h> |
120 | #include <linux/module.h> | 123 | #include <linux/module.h> |
@@ -169,11 +172,13 @@ | |||
169 | #include <asm/dma.h> | 172 | #include <asm/dma.h> |
170 | #include <asm/div64.h> /* do_div */ | 173 | #include <asm/div64.h> /* do_div */ |
171 | 174 | ||
172 | #define VERSION "2.73" | 175 | #define VERSION "2.74" |
173 | #define IP_NAME_SZ 32 | 176 | #define IP_NAME_SZ 32 |
174 | #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ | 177 | #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ |
175 | #define MPLS_STACK_BOTTOM htonl(0x00000100) | 178 | #define MPLS_STACK_BOTTOM htonl(0x00000100) |
176 | 179 | ||
180 | #define func_enter() pr_debug("entering %s\n", __func__); | ||
181 | |||
177 | /* Device flag bits */ | 182 | /* Device flag bits */ |
178 | #define F_IPSRC_RND (1<<0) /* IP-Src Random */ | 183 | #define F_IPSRC_RND (1<<0) /* IP-Src Random */ |
179 | #define F_IPDST_RND (1<<1) /* IP-Dst Random */ | 184 | #define F_IPDST_RND (1<<1) /* IP-Dst Random */ |
@@ -424,7 +429,8 @@ static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2) | |||
424 | } | 429 | } |
425 | 430 | ||
426 | static const char version[] = | 431 | static const char version[] = |
427 | "pktgen " VERSION ": Packet Generator for packet performance testing.\n"; | 432 | "Packet Generator for packet performance testing. " |
433 | "Version: " VERSION "\n"; | ||
428 | 434 | ||
429 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); | 435 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); |
430 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); | 436 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); |
@@ -495,7 +501,7 @@ static ssize_t pgctrl_write(struct file *file, const char __user *buf, | |||
495 | pktgen_reset_all_threads(); | 501 | pktgen_reset_all_threads(); |
496 | 502 | ||
497 | else | 503 | else |
498 | printk(KERN_WARNING "pktgen: Unknown command: %s\n", data); | 504 | pr_warning("Unknown command: %s\n", data); |
499 | 505 | ||
500 | err = count; | 506 | err = count; |
501 | 507 | ||
@@ -840,7 +846,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
840 | const char __user * user_buffer, size_t count, | 846 | const char __user * user_buffer, size_t count, |
841 | loff_t * offset) | 847 | loff_t * offset) |
842 | { | 848 | { |
843 | struct seq_file *seq = (struct seq_file *)file->private_data; | 849 | struct seq_file *seq = file->private_data; |
844 | struct pktgen_dev *pkt_dev = seq->private; | 850 | struct pktgen_dev *pkt_dev = seq->private; |
845 | int i = 0, max, len; | 851 | int i = 0, max, len; |
846 | char name[16], valstr[32]; | 852 | char name[16], valstr[32]; |
@@ -852,14 +858,14 @@ static ssize_t pktgen_if_write(struct file *file, | |||
852 | pg_result = &(pkt_dev->result[0]); | 858 | pg_result = &(pkt_dev->result[0]); |
853 | 859 | ||
854 | if (count < 1) { | 860 | if (count < 1) { |
855 | printk(KERN_WARNING "pktgen: wrong command format\n"); | 861 | pr_warning("wrong command format\n"); |
856 | return -EINVAL; | 862 | return -EINVAL; |
857 | } | 863 | } |
858 | 864 | ||
859 | max = count - i; | 865 | max = count - i; |
860 | tmp = count_trail_chars(&user_buffer[i], max); | 866 | tmp = count_trail_chars(&user_buffer[i], max); |
861 | if (tmp < 0) { | 867 | if (tmp < 0) { |
862 | printk(KERN_WARNING "pktgen: illegal format\n"); | 868 | pr_warning("illegal format\n"); |
863 | return tmp; | 869 | return tmp; |
864 | } | 870 | } |
865 | i += tmp; | 871 | i += tmp; |
@@ -980,6 +986,36 @@ static ssize_t pktgen_if_write(struct file *file, | |||
980 | (unsigned long long) pkt_dev->delay); | 986 | (unsigned long long) pkt_dev->delay); |
981 | return count; | 987 | return count; |
982 | } | 988 | } |
989 | if (!strcmp(name, "rate")) { | ||
990 | len = num_arg(&user_buffer[i], 10, &value); | ||
991 | if (len < 0) | ||
992 | return len; | ||
993 | |||
994 | i += len; | ||
995 | if (!value) | ||
996 | return len; | ||
997 | pkt_dev->delay = pkt_dev->min_pkt_size*8*NSEC_PER_USEC/value; | ||
998 | if (debug) | ||
999 | pr_info("Delay set at: %llu ns\n", pkt_dev->delay); | ||
1000 | |||
1001 | sprintf(pg_result, "OK: rate=%lu", value); | ||
1002 | return count; | ||
1003 | } | ||
1004 | if (!strcmp(name, "ratep")) { | ||
1005 | len = num_arg(&user_buffer[i], 10, &value); | ||
1006 | if (len < 0) | ||
1007 | return len; | ||
1008 | |||
1009 | i += len; | ||
1010 | if (!value) | ||
1011 | return len; | ||
1012 | pkt_dev->delay = NSEC_PER_SEC/value; | ||
1013 | if (debug) | ||
1014 | pr_info("Delay set at: %llu ns\n", pkt_dev->delay); | ||
1015 | |||
1016 | sprintf(pg_result, "OK: rate=%lu", value); | ||
1017 | return count; | ||
1018 | } | ||
983 | if (!strcmp(name, "udp_src_min")) { | 1019 | if (!strcmp(name, "udp_src_min")) { |
984 | len = num_arg(&user_buffer[i], 10, &value); | 1020 | len = num_arg(&user_buffer[i], 10, &value); |
985 | if (len < 0) | 1021 | if (len < 0) |
@@ -1398,18 +1434,12 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1398 | i += len; | 1434 | i += len; |
1399 | 1435 | ||
1400 | for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) { | 1436 | for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) { |
1401 | if (*v >= '0' && *v <= '9') { | 1437 | int value; |
1402 | *m *= 16; | 1438 | |
1403 | *m += *v - '0'; | 1439 | value = hex_to_bin(*v); |
1404 | } | 1440 | if (value >= 0) |
1405 | if (*v >= 'A' && *v <= 'F') { | 1441 | *m = *m * 16 + value; |
1406 | *m *= 16; | 1442 | |
1407 | *m += *v - 'A' + 10; | ||
1408 | } | ||
1409 | if (*v >= 'a' && *v <= 'f') { | ||
1410 | *m *= 16; | ||
1411 | *m += *v - 'a' + 10; | ||
1412 | } | ||
1413 | if (*v == ':') { | 1443 | if (*v == ':') { |
1414 | m++; | 1444 | m++; |
1415 | *m = 0; | 1445 | *m = 0; |
@@ -1440,18 +1470,12 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1440 | i += len; | 1470 | i += len; |
1441 | 1471 | ||
1442 | for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) { | 1472 | for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) { |
1443 | if (*v >= '0' && *v <= '9') { | 1473 | int value; |
1444 | *m *= 16; | 1474 | |
1445 | *m += *v - '0'; | 1475 | value = hex_to_bin(*v); |
1446 | } | 1476 | if (value >= 0) |
1447 | if (*v >= 'A' && *v <= 'F') { | 1477 | *m = *m * 16 + value; |
1448 | *m *= 16; | 1478 | |
1449 | *m += *v - 'A' + 10; | ||
1450 | } | ||
1451 | if (*v >= 'a' && *v <= 'f') { | ||
1452 | *m *= 16; | ||
1453 | *m += *v - 'a' + 10; | ||
1454 | } | ||
1455 | if (*v == ':') { | 1479 | if (*v == ':') { |
1456 | m++; | 1480 | m++; |
1457 | *m = 0; | 1481 | *m = 0; |
@@ -1740,7 +1764,7 @@ static ssize_t pktgen_thread_write(struct file *file, | |||
1740 | const char __user * user_buffer, | 1764 | const char __user * user_buffer, |
1741 | size_t count, loff_t * offset) | 1765 | size_t count, loff_t * offset) |
1742 | { | 1766 | { |
1743 | struct seq_file *seq = (struct seq_file *)file->private_data; | 1767 | struct seq_file *seq = file->private_data; |
1744 | struct pktgen_thread *t = seq->private; | 1768 | struct pktgen_thread *t = seq->private; |
1745 | int i = 0, max, len, ret; | 1769 | int i = 0, max, len, ret; |
1746 | char name[40]; | 1770 | char name[40]; |
@@ -1781,7 +1805,7 @@ static ssize_t pktgen_thread_write(struct file *file, | |||
1781 | name, (unsigned long)count); | 1805 | name, (unsigned long)count); |
1782 | 1806 | ||
1783 | if (!t) { | 1807 | if (!t) { |
1784 | printk(KERN_ERR "pktgen: ERROR: No thread\n"); | 1808 | pr_err("ERROR: No thread\n"); |
1785 | ret = -EINVAL; | 1809 | ret = -EINVAL; |
1786 | goto out; | 1810 | goto out; |
1787 | } | 1811 | } |
@@ -1874,7 +1898,7 @@ static void pktgen_mark_device(const char *ifname) | |||
1874 | int i = 0; | 1898 | int i = 0; |
1875 | 1899 | ||
1876 | mutex_lock(&pktgen_thread_lock); | 1900 | mutex_lock(&pktgen_thread_lock); |
1877 | pr_debug("pktgen: pktgen_mark_device marking %s for removal\n", ifname); | 1901 | pr_debug("%s: marking %s for removal\n", __func__, ifname); |
1878 | 1902 | ||
1879 | while (1) { | 1903 | while (1) { |
1880 | 1904 | ||
@@ -1883,15 +1907,14 @@ static void pktgen_mark_device(const char *ifname) | |||
1883 | break; /* success */ | 1907 | break; /* success */ |
1884 | 1908 | ||
1885 | mutex_unlock(&pktgen_thread_lock); | 1909 | mutex_unlock(&pktgen_thread_lock); |
1886 | pr_debug("pktgen: pktgen_mark_device waiting for %s " | 1910 | pr_debug("%s: waiting for %s to disappear....\n", |
1887 | "to disappear....\n", ifname); | 1911 | __func__, ifname); |
1888 | schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try)); | 1912 | schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try)); |
1889 | mutex_lock(&pktgen_thread_lock); | 1913 | mutex_lock(&pktgen_thread_lock); |
1890 | 1914 | ||
1891 | if (++i >= max_tries) { | 1915 | if (++i >= max_tries) { |
1892 | printk(KERN_ERR "pktgen_mark_device: timed out after " | 1916 | pr_err("%s: timed out after waiting %d msec for device %s to be removed\n", |
1893 | "waiting %d msec for device %s to be removed\n", | 1917 | __func__, msec_per_try * i, ifname); |
1894 | msec_per_try * i, ifname); | ||
1895 | break; | 1918 | break; |
1896 | } | 1919 | } |
1897 | 1920 | ||
@@ -1918,8 +1941,8 @@ static void pktgen_change_name(struct net_device *dev) | |||
1918 | &pktgen_if_fops, | 1941 | &pktgen_if_fops, |
1919 | pkt_dev); | 1942 | pkt_dev); |
1920 | if (!pkt_dev->entry) | 1943 | if (!pkt_dev->entry) |
1921 | printk(KERN_ERR "pktgen: can't move proc " | 1944 | pr_err("can't move proc entry for '%s'\n", |
1922 | " entry for '%s'\n", dev->name); | 1945 | dev->name); |
1923 | break; | 1946 | break; |
1924 | } | 1947 | } |
1925 | } | 1948 | } |
@@ -1983,15 +2006,15 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) | |||
1983 | 2006 | ||
1984 | odev = pktgen_dev_get_by_name(pkt_dev, ifname); | 2007 | odev = pktgen_dev_get_by_name(pkt_dev, ifname); |
1985 | if (!odev) { | 2008 | if (!odev) { |
1986 | printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); | 2009 | pr_err("no such netdevice: \"%s\"\n", ifname); |
1987 | return -ENODEV; | 2010 | return -ENODEV; |
1988 | } | 2011 | } |
1989 | 2012 | ||
1990 | if (odev->type != ARPHRD_ETHER) { | 2013 | if (odev->type != ARPHRD_ETHER) { |
1991 | printk(KERN_ERR "pktgen: not an ethernet device: \"%s\"\n", ifname); | 2014 | pr_err("not an ethernet device: \"%s\"\n", ifname); |
1992 | err = -EINVAL; | 2015 | err = -EINVAL; |
1993 | } else if (!netif_running(odev)) { | 2016 | } else if (!netif_running(odev)) { |
1994 | printk(KERN_ERR "pktgen: device is down: \"%s\"\n", ifname); | 2017 | pr_err("device is down: \"%s\"\n", ifname); |
1995 | err = -ENETDOWN; | 2018 | err = -ENETDOWN; |
1996 | } else { | 2019 | } else { |
1997 | pkt_dev->odev = odev; | 2020 | pkt_dev->odev = odev; |
@@ -2010,8 +2033,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2010 | int ntxq; | 2033 | int ntxq; |
2011 | 2034 | ||
2012 | if (!pkt_dev->odev) { | 2035 | if (!pkt_dev->odev) { |
2013 | printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in " | 2036 | pr_err("ERROR: pkt_dev->odev == NULL in setup_inject\n"); |
2014 | "setup_inject.\n"); | ||
2015 | sprintf(pkt_dev->result, | 2037 | sprintf(pkt_dev->result, |
2016 | "ERROR: pkt_dev->odev == NULL in setup_inject.\n"); | 2038 | "ERROR: pkt_dev->odev == NULL in setup_inject.\n"); |
2017 | return; | 2039 | return; |
@@ -2021,19 +2043,15 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2021 | ntxq = pkt_dev->odev->real_num_tx_queues; | 2043 | ntxq = pkt_dev->odev->real_num_tx_queues; |
2022 | 2044 | ||
2023 | if (ntxq <= pkt_dev->queue_map_min) { | 2045 | if (ntxq <= pkt_dev->queue_map_min) { |
2024 | printk(KERN_WARNING "pktgen: WARNING: Requested " | 2046 | pr_warning("WARNING: Requested queue_map_min (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", |
2025 | "queue_map_min (zero-based) (%d) exceeds valid range " | 2047 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, |
2026 | "[0 - %d] for (%d) queues on %s, resetting\n", | 2048 | pkt_dev->odevname); |
2027 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, | ||
2028 | pkt_dev->odevname); | ||
2029 | pkt_dev->queue_map_min = ntxq - 1; | 2049 | pkt_dev->queue_map_min = ntxq - 1; |
2030 | } | 2050 | } |
2031 | if (pkt_dev->queue_map_max >= ntxq) { | 2051 | if (pkt_dev->queue_map_max >= ntxq) { |
2032 | printk(KERN_WARNING "pktgen: WARNING: Requested " | 2052 | pr_warning("WARNING: Requested queue_map_max (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", |
2033 | "queue_map_max (zero-based) (%d) exceeds valid range " | 2053 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, |
2034 | "[0 - %d] for (%d) queues on %s, resetting\n", | 2054 | pkt_dev->odevname); |
2035 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, | ||
2036 | pkt_dev->odevname); | ||
2037 | pkt_dev->queue_map_max = ntxq - 1; | 2055 | pkt_dev->queue_map_max = ntxq - 1; |
2038 | } | 2056 | } |
2039 | 2057 | ||
@@ -2093,8 +2111,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2093 | } | 2111 | } |
2094 | rcu_read_unlock(); | 2112 | rcu_read_unlock(); |
2095 | if (err) | 2113 | if (err) |
2096 | printk(KERN_ERR "pktgen: ERROR: IPv6 link " | 2114 | pr_err("ERROR: IPv6 link address not available\n"); |
2097 | "address not availble.\n"); | ||
2098 | } | 2115 | } |
2099 | #endif | 2116 | #endif |
2100 | } else { | 2117 | } else { |
@@ -2142,15 +2159,15 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) | |||
2142 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 2159 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); |
2143 | hrtimer_set_expires(&t.timer, spin_until); | 2160 | hrtimer_set_expires(&t.timer, spin_until); |
2144 | 2161 | ||
2145 | remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer)); | 2162 | remaining = ktime_to_ns(hrtimer_expires_remaining(&t.timer)); |
2146 | if (remaining <= 0) { | 2163 | if (remaining <= 0) { |
2147 | pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay); | 2164 | pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay); |
2148 | return; | 2165 | return; |
2149 | } | 2166 | } |
2150 | 2167 | ||
2151 | start_time = ktime_now(); | 2168 | start_time = ktime_now(); |
2152 | if (remaining < 100) | 2169 | if (remaining < 100000) |
2153 | udelay(remaining); /* really small just spin */ | 2170 | ndelay(remaining); /* really small just spin */ |
2154 | else { | 2171 | else { |
2155 | /* see do_nanosleep */ | 2172 | /* see do_nanosleep */ |
2156 | hrtimer_init_sleeper(&t, current); | 2173 | hrtimer_init_sleeper(&t, current); |
@@ -2528,8 +2545,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
2528 | if (nhead > 0) { | 2545 | if (nhead > 0) { |
2529 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); | 2546 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); |
2530 | if (ret < 0) { | 2547 | if (ret < 0) { |
2531 | printk(KERN_ERR "Error expanding " | 2548 | pr_err("Error expanding ipsec packet %d\n", |
2532 | "ipsec packet %d\n", ret); | 2549 | ret); |
2533 | goto err; | 2550 | goto err; |
2534 | } | 2551 | } |
2535 | } | 2552 | } |
@@ -2538,8 +2555,7 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
2538 | skb_pull(skb, ETH_HLEN); | 2555 | skb_pull(skb, ETH_HLEN); |
2539 | ret = pktgen_output_ipsec(skb, pkt_dev); | 2556 | ret = pktgen_output_ipsec(skb, pkt_dev); |
2540 | if (ret) { | 2557 | if (ret) { |
2541 | printk(KERN_ERR "Error creating ipsec " | 2558 | pr_err("Error creating ipsec packet %d\n", ret); |
2542 | "packet %d\n", ret); | ||
2543 | goto err; | 2559 | goto err; |
2544 | } | 2560 | } |
2545 | /* restore ll */ | 2561 | /* restore ll */ |
@@ -3015,8 +3031,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
3015 | if (datalen < sizeof(struct pktgen_hdr)) { | 3031 | if (datalen < sizeof(struct pktgen_hdr)) { |
3016 | datalen = sizeof(struct pktgen_hdr); | 3032 | datalen = sizeof(struct pktgen_hdr); |
3017 | if (net_ratelimit()) | 3033 | if (net_ratelimit()) |
3018 | printk(KERN_INFO "pktgen: increased datalen to %d\n", | 3034 | pr_info("increased datalen to %d\n", datalen); |
3019 | datalen); | ||
3020 | } | 3035 | } |
3021 | 3036 | ||
3022 | udph->source = htons(pkt_dev->cur_udp_src); | 3037 | udph->source = htons(pkt_dev->cur_udp_src); |
@@ -3143,7 +3158,7 @@ static void pktgen_run(struct pktgen_thread *t) | |||
3143 | struct pktgen_dev *pkt_dev; | 3158 | struct pktgen_dev *pkt_dev; |
3144 | int started = 0; | 3159 | int started = 0; |
3145 | 3160 | ||
3146 | pr_debug("pktgen: entering pktgen_run. %p\n", t); | 3161 | func_enter(); |
3147 | 3162 | ||
3148 | if_lock(t); | 3163 | if_lock(t); |
3149 | list_for_each_entry(pkt_dev, &t->if_list, list) { | 3164 | list_for_each_entry(pkt_dev, &t->if_list, list) { |
@@ -3176,7 +3191,7 @@ static void pktgen_stop_all_threads_ifs(void) | |||
3176 | { | 3191 | { |
3177 | struct pktgen_thread *t; | 3192 | struct pktgen_thread *t; |
3178 | 3193 | ||
3179 | pr_debug("pktgen: entering pktgen_stop_all_threads_ifs.\n"); | 3194 | func_enter(); |
3180 | 3195 | ||
3181 | mutex_lock(&pktgen_thread_lock); | 3196 | mutex_lock(&pktgen_thread_lock); |
3182 | 3197 | ||
@@ -3241,7 +3256,7 @@ static void pktgen_run_all_threads(void) | |||
3241 | { | 3256 | { |
3242 | struct pktgen_thread *t; | 3257 | struct pktgen_thread *t; |
3243 | 3258 | ||
3244 | pr_debug("pktgen: entering pktgen_run_all_threads.\n"); | 3259 | func_enter(); |
3245 | 3260 | ||
3246 | mutex_lock(&pktgen_thread_lock); | 3261 | mutex_lock(&pktgen_thread_lock); |
3247 | 3262 | ||
@@ -3260,7 +3275,7 @@ static void pktgen_reset_all_threads(void) | |||
3260 | { | 3275 | { |
3261 | struct pktgen_thread *t; | 3276 | struct pktgen_thread *t; |
3262 | 3277 | ||
3263 | pr_debug("pktgen: entering pktgen_reset_all_threads.\n"); | 3278 | func_enter(); |
3264 | 3279 | ||
3265 | mutex_lock(&pktgen_thread_lock); | 3280 | mutex_lock(&pktgen_thread_lock); |
3266 | 3281 | ||
@@ -3310,8 +3325,8 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
3310 | int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1; | 3325 | int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1; |
3311 | 3326 | ||
3312 | if (!pkt_dev->running) { | 3327 | if (!pkt_dev->running) { |
3313 | printk(KERN_WARNING "pktgen: interface: %s is already " | 3328 | pr_warning("interface: %s is already stopped\n", |
3314 | "stopped\n", pkt_dev->odevname); | 3329 | pkt_dev->odevname); |
3315 | return -EINVAL; | 3330 | return -EINVAL; |
3316 | } | 3331 | } |
3317 | 3332 | ||
@@ -3347,7 +3362,7 @@ static void pktgen_stop(struct pktgen_thread *t) | |||
3347 | { | 3362 | { |
3348 | struct pktgen_dev *pkt_dev; | 3363 | struct pktgen_dev *pkt_dev; |
3349 | 3364 | ||
3350 | pr_debug("pktgen: entering pktgen_stop\n"); | 3365 | func_enter(); |
3351 | 3366 | ||
3352 | if_lock(t); | 3367 | if_lock(t); |
3353 | 3368 | ||
@@ -3367,7 +3382,7 @@ static void pktgen_rem_one_if(struct pktgen_thread *t) | |||
3367 | struct list_head *q, *n; | 3382 | struct list_head *q, *n; |
3368 | struct pktgen_dev *cur; | 3383 | struct pktgen_dev *cur; |
3369 | 3384 | ||
3370 | pr_debug("pktgen: entering pktgen_rem_one_if\n"); | 3385 | func_enter(); |
3371 | 3386 | ||
3372 | if_lock(t); | 3387 | if_lock(t); |
3373 | 3388 | ||
@@ -3393,9 +3408,10 @@ static void pktgen_rem_all_ifs(struct pktgen_thread *t) | |||
3393 | struct list_head *q, *n; | 3408 | struct list_head *q, *n; |
3394 | struct pktgen_dev *cur; | 3409 | struct pktgen_dev *cur; |
3395 | 3410 | ||
3411 | func_enter(); | ||
3412 | |||
3396 | /* Remove all devices, free mem */ | 3413 | /* Remove all devices, free mem */ |
3397 | 3414 | ||
3398 | pr_debug("pktgen: entering pktgen_rem_all_ifs\n"); | ||
3399 | if_lock(t); | 3415 | if_lock(t); |
3400 | 3416 | ||
3401 | list_for_each_safe(q, n, &t->if_list) { | 3417 | list_for_each_safe(q, n, &t->if_list) { |
@@ -3477,8 +3493,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
3477 | 3493 | ||
3478 | pkt_dev->skb = fill_packet(odev, pkt_dev); | 3494 | pkt_dev->skb = fill_packet(odev, pkt_dev); |
3479 | if (pkt_dev->skb == NULL) { | 3495 | if (pkt_dev->skb == NULL) { |
3480 | printk(KERN_ERR "pktgen: ERROR: couldn't " | 3496 | pr_err("ERROR: couldn't allocate skb in fill_packet\n"); |
3481 | "allocate skb in fill_packet.\n"); | ||
3482 | schedule(); | 3497 | schedule(); |
3483 | pkt_dev->clone_count--; /* back out increment, OOM */ | 3498 | pkt_dev->clone_count--; /* back out increment, OOM */ |
3484 | return; | 3499 | return; |
@@ -3558,8 +3573,7 @@ static int pktgen_thread_worker(void *arg) | |||
3558 | init_waitqueue_head(&t->queue); | 3573 | init_waitqueue_head(&t->queue); |
3559 | complete(&t->start_done); | 3574 | complete(&t->start_done); |
3560 | 3575 | ||
3561 | pr_debug("pktgen: starting pktgen/%d: pid=%d\n", | 3576 | pr_debug("starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); |
3562 | cpu, task_pid_nr(current)); | ||
3563 | 3577 | ||
3564 | set_current_state(TASK_INTERRUPTIBLE); | 3578 | set_current_state(TASK_INTERRUPTIBLE); |
3565 | 3579 | ||
@@ -3612,13 +3626,13 @@ static int pktgen_thread_worker(void *arg) | |||
3612 | set_current_state(TASK_INTERRUPTIBLE); | 3626 | set_current_state(TASK_INTERRUPTIBLE); |
3613 | } | 3627 | } |
3614 | 3628 | ||
3615 | pr_debug("pktgen: %s stopping all device\n", t->tsk->comm); | 3629 | pr_debug("%s stopping all device\n", t->tsk->comm); |
3616 | pktgen_stop(t); | 3630 | pktgen_stop(t); |
3617 | 3631 | ||
3618 | pr_debug("pktgen: %s removing all device\n", t->tsk->comm); | 3632 | pr_debug("%s removing all device\n", t->tsk->comm); |
3619 | pktgen_rem_all_ifs(t); | 3633 | pktgen_rem_all_ifs(t); |
3620 | 3634 | ||
3621 | pr_debug("pktgen: %s removing thread.\n", t->tsk->comm); | 3635 | pr_debug("%s removing thread\n", t->tsk->comm); |
3622 | pktgen_rem_thread(t); | 3636 | pktgen_rem_thread(t); |
3623 | 3637 | ||
3624 | return 0; | 3638 | return 0; |
@@ -3642,7 +3656,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | |||
3642 | } | 3656 | } |
3643 | 3657 | ||
3644 | if_unlock(t); | 3658 | if_unlock(t); |
3645 | pr_debug("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev); | 3659 | pr_debug("find_dev(%s) returning %p\n", ifname, pkt_dev); |
3646 | return pkt_dev; | 3660 | return pkt_dev; |
3647 | } | 3661 | } |
3648 | 3662 | ||
@@ -3658,8 +3672,7 @@ static int add_dev_to_thread(struct pktgen_thread *t, | |||
3658 | if_lock(t); | 3672 | if_lock(t); |
3659 | 3673 | ||
3660 | if (pkt_dev->pg_thread) { | 3674 | if (pkt_dev->pg_thread) { |
3661 | printk(KERN_ERR "pktgen: ERROR: already assigned " | 3675 | pr_err("ERROR: already assigned to a thread\n"); |
3662 | "to a thread.\n"); | ||
3663 | rv = -EBUSY; | 3676 | rv = -EBUSY; |
3664 | goto out; | 3677 | goto out; |
3665 | } | 3678 | } |
@@ -3685,7 +3698,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3685 | 3698 | ||
3686 | pkt_dev = __pktgen_NN_threads(ifname, FIND); | 3699 | pkt_dev = __pktgen_NN_threads(ifname, FIND); |
3687 | if (pkt_dev) { | 3700 | if (pkt_dev) { |
3688 | printk(KERN_ERR "pktgen: ERROR: interface already used.\n"); | 3701 | pr_err("ERROR: interface already used\n"); |
3689 | return -EBUSY; | 3702 | return -EBUSY; |
3690 | } | 3703 | } |
3691 | 3704 | ||
@@ -3730,7 +3743,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3730 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, | 3743 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
3731 | &pktgen_if_fops, pkt_dev); | 3744 | &pktgen_if_fops, pkt_dev); |
3732 | if (!pkt_dev->entry) { | 3745 | if (!pkt_dev->entry) { |
3733 | printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", | 3746 | pr_err("cannot create %s/%s procfs entry\n", |
3734 | PG_PROC_DIR, ifname); | 3747 | PG_PROC_DIR, ifname); |
3735 | err = -EINVAL; | 3748 | err = -EINVAL; |
3736 | goto out2; | 3749 | goto out2; |
@@ -3761,8 +3774,7 @@ static int __init pktgen_create_thread(int cpu) | |||
3761 | t = kzalloc_node(sizeof(struct pktgen_thread), GFP_KERNEL, | 3774 | t = kzalloc_node(sizeof(struct pktgen_thread), GFP_KERNEL, |
3762 | cpu_to_node(cpu)); | 3775 | cpu_to_node(cpu)); |
3763 | if (!t) { | 3776 | if (!t) { |
3764 | printk(KERN_ERR "pktgen: ERROR: out of memory, can't " | 3777 | pr_err("ERROR: out of memory, can't create new thread\n"); |
3765 | "create new thread.\n"); | ||
3766 | return -ENOMEM; | 3778 | return -ENOMEM; |
3767 | } | 3779 | } |
3768 | 3780 | ||
@@ -3776,8 +3788,7 @@ static int __init pktgen_create_thread(int cpu) | |||
3776 | 3788 | ||
3777 | p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); | 3789 | p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); |
3778 | if (IS_ERR(p)) { | 3790 | if (IS_ERR(p)) { |
3779 | printk(KERN_ERR "pktgen: kernel_thread() failed " | 3791 | pr_err("kernel_thread() failed for cpu %d\n", t->cpu); |
3780 | "for cpu %d\n", t->cpu); | ||
3781 | list_del(&t->th_list); | 3792 | list_del(&t->th_list); |
3782 | kfree(t); | 3793 | kfree(t); |
3783 | return PTR_ERR(p); | 3794 | return PTR_ERR(p); |
@@ -3788,7 +3799,7 @@ static int __init pktgen_create_thread(int cpu) | |||
3788 | pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir, | 3799 | pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir, |
3789 | &pktgen_thread_fops, t); | 3800 | &pktgen_thread_fops, t); |
3790 | if (!pe) { | 3801 | if (!pe) { |
3791 | printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", | 3802 | pr_err("cannot create %s/%s procfs entry\n", |
3792 | PG_PROC_DIR, t->tsk->comm); | 3803 | PG_PROC_DIR, t->tsk->comm); |
3793 | kthread_stop(p); | 3804 | kthread_stop(p); |
3794 | list_del(&t->th_list); | 3805 | list_del(&t->th_list); |
@@ -3822,11 +3833,10 @@ static int pktgen_remove_device(struct pktgen_thread *t, | |||
3822 | struct pktgen_dev *pkt_dev) | 3833 | struct pktgen_dev *pkt_dev) |
3823 | { | 3834 | { |
3824 | 3835 | ||
3825 | pr_debug("pktgen: remove_device pkt_dev=%p\n", pkt_dev); | 3836 | pr_debug("remove_device pkt_dev=%p\n", pkt_dev); |
3826 | 3837 | ||
3827 | if (pkt_dev->running) { | 3838 | if (pkt_dev->running) { |
3828 | printk(KERN_WARNING "pktgen: WARNING: trying to remove a " | 3839 | pr_warning("WARNING: trying to remove a running interface, stopping it now\n"); |
3829 | "running interface, stopping it now.\n"); | ||
3830 | pktgen_stop_device(pkt_dev); | 3840 | pktgen_stop_device(pkt_dev); |
3831 | } | 3841 | } |
3832 | 3842 | ||
@@ -3857,7 +3867,7 @@ static int __init pg_init(void) | |||
3857 | int cpu; | 3867 | int cpu; |
3858 | struct proc_dir_entry *pe; | 3868 | struct proc_dir_entry *pe; |
3859 | 3869 | ||
3860 | printk(KERN_INFO "%s", version); | 3870 | pr_info("%s", version); |
3861 | 3871 | ||
3862 | pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); | 3872 | pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); |
3863 | if (!pg_proc_dir) | 3873 | if (!pg_proc_dir) |
@@ -3865,8 +3875,7 @@ static int __init pg_init(void) | |||
3865 | 3875 | ||
3866 | pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); | 3876 | pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); |
3867 | if (pe == NULL) { | 3877 | if (pe == NULL) { |
3868 | printk(KERN_ERR "pktgen: ERROR: cannot create %s " | 3878 | pr_err("ERROR: cannot create %s procfs entry\n", PGCTRL); |
3869 | "procfs entry.\n", PGCTRL); | ||
3870 | proc_net_remove(&init_net, PG_PROC_DIR); | 3879 | proc_net_remove(&init_net, PG_PROC_DIR); |
3871 | return -EINVAL; | 3880 | return -EINVAL; |
3872 | } | 3881 | } |
@@ -3879,13 +3888,12 @@ static int __init pg_init(void) | |||
3879 | 3888 | ||
3880 | err = pktgen_create_thread(cpu); | 3889 | err = pktgen_create_thread(cpu); |
3881 | if (err) | 3890 | if (err) |
3882 | printk(KERN_WARNING "pktgen: WARNING: Cannot create " | 3891 | pr_warning("WARNING: Cannot create thread for cpu %d (%d)\n", |
3883 | "thread for cpu %d (%d)\n", cpu, err); | 3892 | cpu, err); |
3884 | } | 3893 | } |
3885 | 3894 | ||
3886 | if (list_empty(&pktgen_threads)) { | 3895 | if (list_empty(&pktgen_threads)) { |
3887 | printk(KERN_ERR "pktgen: ERROR: Initialization failed for " | 3896 | pr_err("ERROR: Initialization failed for all threads\n"); |
3888 | "all threads\n"); | ||
3889 | unregister_netdevice_notifier(&pktgen_notifier_block); | 3897 | unregister_netdevice_notifier(&pktgen_notifier_block); |
3890 | remove_proc_entry(PGCTRL, pg_proc_dir); | 3898 | remove_proc_entry(PGCTRL, pg_proc_dir); |
3891 | proc_net_remove(&init_net, PG_PROC_DIR); | 3899 | proc_net_remove(&init_net, PG_PROC_DIR); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1a2af24e9e3d..f78d821bd935 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -579,7 +579,7 @@ static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, | |||
579 | } | 579 | } |
580 | 580 | ||
581 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | 581 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, |
582 | const struct net_device_stats *b) | 582 | const struct rtnl_link_stats64 *b) |
583 | { | 583 | { |
584 | a->rx_packets = b->rx_packets; | 584 | a->rx_packets = b->rx_packets; |
585 | a->tx_packets = b->tx_packets; | 585 | a->tx_packets = b->tx_packets; |
@@ -610,7 +610,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
610 | a->tx_compressed = b->tx_compressed; | 610 | a->tx_compressed = b->tx_compressed; |
611 | } | 611 | } |
612 | 612 | ||
613 | static void copy_rtnl_link_stats64(void *v, const struct net_device_stats *b) | 613 | static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) |
614 | { | 614 | { |
615 | struct rtnl_link_stats64 a; | 615 | struct rtnl_link_stats64 a; |
616 | 616 | ||
@@ -686,7 +686,7 @@ static size_t rtnl_port_size(const struct net_device *dev) | |||
686 | return port_self_size; | 686 | return port_self_size; |
687 | } | 687 | } |
688 | 688 | ||
689 | static inline size_t if_nlmsg_size(const struct net_device *dev) | 689 | static noinline size_t if_nlmsg_size(const struct net_device *dev) |
690 | { | 690 | { |
691 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | 691 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
692 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | 692 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ |
@@ -791,7 +791,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
791 | { | 791 | { |
792 | struct ifinfomsg *ifm; | 792 | struct ifinfomsg *ifm; |
793 | struct nlmsghdr *nlh; | 793 | struct nlmsghdr *nlh; |
794 | const struct net_device_stats *stats; | 794 | struct rtnl_link_stats64 temp; |
795 | const struct rtnl_link_stats64 *stats; | ||
795 | struct nlattr *attr; | 796 | struct nlattr *attr; |
796 | 797 | ||
797 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); | 798 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); |
@@ -847,7 +848,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
847 | if (attr == NULL) | 848 | if (attr == NULL) |
848 | goto nla_put_failure; | 849 | goto nla_put_failure; |
849 | 850 | ||
850 | stats = dev_get_stats(dev); | 851 | stats = dev_get_stats(dev, &temp); |
851 | copy_rtnl_link_stats(nla_data(attr), stats); | 852 | copy_rtnl_link_stats(nla_data(attr), stats); |
852 | 853 | ||
853 | attr = nla_reserve(skb, IFLA_STATS64, | 854 | attr = nla_reserve(skb, IFLA_STATS64, |
diff --git a/net/core/scm.c b/net/core/scm.c index b88f6f9d0b97..413cab89017d 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -130,6 +130,7 @@ void __scm_destroy(struct scm_cookie *scm) | |||
130 | } | 130 | } |
131 | } | 131 | } |
132 | } | 132 | } |
133 | EXPORT_SYMBOL(__scm_destroy); | ||
133 | 134 | ||
134 | int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | 135 | int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) |
135 | { | 136 | { |
@@ -170,6 +171,30 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
170 | err = scm_check_creds(&p->creds); | 171 | err = scm_check_creds(&p->creds); |
171 | if (err) | 172 | if (err) |
172 | goto error; | 173 | goto error; |
174 | |||
175 | if (pid_vnr(p->pid) != p->creds.pid) { | ||
176 | struct pid *pid; | ||
177 | err = -ESRCH; | ||
178 | pid = find_get_pid(p->creds.pid); | ||
179 | if (!pid) | ||
180 | goto error; | ||
181 | put_pid(p->pid); | ||
182 | p->pid = pid; | ||
183 | } | ||
184 | |||
185 | if ((p->cred->euid != p->creds.uid) || | ||
186 | (p->cred->egid != p->creds.gid)) { | ||
187 | struct cred *cred; | ||
188 | err = -ENOMEM; | ||
189 | cred = prepare_creds(); | ||
190 | if (!cred) | ||
191 | goto error; | ||
192 | |||
193 | cred->uid = cred->euid = p->creds.uid; | ||
194 | cred->gid = cred->egid = p->creds.uid; | ||
195 | put_cred(p->cred); | ||
196 | p->cred = cred; | ||
197 | } | ||
173 | break; | 198 | break; |
174 | default: | 199 | default: |
175 | goto error; | 200 | goto error; |
@@ -187,6 +212,7 @@ error: | |||
187 | scm_destroy(p); | 212 | scm_destroy(p); |
188 | return err; | 213 | return err; |
189 | } | 214 | } |
215 | EXPORT_SYMBOL(__scm_send); | ||
190 | 216 | ||
191 | int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) | 217 | int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) |
192 | { | 218 | { |
@@ -225,6 +251,7 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) | |||
225 | out: | 251 | out: |
226 | return err; | 252 | return err; |
227 | } | 253 | } |
254 | EXPORT_SYMBOL(put_cmsg); | ||
228 | 255 | ||
229 | void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | 256 | void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) |
230 | { | 257 | { |
@@ -294,6 +321,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
294 | */ | 321 | */ |
295 | __scm_destroy(scm); | 322 | __scm_destroy(scm); |
296 | } | 323 | } |
324 | EXPORT_SYMBOL(scm_detach_fds); | ||
297 | 325 | ||
298 | struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) | 326 | struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) |
299 | { | 327 | { |
@@ -311,9 +339,4 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) | |||
311 | } | 339 | } |
312 | return new_fpl; | 340 | return new_fpl; |
313 | } | 341 | } |
314 | |||
315 | EXPORT_SYMBOL(__scm_destroy); | ||
316 | EXPORT_SYMBOL(__scm_send); | ||
317 | EXPORT_SYMBOL(put_cmsg); | ||
318 | EXPORT_SYMBOL(scm_detach_fds); | ||
319 | EXPORT_SYMBOL(scm_fp_dup); | 342 | EXPORT_SYMBOL(scm_fp_dup); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 34432b4e96bb..3a2513f0d0c3 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -817,7 +817,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
817 | memcpy(data + nhead, skb->head, skb->tail - skb->head); | 817 | memcpy(data + nhead, skb->head, skb->tail - skb->head); |
818 | #endif | 818 | #endif |
819 | memcpy(data + size, skb_end_pointer(skb), | 819 | memcpy(data + size, skb_end_pointer(skb), |
820 | sizeof(struct skb_shared_info)); | 820 | offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); |
821 | 821 | ||
822 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 822 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
823 | get_page(skb_shinfo(skb)->frags[i].page); | 823 | get_page(skb_shinfo(skb)->frags[i].page); |
@@ -843,7 +843,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
843 | skb->network_header += off; | 843 | skb->network_header += off; |
844 | if (skb_mac_header_was_set(skb)) | 844 | if (skb_mac_header_was_set(skb)) |
845 | skb->mac_header += off; | 845 | skb->mac_header += off; |
846 | skb->csum_start += nhead; | 846 | /* Only adjust this if it actually is csum_start rather than csum */ |
847 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
848 | skb->csum_start += nhead; | ||
847 | skb->cloned = 0; | 849 | skb->cloned = 0; |
848 | skb->hdr_len = 0; | 850 | skb->hdr_len = 0; |
849 | skb->nohdr = 0; | 851 | skb->nohdr = 0; |
@@ -930,7 +932,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
930 | copy_skb_header(n, skb); | 932 | copy_skb_header(n, skb); |
931 | 933 | ||
932 | off = newheadroom - oldheadroom; | 934 | off = newheadroom - oldheadroom; |
933 | n->csum_start += off; | 935 | if (n->ip_summed == CHECKSUM_PARTIAL) |
936 | n->csum_start += off; | ||
934 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 937 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
935 | n->transport_header += off; | 938 | n->transport_header += off; |
936 | n->network_header += off; | 939 | n->network_header += off; |
@@ -2483,7 +2486,6 @@ unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) | |||
2483 | skb_postpull_rcsum(skb, skb->data, len); | 2486 | skb_postpull_rcsum(skb, skb->data, len); |
2484 | return skb->data += len; | 2487 | return skb->data += len; |
2485 | } | 2488 | } |
2486 | |||
2487 | EXPORT_SYMBOL_GPL(skb_pull_rcsum); | 2489 | EXPORT_SYMBOL_GPL(skb_pull_rcsum); |
2488 | 2490 | ||
2489 | /** | 2491 | /** |
diff --git a/net/core/sock.c b/net/core/sock.c index 2cf7f9f7e775..b05b9b6ddb87 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -110,6 +110,7 @@ | |||
110 | #include <linux/tcp.h> | 110 | #include <linux/tcp.h> |
111 | #include <linux/init.h> | 111 | #include <linux/init.h> |
112 | #include <linux/highmem.h> | 112 | #include <linux/highmem.h> |
113 | #include <linux/user_namespace.h> | ||
113 | 114 | ||
114 | #include <asm/uaccess.h> | 115 | #include <asm/uaccess.h> |
115 | #include <asm/system.h> | 116 | #include <asm/system.h> |
@@ -156,7 +157,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
156 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | 157 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , |
157 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
158 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
159 | "sk_lock-AF_IEEE802154", | 160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , |
160 | "sk_lock-AF_MAX" | 161 | "sk_lock-AF_MAX" |
161 | }; | 162 | }; |
162 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
@@ -172,7 +173,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
172 | "slock-27" , "slock-28" , "slock-AF_CAN" , | 173 | "slock-27" , "slock-28" , "slock-AF_CAN" , |
173 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
174 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
175 | "slock-AF_IEEE802154", | 176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , |
176 | "slock-AF_MAX" | 177 | "slock-AF_MAX" |
177 | }; | 178 | }; |
178 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
@@ -188,7 +189,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
188 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 189 | "clock-27" , "clock-28" , "clock-AF_CAN" , |
189 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
190 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
191 | "clock-AF_IEEE802154", | 192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , |
192 | "clock-AF_MAX" | 193 | "clock-AF_MAX" |
193 | }; | 194 | }; |
194 | 195 | ||
@@ -749,6 +750,20 @@ set_rcvbuf: | |||
749 | EXPORT_SYMBOL(sock_setsockopt); | 750 | EXPORT_SYMBOL(sock_setsockopt); |
750 | 751 | ||
751 | 752 | ||
753 | void cred_to_ucred(struct pid *pid, const struct cred *cred, | ||
754 | struct ucred *ucred) | ||
755 | { | ||
756 | ucred->pid = pid_vnr(pid); | ||
757 | ucred->uid = ucred->gid = -1; | ||
758 | if (cred) { | ||
759 | struct user_namespace *current_ns = current_user_ns(); | ||
760 | |||
761 | ucred->uid = user_ns_map_uid(current_ns, cred, cred->euid); | ||
762 | ucred->gid = user_ns_map_gid(current_ns, cred, cred->egid); | ||
763 | } | ||
764 | } | ||
765 | EXPORT_SYMBOL_GPL(cred_to_ucred); | ||
766 | |||
752 | int sock_getsockopt(struct socket *sock, int level, int optname, | 767 | int sock_getsockopt(struct socket *sock, int level, int optname, |
753 | char __user *optval, int __user *optlen) | 768 | char __user *optval, int __user *optlen) |
754 | { | 769 | { |
@@ -901,11 +916,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
901 | break; | 916 | break; |
902 | 917 | ||
903 | case SO_PEERCRED: | 918 | case SO_PEERCRED: |
904 | if (len > sizeof(sk->sk_peercred)) | 919 | { |
905 | len = sizeof(sk->sk_peercred); | 920 | struct ucred peercred; |
906 | if (copy_to_user(optval, &sk->sk_peercred, len)) | 921 | if (len > sizeof(peercred)) |
922 | len = sizeof(peercred); | ||
923 | cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred); | ||
924 | if (copy_to_user(optval, &peercred, len)) | ||
907 | return -EFAULT; | 925 | return -EFAULT; |
908 | goto lenout; | 926 | goto lenout; |
927 | } | ||
909 | 928 | ||
910 | case SO_PEERNAME: | 929 | case SO_PEERNAME: |
911 | { | 930 | { |
@@ -1119,6 +1138,9 @@ static void __sk_free(struct sock *sk) | |||
1119 | printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", | 1138 | printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", |
1120 | __func__, atomic_read(&sk->sk_omem_alloc)); | 1139 | __func__, atomic_read(&sk->sk_omem_alloc)); |
1121 | 1140 | ||
1141 | if (sk->sk_peer_cred) | ||
1142 | put_cred(sk->sk_peer_cred); | ||
1143 | put_pid(sk->sk_peer_pid); | ||
1122 | put_net(sock_net(sk)); | 1144 | put_net(sock_net(sk)); |
1123 | sk_prot_free(sk->sk_prot_creator, sk); | 1145 | sk_prot_free(sk->sk_prot_creator, sk); |
1124 | } | 1146 | } |
@@ -1317,9 +1339,10 @@ EXPORT_SYMBOL(sock_wfree); | |||
1317 | void sock_rfree(struct sk_buff *skb) | 1339 | void sock_rfree(struct sk_buff *skb) |
1318 | { | 1340 | { |
1319 | struct sock *sk = skb->sk; | 1341 | struct sock *sk = skb->sk; |
1342 | unsigned int len = skb->truesize; | ||
1320 | 1343 | ||
1321 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); | 1344 | atomic_sub(len, &sk->sk_rmem_alloc); |
1322 | sk_mem_uncharge(skb->sk, skb->truesize); | 1345 | sk_mem_uncharge(sk, len); |
1323 | } | 1346 | } |
1324 | EXPORT_SYMBOL(sock_rfree); | 1347 | EXPORT_SYMBOL(sock_rfree); |
1325 | 1348 | ||
@@ -1954,9 +1977,8 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1954 | sk->sk_sndmsg_page = NULL; | 1977 | sk->sk_sndmsg_page = NULL; |
1955 | sk->sk_sndmsg_off = 0; | 1978 | sk->sk_sndmsg_off = 0; |
1956 | 1979 | ||
1957 | sk->sk_peercred.pid = 0; | 1980 | sk->sk_peer_pid = NULL; |
1958 | sk->sk_peercred.uid = -1; | 1981 | sk->sk_peer_cred = NULL; |
1959 | sk->sk_peercred.gid = -1; | ||
1960 | sk->sk_write_pending = 0; | 1982 | sk->sk_write_pending = 0; |
1961 | sk->sk_rcvlowat = 1; | 1983 | sk->sk_rcvlowat = 1; |
1962 | sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; | 1984 | sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; |
@@ -2210,8 +2232,7 @@ static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR); | |||
2210 | #ifdef CONFIG_NET_NS | 2232 | #ifdef CONFIG_NET_NS |
2211 | void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) | 2233 | void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) |
2212 | { | 2234 | { |
2213 | int cpu = smp_processor_id(); | 2235 | __this_cpu_add(net->core.inuse->val[prot->inuse_idx], val); |
2214 | per_cpu_ptr(net->core.inuse, cpu)->val[prot->inuse_idx] += val; | ||
2215 | } | 2236 | } |
2216 | EXPORT_SYMBOL_GPL(sock_prot_inuse_add); | 2237 | EXPORT_SYMBOL_GPL(sock_prot_inuse_add); |
2217 | 2238 | ||
@@ -2257,7 +2278,7 @@ static DEFINE_PER_CPU(struct prot_inuse, prot_inuse); | |||
2257 | 2278 | ||
2258 | void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) | 2279 | void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) |
2259 | { | 2280 | { |
2260 | __get_cpu_var(prot_inuse).val[prot->inuse_idx] += val; | 2281 | __this_cpu_add(prot_inuse.val[prot->inuse_idx], val); |
2261 | } | 2282 | } |
2262 | EXPORT_SYMBOL_GPL(sock_prot_inuse_add); | 2283 | EXPORT_SYMBOL_GPL(sock_prot_inuse_add); |
2263 | 2284 | ||
diff --git a/net/core/stream.c b/net/core/stream.c index cc196f42b8d8..d959e0f41528 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -43,7 +43,6 @@ void sk_stream_write_space(struct sock *sk) | |||
43 | rcu_read_unlock(); | 43 | rcu_read_unlock(); |
44 | } | 44 | } |
45 | } | 45 | } |
46 | |||
47 | EXPORT_SYMBOL(sk_stream_write_space); | 46 | EXPORT_SYMBOL(sk_stream_write_space); |
48 | 47 | ||
49 | /** | 48 | /** |
@@ -81,7 +80,6 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) | |||
81 | } while (!done); | 80 | } while (!done); |
82 | return 0; | 81 | return 0; |
83 | } | 82 | } |
84 | |||
85 | EXPORT_SYMBOL(sk_stream_wait_connect); | 83 | EXPORT_SYMBOL(sk_stream_wait_connect); |
86 | 84 | ||
87 | /** | 85 | /** |
@@ -109,7 +107,6 @@ void sk_stream_wait_close(struct sock *sk, long timeout) | |||
109 | finish_wait(sk_sleep(sk), &wait); | 107 | finish_wait(sk_sleep(sk), &wait); |
110 | } | 108 | } |
111 | } | 109 | } |
112 | |||
113 | EXPORT_SYMBOL(sk_stream_wait_close); | 110 | EXPORT_SYMBOL(sk_stream_wait_close); |
114 | 111 | ||
115 | /** | 112 | /** |
@@ -174,7 +171,6 @@ do_interrupted: | |||
174 | err = sock_intr_errno(*timeo_p); | 171 | err = sock_intr_errno(*timeo_p); |
175 | goto out; | 172 | goto out; |
176 | } | 173 | } |
177 | |||
178 | EXPORT_SYMBOL(sk_stream_wait_memory); | 174 | EXPORT_SYMBOL(sk_stream_wait_memory); |
179 | 175 | ||
180 | int sk_stream_error(struct sock *sk, int flags, int err) | 176 | int sk_stream_error(struct sock *sk, int flags, int err) |
@@ -185,7 +181,6 @@ int sk_stream_error(struct sock *sk, int flags, int err) | |||
185 | send_sig(SIGPIPE, current, 0); | 181 | send_sig(SIGPIPE, current, 0); |
186 | return err; | 182 | return err; |
187 | } | 183 | } |
188 | |||
189 | EXPORT_SYMBOL(sk_stream_error); | 184 | EXPORT_SYMBOL(sk_stream_error); |
190 | 185 | ||
191 | void sk_stream_kill_queues(struct sock *sk) | 186 | void sk_stream_kill_queues(struct sock *sk) |
@@ -210,5 +205,4 @@ void sk_stream_kill_queues(struct sock *sk) | |||
210 | * have gone away, only the net layer knows can touch it. | 205 | * have gone away, only the net layer knows can touch it. |
211 | */ | 206 | */ |
212 | } | 207 | } |
213 | |||
214 | EXPORT_SYMBOL(sk_stream_kill_queues); | 208 | EXPORT_SYMBOL(sk_stream_kill_queues); |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c new file mode 100644 index 000000000000..0ae6c22da85b --- /dev/null +++ b/net/core/timestamping.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * PTP 1588 clock support - support for timestamping in PHY devices | ||
3 | * | ||
4 | * Copyright (C) 2010 OMICRON electronics GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | #include <linux/errqueue.h> | ||
21 | #include <linux/phy.h> | ||
22 | #include <linux/ptp_classify.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | |||
25 | static struct sock_filter ptp_filter[] = { | ||
26 | PTP_FILTER | ||
27 | }; | ||
28 | |||
29 | static unsigned int classify(struct sk_buff *skb) | ||
30 | { | ||
31 | if (likely(skb->dev && | ||
32 | skb->dev->phydev && | ||
33 | skb->dev->phydev->drv)) | ||
34 | return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter)); | ||
35 | else | ||
36 | return PTP_CLASS_NONE; | ||
37 | } | ||
38 | |||
39 | void skb_clone_tx_timestamp(struct sk_buff *skb) | ||
40 | { | ||
41 | struct phy_device *phydev; | ||
42 | struct sk_buff *clone; | ||
43 | struct sock *sk = skb->sk; | ||
44 | unsigned int type; | ||
45 | |||
46 | if (!sk) | ||
47 | return; | ||
48 | |||
49 | type = classify(skb); | ||
50 | |||
51 | switch (type) { | ||
52 | case PTP_CLASS_V1_IPV4: | ||
53 | case PTP_CLASS_V1_IPV6: | ||
54 | case PTP_CLASS_V2_IPV4: | ||
55 | case PTP_CLASS_V2_IPV6: | ||
56 | case PTP_CLASS_V2_L2: | ||
57 | case PTP_CLASS_V2_VLAN: | ||
58 | phydev = skb->dev->phydev; | ||
59 | if (likely(phydev->drv->txtstamp)) { | ||
60 | clone = skb_clone(skb, GFP_ATOMIC); | ||
61 | if (!clone) | ||
62 | return; | ||
63 | clone->sk = sk; | ||
64 | phydev->drv->txtstamp(phydev, clone, type); | ||
65 | } | ||
66 | break; | ||
67 | default: | ||
68 | break; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | void skb_complete_tx_timestamp(struct sk_buff *skb, | ||
73 | struct skb_shared_hwtstamps *hwtstamps) | ||
74 | { | ||
75 | struct sock *sk = skb->sk; | ||
76 | struct sock_exterr_skb *serr; | ||
77 | int err; | ||
78 | |||
79 | if (!hwtstamps) | ||
80 | return; | ||
81 | |||
82 | *skb_hwtstamps(skb) = *hwtstamps; | ||
83 | serr = SKB_EXT_ERR(skb); | ||
84 | memset(serr, 0, sizeof(*serr)); | ||
85 | serr->ee.ee_errno = ENOMSG; | ||
86 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | ||
87 | skb->sk = NULL; | ||
88 | err = sock_queue_err_skb(sk, skb); | ||
89 | if (err) | ||
90 | kfree_skb(skb); | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); | ||
93 | |||
94 | bool skb_defer_rx_timestamp(struct sk_buff *skb) | ||
95 | { | ||
96 | struct phy_device *phydev; | ||
97 | unsigned int type; | ||
98 | |||
99 | skb_push(skb, ETH_HLEN); | ||
100 | |||
101 | type = classify(skb); | ||
102 | |||
103 | skb_pull(skb, ETH_HLEN); | ||
104 | |||
105 | switch (type) { | ||
106 | case PTP_CLASS_V1_IPV4: | ||
107 | case PTP_CLASS_V1_IPV6: | ||
108 | case PTP_CLASS_V2_IPV4: | ||
109 | case PTP_CLASS_V2_IPV6: | ||
110 | case PTP_CLASS_V2_L2: | ||
111 | case PTP_CLASS_V2_VLAN: | ||
112 | phydev = skb->dev->phydev; | ||
113 | if (likely(phydev->drv->rxtstamp)) | ||
114 | return phydev->drv->rxtstamp(phydev, skb, type); | ||
115 | break; | ||
116 | default: | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | return false; | ||
121 | } | ||
122 | |||
123 | void __init skb_timestamping_init(void) | ||
124 | { | ||
125 | BUG_ON(sk_chk_filter(ptp_filter, ARRAY_SIZE(ptp_filter))); | ||
126 | } | ||
diff --git a/net/core/utils.c b/net/core/utils.c index 838250241d26..f41854470539 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -77,7 +77,6 @@ __be32 in_aton(const char *str) | |||
77 | } | 77 | } |
78 | return(htonl(l)); | 78 | return(htonl(l)); |
79 | } | 79 | } |
80 | |||
81 | EXPORT_SYMBOL(in_aton); | 80 | EXPORT_SYMBOL(in_aton); |
82 | 81 | ||
83 | #define IN6PTON_XDIGIT 0x00010000 | 82 | #define IN6PTON_XDIGIT 0x00010000 |
@@ -162,7 +161,6 @@ out: | |||
162 | *end = s; | 161 | *end = s; |
163 | return ret; | 162 | return ret; |
164 | } | 163 | } |
165 | |||
166 | EXPORT_SYMBOL(in4_pton); | 164 | EXPORT_SYMBOL(in4_pton); |
167 | 165 | ||
168 | int in6_pton(const char *src, int srclen, | 166 | int in6_pton(const char *src, int srclen, |
@@ -280,7 +278,6 @@ out: | |||
280 | *end = s; | 278 | *end = s; |
281 | return ret; | 279 | return ret; |
282 | } | 280 | } |
283 | |||
284 | EXPORT_SYMBOL(in6_pton); | 281 | EXPORT_SYMBOL(in6_pton); |
285 | 282 | ||
286 | void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, | 283 | void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, |