aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e96b15a66aba..f73e9d38d5ba 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2658,20 +2658,23 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2658 } 2658 }
2659 2659
2660 if (params->spp_flags & SPP_IPV6_FLOWLABEL) { 2660 if (params->spp_flags & SPP_IPV6_FLOWLABEL) {
2661 if (trans && trans->ipaddr.sa.sa_family == AF_INET6) { 2661 if (trans) {
2662 trans->flowlabel = params->spp_ipv6_flowlabel & 2662 if (trans->ipaddr.sa.sa_family == AF_INET6) {
2663 SCTP_FLOWLABEL_VAL_MASK;
2664 trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
2665 } else if (asoc) {
2666 list_for_each_entry(trans,
2667 &asoc->peer.transport_addr_list,
2668 transports) {
2669 if (trans->ipaddr.sa.sa_family != AF_INET6)
2670 continue;
2671 trans->flowlabel = params->spp_ipv6_flowlabel & 2663 trans->flowlabel = params->spp_ipv6_flowlabel &
2672 SCTP_FLOWLABEL_VAL_MASK; 2664 SCTP_FLOWLABEL_VAL_MASK;
2673 trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2665 trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
2674 } 2666 }
2667 } else if (asoc) {
2668 struct sctp_transport *t;
2669
2670 list_for_each_entry(t, &asoc->peer.transport_addr_list,
2671 transports) {
2672 if (t->ipaddr.sa.sa_family != AF_INET6)
2673 continue;
2674 t->flowlabel = params->spp_ipv6_flowlabel &
2675 SCTP_FLOWLABEL_VAL_MASK;
2676 t->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
2677 }
2675 asoc->flowlabel = params->spp_ipv6_flowlabel & 2678 asoc->flowlabel = params->spp_ipv6_flowlabel &
2676 SCTP_FLOWLABEL_VAL_MASK; 2679 SCTP_FLOWLABEL_VAL_MASK;
2677 asoc->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2680 asoc->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
@@ -2687,12 +2690,13 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2687 trans->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK; 2690 trans->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
2688 trans->dscp |= SCTP_DSCP_SET_MASK; 2691 trans->dscp |= SCTP_DSCP_SET_MASK;
2689 } else if (asoc) { 2692 } else if (asoc) {
2690 list_for_each_entry(trans, 2693 struct sctp_transport *t;
2691 &asoc->peer.transport_addr_list, 2694
2695 list_for_each_entry(t, &asoc->peer.transport_addr_list,
2692 transports) { 2696 transports) {
2693 trans->dscp = params->spp_dscp & 2697 t->dscp = params->spp_dscp &
2694 SCTP_DSCP_VAL_MASK; 2698 SCTP_DSCP_VAL_MASK;
2695 trans->dscp |= SCTP_DSCP_SET_MASK; 2699 t->dscp |= SCTP_DSCP_SET_MASK;
2696 } 2700 }
2697 asoc->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK; 2701 asoc->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
2698 asoc->dscp |= SCTP_DSCP_SET_MASK; 2702 asoc->dscp |= SCTP_DSCP_SET_MASK;
@@ -5005,9 +5009,14 @@ struct sctp_transport *sctp_transport_get_next(struct net *net,
5005 break; 5009 break;
5006 } 5010 }
5007 5011
5012 if (!sctp_transport_hold(t))
5013 continue;
5014
5008 if (net_eq(sock_net(t->asoc->base.sk), net) && 5015 if (net_eq(sock_net(t->asoc->base.sk), net) &&
5009 t->asoc->peer.primary_path == t) 5016 t->asoc->peer.primary_path == t)
5010 break; 5017 break;
5018
5019 sctp_transport_put(t);
5011 } 5020 }
5012 5021
5013 return t; 5022 return t;
@@ -5017,13 +5026,18 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
5017 struct rhashtable_iter *iter, 5026 struct rhashtable_iter *iter,
5018 int pos) 5027 int pos)
5019{ 5028{
5020 void *obj = SEQ_START_TOKEN; 5029 struct sctp_transport *t;
5021 5030
5022 while (pos && (obj = sctp_transport_get_next(net, iter)) && 5031 if (!pos)
5023 !IS_ERR(obj)) 5032 return SEQ_START_TOKEN;
5024 pos--;
5025 5033
5026 return obj; 5034 while ((t = sctp_transport_get_next(net, iter)) && !IS_ERR(t)) {
5035 if (!--pos)
5036 break;
5037 sctp_transport_put(t);
5038 }
5039
5040 return t;
5027} 5041}
5028 5042
5029int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), 5043int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
@@ -5082,8 +5096,6 @@ again:
5082 5096
5083 tsp = sctp_transport_get_idx(net, &hti, *pos + 1); 5097 tsp = sctp_transport_get_idx(net, &hti, *pos + 1);
5084 for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) { 5098 for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) {
5085 if (!sctp_transport_hold(tsp))
5086 continue;
5087 ret = cb(tsp, p); 5099 ret = cb(tsp, p);
5088 if (ret) 5100 if (ret)
5089 break; 5101 break;