aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-02 13:36:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-02 13:36:41 -0400
commitbb6bbc7ca2254fd885f5b85f4cc0cda7cf04f8c1 (patch)
tree00ea99c4249a670f2325b84fc177a7a182f10e86 /net
parentf51fdffad5b7709d0ade40736b58a2da2707fa15 (diff)
parent1cceda7849809a8857fd9f26efe8846506c710e1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix wrong TCP checksums on MTU probing when checksum offloading is disabled, from Douglas Caetano dos Santos. 2) Fix qdisc backlog updates in qfq and sfb schedulers, from Cong Wang. 3) Route lookup flow key protocol value is wrong in ip6gre_xmit_other(), fix from Lance Richardson. 4) Scheduling while atomic in multicast routing code of ipv4 and ipv6, fix from Nikolay Aleksandrov. 5) Fix packet alignment in fec driver, from Eric Nelson. 6) Fix perf regression in sctp due to struct layout and cache misses, from Xin Long. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: sctp: fix the issue sctp_diag uses lock_sock in rcu_read_lock sctp: change to check peer prsctp_capable when using prsctp polices sctp: remove prsctp_param from sctp_chunk sctp: move sent_count to the memory hole in sctp_chunk tg3: Avoid NULL pointer dereference in tg3_io_error_detected() act_ife: Fix false encoding act_ife: Fix external mac header on encode VSOCK: Don't dec ack backlog twice for rejected connections Revert "net: ethernet: bcmgenet: use phydev from struct net_device" net: fec: align IP header in hardware net: fec: remove QUIRK_HAS_RACC from i.mx27 net: fec: remove QUIRK_HAS_RACC from i.mx25 ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route ip6_gre: fix flowi6_proto value in ip6gre_xmit_other() tcp: fix a compile error in DBGUNDO() tcp: fix wrong checksum calculation on MTU probing sch_sfb: keep backlog updated with qlen sch_qfq: keep backlog updated with qlen can: dev: fix deadlock reported after bus-off
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/ipmr.c3
-rw-r--r--net/ipv4/route.c3
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/ipv6/ip6_gre.c1
-rw-r--r--net/ipv6/ip6mr.c5
-rw-r--r--net/ipv6/route.c4
-rw-r--r--net/sched/act_ife.c7
-rw-r--r--net/sched/sch_qfq.c3
-rw-r--r--net/sched/sch_sfb.c3
-rw-r--r--net/sctp/chunk.c11
-rw-r--r--net/sctp/outqueue.c12
-rw-r--r--net/sctp/sctp_diag.c58
-rw-r--r--net/sctp/sm_make_chunk.c15
-rw-r--r--net/sctp/socket.c10
-rw-r--r--net/vmw_vsock/af_vsock.c6
16 files changed, 91 insertions, 65 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index a87bcd2d4a94..5f006e13de56 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2123,7 +2123,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2123 2123
2124int ipmr_get_route(struct net *net, struct sk_buff *skb, 2124int ipmr_get_route(struct net *net, struct sk_buff *skb,
2125 __be32 saddr, __be32 daddr, 2125 __be32 saddr, __be32 daddr,
2126 struct rtmsg *rtm, int nowait) 2126 struct rtmsg *rtm, int nowait, u32 portid)
2127{ 2127{
2128 struct mfc_cache *cache; 2128 struct mfc_cache *cache;
2129 struct mr_table *mrt; 2129 struct mr_table *mrt;
@@ -2168,6 +2168,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
2168 return -ENOMEM; 2168 return -ENOMEM;
2169 } 2169 }
2170 2170
2171 NETLINK_CB(skb2).portid = portid;
2171 skb_push(skb2, sizeof(struct iphdr)); 2172 skb_push(skb2, sizeof(struct iphdr));
2172 skb_reset_network_header(skb2); 2173 skb_reset_network_header(skb2);
2173 iph = ip_hdr(skb2); 2174 iph = ip_hdr(skb2);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b5b47a26d4ec..62c3ed0b7556 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2503,7 +2503,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id,
2503 IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { 2503 IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
2504 int err = ipmr_get_route(net, skb, 2504 int err = ipmr_get_route(net, skb,
2505 fl4->saddr, fl4->daddr, 2505 fl4->saddr, fl4->daddr,
2506 r, nowait); 2506 r, nowait, portid);
2507
2507 if (err <= 0) { 2508 if (err <= 0) {
2508 if (!nowait) { 2509 if (!nowait) {
2509 if (err == 0) 2510 if (err == 0)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 08323bd95f2a..a756b8749a26 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2329,10 +2329,9 @@ static void DBGUNDO(struct sock *sk, const char *msg)
2329 } 2329 }
2330#if IS_ENABLED(CONFIG_IPV6) 2330#if IS_ENABLED(CONFIG_IPV6)
2331 else if (sk->sk_family == AF_INET6) { 2331 else if (sk->sk_family == AF_INET6) {
2332 struct ipv6_pinfo *np = inet6_sk(sk);
2333 pr_debug("Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", 2332 pr_debug("Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n",
2334 msg, 2333 msg,
2335 &np->daddr, ntohs(inet->inet_dport), 2334 &sk->sk_v6_daddr, ntohs(inet->inet_dport),
2336 tp->snd_cwnd, tcp_left_out(tp), 2335 tp->snd_cwnd, tcp_left_out(tp),
2337 tp->snd_ssthresh, tp->prior_ssthresh, 2336 tp->snd_ssthresh, tp->prior_ssthresh,
2338 tp->packets_out); 2337 tp->packets_out);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5288cec4a2b2..d48d5571e62a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1966,12 +1966,14 @@ static int tcp_mtu_probe(struct sock *sk)
1966 len = 0; 1966 len = 0;
1967 tcp_for_write_queue_from_safe(skb, next, sk) { 1967 tcp_for_write_queue_from_safe(skb, next, sk) {
1968 copy = min_t(int, skb->len, probe_size - len); 1968 copy = min_t(int, skb->len, probe_size - len);
1969 if (nskb->ip_summed) 1969 if (nskb->ip_summed) {
1970 skb_copy_bits(skb, 0, skb_put(nskb, copy), copy); 1970 skb_copy_bits(skb, 0, skb_put(nskb, copy), copy);
1971 else 1971 } else {
1972 nskb->csum = skb_copy_and_csum_bits(skb, 0, 1972 __wsum csum = skb_copy_and_csum_bits(skb, 0,
1973 skb_put(nskb, copy), 1973 skb_put(nskb, copy),
1974 copy, nskb->csum); 1974 copy, 0);
1975 nskb->csum = csum_block_add(nskb->csum, csum, len);
1976 }
1975 1977
1976 if (skb->len <= copy) { 1978 if (skb->len <= copy) {
1977 /* We've eaten all the data from this skb. 1979 /* We've eaten all the data from this skb.
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 704274cbd495..edc3daab354e 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -648,7 +648,6 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev)
648 encap_limit = t->parms.encap_limit; 648 encap_limit = t->parms.encap_limit;
649 649
650 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); 650 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
651 fl6.flowi6_proto = skb->protocol;
652 651
653 err = gre_handle_offloads(skb, !!(t->parms.o_flags & TUNNEL_CSUM)); 652 err = gre_handle_offloads(skb, !!(t->parms.o_flags & TUNNEL_CSUM));
654 if (err) 653 if (err)
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index fccb5dd91902..7f4265b1649b 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2285,8 +2285,8 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2285 return 1; 2285 return 1;
2286} 2286}
2287 2287
2288int ip6mr_get_route(struct net *net, 2288int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
2289 struct sk_buff *skb, struct rtmsg *rtm, int nowait) 2289 int nowait, u32 portid)
2290{ 2290{
2291 int err; 2291 int err;
2292 struct mr6_table *mrt; 2292 struct mr6_table *mrt;
@@ -2331,6 +2331,7 @@ int ip6mr_get_route(struct net *net,
2331 return -ENOMEM; 2331 return -ENOMEM;
2332 } 2332 }
2333 2333
2334 NETLINK_CB(skb2).portid = portid;
2334 skb_reset_transport_header(skb2); 2335 skb_reset_transport_header(skb2);
2335 2336
2336 skb_put(skb2, sizeof(struct ipv6hdr)); 2337 skb_put(skb2, sizeof(struct ipv6hdr));
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e3a224b97905..269218aacbea 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3202,7 +3202,9 @@ static int rt6_fill_node(struct net *net,
3202 if (iif) { 3202 if (iif) {
3203#ifdef CONFIG_IPV6_MROUTE 3203#ifdef CONFIG_IPV6_MROUTE
3204 if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { 3204 if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
3205 int err = ip6mr_get_route(net, skb, rtm, nowait); 3205 int err = ip6mr_get_route(net, skb, rtm, nowait,
3206 portid);
3207
3206 if (err <= 0) { 3208 if (err <= 0) {
3207 if (!nowait) { 3209 if (!nowait) {
3208 if (err == 0) 3210 if (err == 0)
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index e87cd81315e1..4a60cd5e1875 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -53,7 +53,7 @@ int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, const void *dval)
53 u32 *tlv = (u32 *)(skbdata); 53 u32 *tlv = (u32 *)(skbdata);
54 u16 totlen = nla_total_size(dlen); /*alignment + hdr */ 54 u16 totlen = nla_total_size(dlen); /*alignment + hdr */
55 char *dptr = (char *)tlv + NLA_HDRLEN; 55 char *dptr = (char *)tlv + NLA_HDRLEN;
56 u32 htlv = attrtype << 16 | dlen; 56 u32 htlv = attrtype << 16 | (dlen + NLA_HDRLEN);
57 57
58 *tlv = htonl(htlv); 58 *tlv = htonl(htlv);
59 memset(dptr, 0, totlen - NLA_HDRLEN); 59 memset(dptr, 0, totlen - NLA_HDRLEN);
@@ -627,7 +627,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
627 struct tcf_ife_info *ife = to_ife(a); 627 struct tcf_ife_info *ife = to_ife(a);
628 int action = ife->tcf_action; 628 int action = ife->tcf_action;
629 struct ifeheadr *ifehdr = (struct ifeheadr *)skb->data; 629 struct ifeheadr *ifehdr = (struct ifeheadr *)skb->data;
630 u16 ifehdrln = ifehdr->metalen; 630 int ifehdrln = (int)ifehdr->metalen;
631 struct meta_tlvhdr *tlv = (struct meta_tlvhdr *)(ifehdr->tlv_data); 631 struct meta_tlvhdr *tlv = (struct meta_tlvhdr *)(ifehdr->tlv_data);
632 632
633 spin_lock(&ife->tcf_lock); 633 spin_lock(&ife->tcf_lock);
@@ -740,8 +740,6 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
740 return TC_ACT_SHOT; 740 return TC_ACT_SHOT;
741 } 741 }
742 742
743 iethh = eth_hdr(skb);
744
745 err = skb_cow_head(skb, hdrm); 743 err = skb_cow_head(skb, hdrm);
746 if (unlikely(err)) { 744 if (unlikely(err)) {
747 ife->tcf_qstats.drops++; 745 ife->tcf_qstats.drops++;
@@ -752,6 +750,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
752 if (!(at & AT_EGRESS)) 750 if (!(at & AT_EGRESS))
753 skb_push(skb, skb->dev->hard_header_len); 751 skb_push(skb, skb->dev->hard_header_len);
754 752
753 iethh = (struct ethhdr *)skb->data;
755 __skb_push(skb, hdrm); 754 __skb_push(skb, hdrm);
756 memcpy(skb->data, iethh, skb->mac_len); 755 memcpy(skb->data, iethh, skb->mac_len);
757 skb_reset_mac_header(skb); 756 skb_reset_mac_header(skb);
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index f27ffee106f6..ca0516e6f743 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -1153,6 +1153,7 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
1153 if (!skb) 1153 if (!skb)
1154 return NULL; 1154 return NULL;
1155 1155
1156 qdisc_qstats_backlog_dec(sch, skb);
1156 sch->q.qlen--; 1157 sch->q.qlen--;
1157 qdisc_bstats_update(sch, skb); 1158 qdisc_bstats_update(sch, skb);
1158 1159
@@ -1256,6 +1257,7 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
1256 } 1257 }
1257 1258
1258 bstats_update(&cl->bstats, skb); 1259 bstats_update(&cl->bstats, skb);
1260 qdisc_qstats_backlog_inc(sch, skb);
1259 ++sch->q.qlen; 1261 ++sch->q.qlen;
1260 1262
1261 agg = cl->agg; 1263 agg = cl->agg;
@@ -1476,6 +1478,7 @@ static void qfq_reset_qdisc(struct Qdisc *sch)
1476 qdisc_reset(cl->qdisc); 1478 qdisc_reset(cl->qdisc);
1477 } 1479 }
1478 } 1480 }
1481 sch->qstats.backlog = 0;
1479 sch->q.qlen = 0; 1482 sch->q.qlen = 0;
1480} 1483}
1481 1484
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index add3cc7d37ec..20a350bd1b1d 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -400,6 +400,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
400enqueue: 400enqueue:
401 ret = qdisc_enqueue(skb, child, to_free); 401 ret = qdisc_enqueue(skb, child, to_free);
402 if (likely(ret == NET_XMIT_SUCCESS)) { 402 if (likely(ret == NET_XMIT_SUCCESS)) {
403 qdisc_qstats_backlog_inc(sch, skb);
403 sch->q.qlen++; 404 sch->q.qlen++;
404 increment_qlen(skb, q); 405 increment_qlen(skb, q);
405 } else if (net_xmit_drop_count(ret)) { 406 } else if (net_xmit_drop_count(ret)) {
@@ -428,6 +429,7 @@ static struct sk_buff *sfb_dequeue(struct Qdisc *sch)
428 429
429 if (skb) { 430 if (skb) {
430 qdisc_bstats_update(sch, skb); 431 qdisc_bstats_update(sch, skb);
432 qdisc_qstats_backlog_dec(sch, skb);
431 sch->q.qlen--; 433 sch->q.qlen--;
432 decrement_qlen(skb, q); 434 decrement_qlen(skb, q);
433 } 435 }
@@ -450,6 +452,7 @@ static void sfb_reset(struct Qdisc *sch)
450 struct sfb_sched_data *q = qdisc_priv(sch); 452 struct sfb_sched_data *q = qdisc_priv(sch);
451 453
452 qdisc_reset(q->qdisc); 454 qdisc_reset(q->qdisc);
455 sch->qstats.backlog = 0;
453 sch->q.qlen = 0; 456 sch->q.qlen = 0;
454 q->slot = 0; 457 q->slot = 0;
455 q->double_buffering = false; 458 q->double_buffering = false;
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index a55e54738b81..0a3dbec0a8fb 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -179,6 +179,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
179 msg, msg->expires_at, jiffies); 179 msg, msg->expires_at, jiffies);
180 } 180 }
181 181
182 if (asoc->peer.prsctp_capable &&
183 SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
184 msg->expires_at =
185 jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
186
182 /* This is the biggest possible DATA chunk that can fit into 187 /* This is the biggest possible DATA chunk that can fit into
183 * the packet 188 * the packet
184 */ 189 */
@@ -335,7 +340,7 @@ errout:
335/* Check whether this message has expired. */ 340/* Check whether this message has expired. */
336int sctp_chunk_abandoned(struct sctp_chunk *chunk) 341int sctp_chunk_abandoned(struct sctp_chunk *chunk)
337{ 342{
338 if (!chunk->asoc->prsctp_enable || 343 if (!chunk->asoc->peer.prsctp_capable ||
339 !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) { 344 !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) {
340 struct sctp_datamsg *msg = chunk->msg; 345 struct sctp_datamsg *msg = chunk->msg;
341 346
@@ -349,14 +354,14 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
349 } 354 }
350 355
351 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && 356 if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
352 time_after(jiffies, chunk->prsctp_param)) { 357 time_after(jiffies, chunk->msg->expires_at)) {
353 if (chunk->sent_count) 358 if (chunk->sent_count)
354 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++; 359 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
355 else 360 else
356 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; 361 chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
357 return 1; 362 return 1;
358 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && 363 } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
359 chunk->sent_count > chunk->prsctp_param) { 364 chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
360 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; 365 chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
361 return 1; 366 return 1;
362 } 367 }
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 72e54a416af6..107233da5cc9 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -326,7 +326,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk, gfp_t gfp)
326 326
327 sctp_chunk_hold(chunk); 327 sctp_chunk_hold(chunk);
328 sctp_outq_tail_data(q, chunk); 328 sctp_outq_tail_data(q, chunk);
329 if (chunk->asoc->prsctp_enable && 329 if (chunk->asoc->peer.prsctp_capable &&
330 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags)) 330 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
331 chunk->asoc->sent_cnt_removable++; 331 chunk->asoc->sent_cnt_removable++;
332 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 332 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
@@ -383,7 +383,7 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
383 383
384 list_for_each_entry_safe(chk, temp, queue, transmitted_list) { 384 list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
385 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || 385 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
386 chk->prsctp_param <= sinfo->sinfo_timetolive) 386 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
387 continue; 387 continue;
388 388
389 list_del_init(&chk->transmitted_list); 389 list_del_init(&chk->transmitted_list);
@@ -418,7 +418,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
418 418
419 list_for_each_entry_safe(chk, temp, queue, list) { 419 list_for_each_entry_safe(chk, temp, queue, list) {
420 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || 420 if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
421 chk->prsctp_param <= sinfo->sinfo_timetolive) 421 chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
422 continue; 422 continue;
423 423
424 list_del_init(&chk->list); 424 list_del_init(&chk->list);
@@ -442,7 +442,7 @@ void sctp_prsctp_prune(struct sctp_association *asoc,
442{ 442{
443 struct sctp_transport *transport; 443 struct sctp_transport *transport;
444 444
445 if (!asoc->prsctp_enable || !asoc->sent_cnt_removable) 445 if (!asoc->peer.prsctp_capable || !asoc->sent_cnt_removable)
446 return; 446 return;
447 447
448 msg_len = sctp_prsctp_prune_sent(asoc, sinfo, 448 msg_len = sctp_prsctp_prune_sent(asoc, sinfo,
@@ -1055,7 +1055,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
1055 1055
1056 /* Mark as failed send. */ 1056 /* Mark as failed send. */
1057 sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM); 1057 sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM);
1058 if (asoc->prsctp_enable && 1058 if (asoc->peer.prsctp_capable &&
1059 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags)) 1059 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
1060 asoc->sent_cnt_removable--; 1060 asoc->sent_cnt_removable--;
1061 sctp_chunk_free(chunk); 1061 sctp_chunk_free(chunk);
@@ -1347,7 +1347,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
1347 tsn = ntohl(tchunk->subh.data_hdr->tsn); 1347 tsn = ntohl(tchunk->subh.data_hdr->tsn);
1348 if (TSN_lte(tsn, ctsn)) { 1348 if (TSN_lte(tsn, ctsn)) {
1349 list_del_init(&tchunk->transmitted_list); 1349 list_del_init(&tchunk->transmitted_list);
1350 if (asoc->prsctp_enable && 1350 if (asoc->peer.prsctp_capable &&
1351 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags)) 1351 SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
1352 asoc->sent_cnt_removable--; 1352 asoc->sent_cnt_removable--;
1353 sctp_chunk_free(tchunk); 1353 sctp_chunk_free(tchunk);
diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c
index f3508aa75815..cef0cee182d4 100644
--- a/net/sctp/sctp_diag.c
+++ b/net/sctp/sctp_diag.c
@@ -272,28 +272,17 @@ out:
272 return err; 272 return err;
273} 273}
274 274
275static int sctp_tsp_dump(struct sctp_transport *tsp, void *p) 275static int sctp_sock_dump(struct sock *sk, void *p)
276{ 276{
277 struct sctp_endpoint *ep = tsp->asoc->ep; 277 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
278 struct sctp_comm_param *commp = p; 278 struct sctp_comm_param *commp = p;
279 struct sock *sk = ep->base.sk;
280 struct sk_buff *skb = commp->skb; 279 struct sk_buff *skb = commp->skb;
281 struct netlink_callback *cb = commp->cb; 280 struct netlink_callback *cb = commp->cb;
282 const struct inet_diag_req_v2 *r = commp->r; 281 const struct inet_diag_req_v2 *r = commp->r;
283 struct sctp_association *assoc = 282 struct sctp_association *assoc;
284 list_entry(ep->asocs.next, struct sctp_association, asocs);
285 int err = 0; 283 int err = 0;
286 284
287 /* find the ep only once through the transports by this condition */
288 if (tsp->asoc != assoc)
289 goto out;
290
291 if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family)
292 goto out;
293
294 lock_sock(sk); 285 lock_sock(sk);
295 if (sk != assoc->base.sk)
296 goto release;
297 list_for_each_entry(assoc, &ep->asocs, asocs) { 286 list_for_each_entry(assoc, &ep->asocs, asocs) {
298 if (cb->args[4] < cb->args[1]) 287 if (cb->args[4] < cb->args[1])
299 goto next; 288 goto next;
@@ -312,7 +301,7 @@ static int sctp_tsp_dump(struct sctp_transport *tsp, void *p)
312 cb->nlh->nlmsg_seq, 301 cb->nlh->nlmsg_seq,
313 NLM_F_MULTI, cb->nlh) < 0) { 302 NLM_F_MULTI, cb->nlh) < 0) {
314 cb->args[3] = 1; 303 cb->args[3] = 1;
315 err = 2; 304 err = 1;
316 goto release; 305 goto release;
317 } 306 }
318 cb->args[3] = 1; 307 cb->args[3] = 1;
@@ -321,7 +310,7 @@ static int sctp_tsp_dump(struct sctp_transport *tsp, void *p)
321 sk_user_ns(NETLINK_CB(cb->skb).sk), 310 sk_user_ns(NETLINK_CB(cb->skb).sk),
322 NETLINK_CB(cb->skb).portid, 311 NETLINK_CB(cb->skb).portid,
323 cb->nlh->nlmsg_seq, 0, cb->nlh) < 0) { 312 cb->nlh->nlmsg_seq, 0, cb->nlh) < 0) {
324 err = 2; 313 err = 1;
325 goto release; 314 goto release;
326 } 315 }
327next: 316next:
@@ -333,10 +322,35 @@ next:
333 cb->args[4] = 0; 322 cb->args[4] = 0;
334release: 323release:
335 release_sock(sk); 324 release_sock(sk);
325 sock_put(sk);
336 return err; 326 return err;
327}
328
329static int sctp_get_sock(struct sctp_transport *tsp, void *p)
330{
331 struct sctp_endpoint *ep = tsp->asoc->ep;
332 struct sctp_comm_param *commp = p;
333 struct sock *sk = ep->base.sk;
334 struct netlink_callback *cb = commp->cb;
335 const struct inet_diag_req_v2 *r = commp->r;
336 struct sctp_association *assoc =
337 list_entry(ep->asocs.next, struct sctp_association, asocs);
338
339 /* find the ep only once through the transports by this condition */
340 if (tsp->asoc != assoc)
341 goto out;
342
343 if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family)
344 goto out;
345
346 sock_hold(sk);
347 cb->args[5] = (long)sk;
348
349 return 1;
350
337out: 351out:
338 cb->args[2]++; 352 cb->args[2]++;
339 return err; 353 return 0;
340} 354}
341 355
342static int sctp_ep_dump(struct sctp_endpoint *ep, void *p) 356static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
@@ -472,10 +486,18 @@ skip:
472 * 2 : to record the transport pos of this time's traversal 486 * 2 : to record the transport pos of this time's traversal
473 * 3 : to mark if we have dumped the ep info of the current asoc 487 * 3 : to mark if we have dumped the ep info of the current asoc
474 * 4 : to work as a temporary variable to traversal list 488 * 4 : to work as a temporary variable to traversal list
489 * 5 : to save the sk we get from travelsing the tsp list.
475 */ 490 */
476 if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE))) 491 if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
477 goto done; 492 goto done;
478 sctp_for_each_transport(sctp_tsp_dump, net, cb->args[2], &commp); 493
494next:
495 cb->args[5] = 0;
496 sctp_for_each_transport(sctp_get_sock, net, cb->args[2], &commp);
497
498 if (cb->args[5] && !sctp_sock_dump((struct sock *)cb->args[5], &commp))
499 goto next;
500
479done: 501done:
480 cb->args[1] = cb->args[4]; 502 cb->args[1] = cb->args[4];
481 cb->args[4] = 0; 503 cb->args[4] = 0;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 8c77b87a8565..46ffecc57214 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -706,20 +706,6 @@ nodata:
706 return retval; 706 return retval;
707} 707}
708 708
709static void sctp_set_prsctp_policy(struct sctp_chunk *chunk,
710 const struct sctp_sndrcvinfo *sinfo)
711{
712 if (!chunk->asoc->prsctp_enable)
713 return;
714
715 if (SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
716 chunk->prsctp_param =
717 jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
718 else if (SCTP_PR_RTX_ENABLED(sinfo->sinfo_flags) ||
719 SCTP_PR_PRIO_ENABLED(sinfo->sinfo_flags))
720 chunk->prsctp_param = sinfo->sinfo_timetolive;
721}
722
723/* Make a DATA chunk for the given association from the provided 709/* Make a DATA chunk for the given association from the provided
724 * parameters. However, do not populate the data payload. 710 * parameters. However, do not populate the data payload.
725 */ 711 */
@@ -753,7 +739,6 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
753 739
754 retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp); 740 retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp);
755 memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo)); 741 memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo));
756 sctp_set_prsctp_policy(retval, sinfo);
757 742
758nodata: 743nodata:
759 return retval; 744 return retval;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9fc417a8b476..8ed2d99bde6d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4469,17 +4469,21 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
4469 const union sctp_addr *paddr, void *p) 4469 const union sctp_addr *paddr, void *p)
4470{ 4470{
4471 struct sctp_transport *transport; 4471 struct sctp_transport *transport;
4472 int err = 0; 4472 int err = -ENOENT;
4473 4473
4474 rcu_read_lock(); 4474 rcu_read_lock();
4475 transport = sctp_addrs_lookup_transport(net, laddr, paddr); 4475 transport = sctp_addrs_lookup_transport(net, laddr, paddr);
4476 if (!transport || !sctp_transport_hold(transport)) 4476 if (!transport || !sctp_transport_hold(transport))
4477 goto out; 4477 goto out;
4478 err = cb(transport, p); 4478
4479 sctp_association_hold(transport->asoc);
4479 sctp_transport_put(transport); 4480 sctp_transport_put(transport);
4480 4481
4481out:
4482 rcu_read_unlock(); 4482 rcu_read_unlock();
4483 err = cb(transport, p);
4484 sctp_association_put(transport->asoc);
4485
4486out:
4483 return err; 4487 return err;
4484} 4488}
4485EXPORT_SYMBOL_GPL(sctp_transport_lookup_process); 4489EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 17dbbe64cd73..8a398b3fb532 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -465,6 +465,8 @@ void vsock_pending_work(struct work_struct *work)
465 465
466 if (vsock_is_pending(sk)) { 466 if (vsock_is_pending(sk)) {
467 vsock_remove_pending(listener, sk); 467 vsock_remove_pending(listener, sk);
468
469 listener->sk_ack_backlog--;
468 } else if (!vsk->rejected) { 470 } else if (!vsk->rejected) {
469 /* We are not on the pending list and accept() did not reject 471 /* We are not on the pending list and accept() did not reject
470 * us, so we must have been accepted by our user process. We 472 * us, so we must have been accepted by our user process. We
@@ -475,8 +477,6 @@ void vsock_pending_work(struct work_struct *work)
475 goto out; 477 goto out;
476 } 478 }
477 479
478 listener->sk_ack_backlog--;
479
480 /* We need to remove ourself from the global connected sockets list so 480 /* We need to remove ourself from the global connected sockets list so
481 * incoming packets can't find this socket, and to reduce the reference 481 * incoming packets can't find this socket, and to reduce the reference
482 * count. 482 * count.
@@ -2010,5 +2010,5 @@ EXPORT_SYMBOL_GPL(vsock_core_get_transport);
2010 2010
2011MODULE_AUTHOR("VMware, Inc."); 2011MODULE_AUTHOR("VMware, Inc.");
2012MODULE_DESCRIPTION("VMware Virtual Socket Family"); 2012MODULE_DESCRIPTION("VMware Virtual Socket Family");
2013MODULE_VERSION("1.0.1.0-k"); 2013MODULE_VERSION("1.0.2.0-k");
2014MODULE_LICENSE("GPL v2"); 2014MODULE_LICENSE("GPL v2");