Commit 13651224 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

net: ping6: support setting basic SOL_IPV6 options via cmsg



Support setting IPV6_HOPLIMIT, IPV6_TCLASS, IPV6_DONTFRAG
during sendmsg via SOL_IPV6 cmsgs.

tclass and dontfrag are init'ed from struct ipv6_pinfo in
ipcm6_init_sk(), while hlimit is inited to -1, so we need
to handle it being populated via cmsg explicitly.

Leave extension headers and flowlabel unimplemented.
Those are slightly more laborious to test and users
seem to primarily care about IPV6_TCLASS.

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d54f16c7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1487,6 +1487,7 @@ static int __ip6_append_data(struct sock *sk,

	if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
	    (sk->sk_protocol == IPPROTO_UDP ||
	     sk->sk_protocol == IPPROTO_ICMPV6 ||
	     sk->sk_protocol == IPPROTO_RAW)) {
		ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
				sizeof(struct ipv6hdr));
+16 −5
Original line number Diff line number Diff line
@@ -101,11 +101,21 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
	ipc6.sockc.tsflags = sk->sk_tsflags;
	ipc6.sockc.mark = sk->sk_mark;

	err = sock_cmsg_send(sk, msg, &ipc6.sockc);
	if (err)
	if (msg->msg_controllen) {
		struct ipv6_txoptions opt = {};

		opt.tot_len = sizeof(opt);
		ipc6.opt = &opt;

		err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6);
		if (err < 0)
			return err;

	/* TODO: use ip6_datagram_send_ctl to get options from cmsg */
		/* Changes to txoptions and flow info are not implemented, yet.
		 * Drop the options, fl6 is wiped below.
		 */
		ipc6.opt = NULL;
	}

	memset(&fl6, 0, sizeof(fl6));

@@ -140,6 +150,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
	pfh.wcheck = 0;
	pfh.family = AF_INET6;

	if (ipc6.hlimit < 0)
		ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);

	lock_sock(sk);