Commit 4be4139f authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: add support for setting flowlabel when adding a transport



Struct sockaddr_in6 has the member sin6_flowinfo that includes the
ipv6 flowlabel, it should also support for setting flowlabel when
adding a transport whose ipaddr is from userspace.

Note that addrinfo in sctp_sendmsg is using struct in6_addr for
the secondary addrs, which doesn't contain sin6_flowinfo, and
it needs to copy sin6_flowinfo from the primary addr.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0b0dce7a
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -650,8 +650,16 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
	peer->sackdelay = asoc->sackdelay;
	peer->sackfreq = asoc->sackfreq;

	if (addr->sa.sa_family == AF_INET6)
	if (addr->sa.sa_family == AF_INET6) {
		__be32 info = addr->v6.sin6_flowinfo;

		if (info) {
			peer->flowlabel = ntohl(info & IPV6_FLOWLABEL_MASK);
			peer->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
		} else {
			peer->flowlabel = asoc->flowlabel;
		}
	}
	peer->dscp = asoc->dscp;

	/* Enable/disable heartbeat, SACK delay, and path MTU discovery
+5 −0
Original line number Diff line number Diff line
@@ -1697,6 +1697,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
	struct sctp_association *asoc;
	enum sctp_scope scope;
	struct cmsghdr *cmsg;
	__be32 flowinfo = 0;
	struct sctp_af *af;
	int err;

@@ -1781,6 +1782,9 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
	if (!cmsgs->addrs_msg)
		return 0;

	if (daddr->sa.sa_family == AF_INET6)
		flowinfo = daddr->v6.sin6_flowinfo;

	/* sendv addr list parse */
	for_each_cmsghdr(cmsg, cmsgs->addrs_msg) {
		struct sctp_transport *transport;
@@ -1813,6 +1817,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
			}

			dlen = sizeof(struct in6_addr);
			daddr->v6.sin6_flowinfo = flowinfo;
			daddr->v6.sin6_family = AF_INET6;
			daddr->v6.sin6_port = htons(asoc->peer.port);
			memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen);