diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-07-02 06:21:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-03 22:36:54 -0400 |
commit | 8a9c58d28d0f66569737a3295116710ed24573cd (patch) | |
tree | 4d530788207cca98e68faee6d5a4145d5d8befc4 /net/sctp/protocol.c | |
parent | 69b9e1e07d98b57b972df3c44647ca8795284d39 (diff) |
sctp: add support for dscp and flowlabel per transport
Like some other per transport params, flowlabel and dscp are added
in transport, asoc and sctp_sock. By default, transport sets its
value from asoc's, and asoc does it from sctp_sock. flowlabel
only works for ipv6 transport.
Other than that they need to be passed down in sctp_xmit, flow4/6
also needs to set them before looking up route in get_dst.
Note that it uses '& 0x100000' to check if flowlabel is set and
'& 0x1' (tos 1st bit is unused) to check if dscp is set by users,
so that they could be set to 0 by sockopt in next patch.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 67f73d3a1356..e948db29ab53 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -426,13 +426,16 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
426 | struct dst_entry *dst = NULL; | 426 | struct dst_entry *dst = NULL; |
427 | union sctp_addr *daddr = &t->ipaddr; | 427 | union sctp_addr *daddr = &t->ipaddr; |
428 | union sctp_addr dst_saddr; | 428 | union sctp_addr dst_saddr; |
429 | __u8 tos = inet_sk(sk)->tos; | ||
429 | 430 | ||
431 | if (t->dscp & SCTP_DSCP_SET_MASK) | ||
432 | tos = t->dscp & SCTP_DSCP_VAL_MASK; | ||
430 | memset(fl4, 0x0, sizeof(struct flowi4)); | 433 | memset(fl4, 0x0, sizeof(struct flowi4)); |
431 | fl4->daddr = daddr->v4.sin_addr.s_addr; | 434 | fl4->daddr = daddr->v4.sin_addr.s_addr; |
432 | fl4->fl4_dport = daddr->v4.sin_port; | 435 | fl4->fl4_dport = daddr->v4.sin_port; |
433 | fl4->flowi4_proto = IPPROTO_SCTP; | 436 | fl4->flowi4_proto = IPPROTO_SCTP; |
434 | if (asoc) { | 437 | if (asoc) { |
435 | fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); | 438 | fl4->flowi4_tos = RT_CONN_FLAGS_TOS(asoc->base.sk, tos); |
436 | fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; | 439 | fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; |
437 | fl4->fl4_sport = htons(asoc->base.bind_addr.port); | 440 | fl4->fl4_sport = htons(asoc->base.bind_addr.port); |
438 | } | 441 | } |
@@ -495,7 +498,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
495 | fl4->fl4_sport = laddr->a.v4.sin_port; | 498 | fl4->fl4_sport = laddr->a.v4.sin_port; |
496 | flowi4_update_output(fl4, | 499 | flowi4_update_output(fl4, |
497 | asoc->base.sk->sk_bound_dev_if, | 500 | asoc->base.sk->sk_bound_dev_if, |
498 | RT_CONN_FLAGS(asoc->base.sk), | 501 | RT_CONN_FLAGS_TOS(asoc->base.sk, tos), |
499 | daddr->v4.sin_addr.s_addr, | 502 | daddr->v4.sin_addr.s_addr, |
500 | laddr->a.v4.sin_addr.s_addr); | 503 | laddr->a.v4.sin_addr.s_addr); |
501 | 504 | ||
@@ -971,16 +974,21 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, | |||
971 | struct sctp_transport *transport) | 974 | struct sctp_transport *transport) |
972 | { | 975 | { |
973 | struct inet_sock *inet = inet_sk(skb->sk); | 976 | struct inet_sock *inet = inet_sk(skb->sk); |
977 | __u8 dscp = inet->tos; | ||
974 | 978 | ||
975 | pr_debug("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", __func__, skb, | 979 | pr_debug("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", __func__, skb, |
976 | skb->len, &transport->fl.u.ip4.saddr, &transport->fl.u.ip4.daddr); | 980 | skb->len, &transport->fl.u.ip4.saddr, |
981 | &transport->fl.u.ip4.daddr); | ||
982 | |||
983 | if (transport->dscp & SCTP_DSCP_SET_MASK) | ||
984 | dscp = transport->dscp & SCTP_DSCP_VAL_MASK; | ||
977 | 985 | ||
978 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? | 986 | inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? |
979 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; | 987 | IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
980 | 988 | ||
981 | SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); | 989 | SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); |
982 | 990 | ||
983 | return ip_queue_xmit(&inet->sk, skb, &transport->fl); | 991 | return __ip_queue_xmit(&inet->sk, skb, &transport->fl, dscp); |
984 | } | 992 | } |
985 | 993 | ||
986 | static struct sctp_af sctp_af_inet; | 994 | static struct sctp_af sctp_af_inet; |