diff options
author | David S. Miller <davem@davemloft.net> | 2015-07-23 03:41:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-23 03:41:16 -0400 |
commit | c5e40ee287db61a79af1746954ee03ebbf1ff8a3 (patch) | |
tree | 007da00e75e9b84766ac4868421705300e1e2e14 /net/core | |
parent | 052831879945be0d9fad2216b127147c565ec1b1 (diff) | |
parent | c5dfd654d0ec0a28fe81e7bd4d4fd984a9855e09 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/bridge/br_mdb.c
br_mdb.c conflict was a function call being removed to fix a bug in
'net' but whose signature was changed in 'net-next'.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/datagram.c | 56 | ||||
-rw-r--r-- | net/core/dst.c | 4 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 11 |
3 files changed, 57 insertions, 14 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index b80fb91bb3f7..4967262b2707 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -131,6 +131,35 @@ out_noerr: | |||
131 | goto out; | 131 | goto out; |
132 | } | 132 | } |
133 | 133 | ||
134 | static int skb_set_peeked(struct sk_buff *skb) | ||
135 | { | ||
136 | struct sk_buff *nskb; | ||
137 | |||
138 | if (skb->peeked) | ||
139 | return 0; | ||
140 | |||
141 | /* We have to unshare an skb before modifying it. */ | ||
142 | if (!skb_shared(skb)) | ||
143 | goto done; | ||
144 | |||
145 | nskb = skb_clone(skb, GFP_ATOMIC); | ||
146 | if (!nskb) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | skb->prev->next = nskb; | ||
150 | skb->next->prev = nskb; | ||
151 | nskb->prev = skb->prev; | ||
152 | nskb->next = skb->next; | ||
153 | |||
154 | consume_skb(skb); | ||
155 | skb = nskb; | ||
156 | |||
157 | done: | ||
158 | skb->peeked = 1; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
134 | /** | 163 | /** |
135 | * __skb_recv_datagram - Receive a datagram skbuff | 164 | * __skb_recv_datagram - Receive a datagram skbuff |
136 | * @sk: socket | 165 | * @sk: socket |
@@ -165,7 +194,9 @@ out_noerr: | |||
165 | struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | 194 | struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, |
166 | int *peeked, int *off, int *err) | 195 | int *peeked, int *off, int *err) |
167 | { | 196 | { |
197 | struct sk_buff_head *queue = &sk->sk_receive_queue; | ||
168 | struct sk_buff *skb, *last; | 198 | struct sk_buff *skb, *last; |
199 | unsigned long cpu_flags; | ||
169 | long timeo; | 200 | long timeo; |
170 | /* | 201 | /* |
171 | * Caller is allowed not to check sk->sk_err before skb_recv_datagram() | 202 | * Caller is allowed not to check sk->sk_err before skb_recv_datagram() |
@@ -184,8 +215,6 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
184 | * Look at current nfs client by the way... | 215 | * Look at current nfs client by the way... |
185 | * However, this function was correct in any case. 8) | 216 | * However, this function was correct in any case. 8) |
186 | */ | 217 | */ |
187 | unsigned long cpu_flags; | ||
188 | struct sk_buff_head *queue = &sk->sk_receive_queue; | ||
189 | int _off = *off; | 218 | int _off = *off; |
190 | 219 | ||
191 | last = (struct sk_buff *)queue; | 220 | last = (struct sk_buff *)queue; |
@@ -199,7 +228,11 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
199 | _off -= skb->len; | 228 | _off -= skb->len; |
200 | continue; | 229 | continue; |
201 | } | 230 | } |
202 | skb->peeked = 1; | 231 | |
232 | error = skb_set_peeked(skb); | ||
233 | if (error) | ||
234 | goto unlock_err; | ||
235 | |||
203 | atomic_inc(&skb->users); | 236 | atomic_inc(&skb->users); |
204 | } else | 237 | } else |
205 | __skb_unlink(skb, queue); | 238 | __skb_unlink(skb, queue); |
@@ -223,6 +256,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, | |||
223 | 256 | ||
224 | return NULL; | 257 | return NULL; |
225 | 258 | ||
259 | unlock_err: | ||
260 | spin_unlock_irqrestore(&queue->lock, cpu_flags); | ||
226 | no_packet: | 261 | no_packet: |
227 | *err = error; | 262 | *err = error; |
228 | return NULL; | 263 | return NULL; |
@@ -622,7 +657,8 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len) | |||
622 | !skb->csum_complete_sw) | 657 | !skb->csum_complete_sw) |
623 | netdev_rx_csum_fault(skb->dev); | 658 | netdev_rx_csum_fault(skb->dev); |
624 | } | 659 | } |
625 | skb->csum_valid = !sum; | 660 | if (!skb_shared(skb)) |
661 | skb->csum_valid = !sum; | ||
626 | return sum; | 662 | return sum; |
627 | } | 663 | } |
628 | EXPORT_SYMBOL(__skb_checksum_complete_head); | 664 | EXPORT_SYMBOL(__skb_checksum_complete_head); |
@@ -642,11 +678,13 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb) | |||
642 | netdev_rx_csum_fault(skb->dev); | 678 | netdev_rx_csum_fault(skb->dev); |
643 | } | 679 | } |
644 | 680 | ||
645 | /* Save full packet checksum */ | 681 | if (!skb_shared(skb)) { |
646 | skb->csum = csum; | 682 | /* Save full packet checksum */ |
647 | skb->ip_summed = CHECKSUM_COMPLETE; | 683 | skb->csum = csum; |
648 | skb->csum_complete_sw = 1; | 684 | skb->ip_summed = CHECKSUM_COMPLETE; |
649 | skb->csum_valid = !sum; | 685 | skb->csum_complete_sw = 1; |
686 | skb->csum_valid = !sum; | ||
687 | } | ||
650 | 688 | ||
651 | return sum; | 689 | return sum; |
652 | } | 690 | } |
diff --git a/net/core/dst.c b/net/core/dst.c index 917364f0d0be..76a617f6d60a 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -299,7 +299,9 @@ void dst_release(struct dst_entry *dst) | |||
299 | int newrefcnt; | 299 | int newrefcnt; |
300 | 300 | ||
301 | newrefcnt = atomic_dec_return(&dst->__refcnt); | 301 | newrefcnt = atomic_dec_return(&dst->__refcnt); |
302 | WARN_ON(newrefcnt < 0); | 302 | if (unlikely(newrefcnt < 0)) |
303 | net_warn_ratelimited("%s: dst:%p refcnt:%d\n", | ||
304 | __func__, dst, newrefcnt); | ||
303 | if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) | 305 | if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) |
304 | call_rcu(&dst->rcu_head, dst_destroy_rcu); | 306 | call_rcu(&dst->rcu_head, dst_destroy_rcu); |
305 | } | 307 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 5fb4af20c6dd..788ceed39463 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1808,10 +1808,13 @@ static int do_setlink(const struct sk_buff *skb, | |||
1808 | goto errout; | 1808 | goto errout; |
1809 | 1809 | ||
1810 | nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) { | 1810 | nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) { |
1811 | if (nla_type(attr) != IFLA_VF_PORT) | 1811 | if (nla_type(attr) != IFLA_VF_PORT || |
1812 | continue; | 1812 | nla_len(attr) < NLA_HDRLEN) { |
1813 | err = nla_parse_nested(port, IFLA_PORT_MAX, | 1813 | err = -EINVAL; |
1814 | attr, ifla_port_policy); | 1814 | goto errout; |
1815 | } | ||
1816 | err = nla_parse_nested(port, IFLA_PORT_MAX, attr, | ||
1817 | ifla_port_policy); | ||
1815 | if (err < 0) | 1818 | if (err < 0) |
1816 | goto errout; | 1819 | goto errout; |
1817 | if (!port[IFLA_PORT_VF]) { | 1820 | if (!port[IFLA_PORT_VF]) { |