Skip to content

Commit 259db53

Browse files
lxinkuba-moo
authored andcommitted
sctp: support for sending packet over udp6 sock
This one basically does the similar things in sctp_v6_xmit as does for udp4 sock in the last patch, just note that: 1. label needs to be calculated, as it's the param of udp_tunnel6_xmit_skb(). 2. The 'nocheck' param of udp_tunnel6_xmit_skb() is false, as required by RFC. v1->v2: - Use sp->udp_port instead in sctp_v6_xmit(), which is more safe. Signed-off-by: Xin Long <[email protected]> Acked-by: Marcelo Ricardo Leitner <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 600af7f commit 259db53

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

net/sctp/ipv6.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <net/inet_common.h>
5656
#include <net/inet_ecn.h>
5757
#include <net/sctp/sctp.h>
58+
#include <net/udp_tunnel.h>
5859

5960
#include <linux/uaccess.h>
6061

@@ -191,33 +192,53 @@ static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
191192
return ret;
192193
}
193194

194-
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
195+
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)
195196
{
197+
struct dst_entry *dst = dst_clone(t->dst);
198+
struct flowi6 *fl6 = &t->fl.u.ip6;
196199
struct sock *sk = skb->sk;
197200
struct ipv6_pinfo *np = inet6_sk(sk);
198-
struct flowi6 *fl6 = &transport->fl.u.ip6;
199201
__u8 tclass = np->tclass;
200-
int res;
202+
__be32 label;
201203

202204
pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb,
203205
skb->len, &fl6->saddr, &fl6->daddr);
204206

205-
if (transport->dscp & SCTP_DSCP_SET_MASK)
206-
tclass = transport->dscp & SCTP_DSCP_VAL_MASK;
207+
if (t->dscp & SCTP_DSCP_SET_MASK)
208+
tclass = t->dscp & SCTP_DSCP_VAL_MASK;
207209

208210
if (INET_ECN_is_capable(tclass))
209211
IP6_ECN_flow_xmit(sk, fl6->flowlabel);
210212

211-
if (!(transport->param_flags & SPP_PMTUD_ENABLE))
213+
if (!(t->param_flags & SPP_PMTUD_ENABLE))
212214
skb->ignore_df = 1;
213215

214216
SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS);
215217

216-
rcu_read_lock();
217-
res = ip6_xmit(sk, skb, fl6, sk->sk_mark, rcu_dereference(np->opt),
218-
tclass, sk->sk_priority);
219-
rcu_read_unlock();
220-
return res;
218+
if (!t->encap_port || !sctp_sk(sk)->udp_port) {
219+
int res;
220+
221+
skb_dst_set(skb, dst);
222+
rcu_read_lock();
223+
res = ip6_xmit(sk, skb, fl6, sk->sk_mark,
224+
rcu_dereference(np->opt),
225+
tclass, sk->sk_priority);
226+
rcu_read_unlock();
227+
return res;
228+
}
229+
230+
if (skb_is_gso(skb))
231+
skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
232+
233+
skb->encapsulation = 1;
234+
skb_reset_inner_mac_header(skb);
235+
skb_reset_inner_transport_header(skb);
236+
skb_set_inner_ipproto(skb, IPPROTO_SCTP);
237+
label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6);
238+
239+
return udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr,
240+
&fl6->daddr, tclass, ip6_dst_hoplimit(dst),
241+
label, sctp_sk(sk)->udp_port, t->encap_port, false);
221242
}
222243

223244
/* Returns the dst cache entry for the given source and destination ip

0 commit comments

Comments
 (0)