summaryrefslogtreecommitdiff
path: root/net/sctp/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r--net/sctp/output.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 1441eaf460bb..6614c9fdc51e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -508,20 +508,14 @@ merge:
sizeof(struct inet6_skb_parm)));
skb_shinfo(head)->gso_segs = pkt_count;
skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
- rcu_read_lock();
- if (skb_dst(head) != tp->dst) {
- dst_hold(tp->dst);
- sk_setup_caps(sk, tp->dst);
- }
- rcu_read_unlock();
goto chksum;
}
if (sctp_checksum_disable)
return 1;
- if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) ||
- dst_xfrm(skb_dst(head)) || packet->ipfragok) {
+ if (!(tp->dst->dev->features & NETIF_F_SCTP_CRC) ||
+ dst_xfrm(tp->dst) || packet->ipfragok || tp->encap_port) {
struct sctphdr *sh =
(struct sctphdr *)skb_transport_header(head);
@@ -548,7 +542,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
struct sctp_association *asoc = tp->asoc;
struct sctp_chunk *chunk, *tmp;
int pkt_count, gso = 0;
- struct dst_entry *dst;
struct sk_buff *head;
struct sctphdr *sh;
struct sock *sk;
@@ -585,13 +578,18 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
sh->checksum = 0;
/* drop packet if no dst */
- dst = dst_clone(tp->dst);
- if (!dst) {
+ if (!tp->dst) {
IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(head);
goto out;
}
- skb_dst_set(head, dst);
+
+ rcu_read_lock();
+ if (__sk_dst_get(sk) != tp->dst) {
+ dst_hold(tp->dst);
+ sk_setup_caps(sk, tp->dst);
+ }
+ rcu_read_unlock();
/* pack up chunks */
pkt_count = sctp_packet_pack(packet, head, gso, gfp);