Re: Lksctp and receiving ancilliary data from IP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> Hi,
>
> Recently I wanted to write an application which receives DSCP value from kernel through recvmsg's ancilliary control data feature, but I had to realize that despite I've used setsockopt with IP_RECVTOS parameter to achieve this, the buffer contained only SCTP level control data. When I looked into the code, I found that in net/sctp/socket.c::sctp_recvmsg() the necessary lines are commented out:
>
> 	if (sp->subscribe.sctp_data_io_event)
> 		sctp_ulpevent_read_sndrcvinfo(event, msg);
> #if 0
> 	/* FIXME: we should be calling IP/IPv6 layers.  */
> 	if (sk->sk_protinfo.af_inet.cmsg_flags)
> 		ip_cmsg_recv(msg, skb);
> #endif

those code do not run any more, and maybe only run for IPv4 before
it be removed.

> I've tried to search about the reasons, but I couldn't find any answers about why is this left like this. Is there any special reason? At first look this code snippet looks working, but I suppose it's not an accident why it is not included in the official code.

You can try the following un-test patch, only for IPv4.

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5c9bada..7dcbca8 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -631,6 +631,8 @@ struct sctp_pf {
 	struct sock *(*create_accept_sk) (struct sock *sk,
 					  struct sctp_association *asoc);
 	void (*addr_v4map) (struct sctp_sock *, union sctp_addr *);
+	void (*cmsg_recv_ctl)(struct sock *sk, struct msghdr *msg,
+			      struct sk_buff *skb);
 	struct sctp_af *af;
 };
 
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 865ce7b..01bde2d 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -893,6 +893,12 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
 	return 1;
 }
 
+static void sctp_v6_cmsg_recv_ctl(struct sock *sk, struct msghdr *msg,
+				  struct sk_buff *skb)
+{
+	// skip
+}
+
 static const struct proto_ops inet6_seqpacket_ops = {
 	.family		   = PF_INET6,
 	.owner		   = THIS_MODULE,
@@ -988,6 +994,7 @@ static struct sctp_pf sctp_pf_inet6 = {
 	.supported_addrs = sctp_inet6_supported_addrs,
 	.create_accept_sk = sctp_v6_create_accept_sk,
 	.addr_v4map    = sctp_v6_addr_v4map,
+	.cmsg_recv_ctl = sctp_v6_cmsg_recv_ctl,
 	.af            = &sctp_af_inet6,
 };
 
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index d5bf91d..64ec7ed 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -846,6 +846,15 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
 	return 1;
 }
 
+static void sctp_v4_cmsg_recv_ctl(struct sock *sk, struct msghdr *msg,
+				  struct sk_buff *skb)
+{
+	struct inet_sock *inet = inet_sk(sk);
+
+	if (inet->cmsg_flags)
+		ip_cmsg_recv(msg, skb);
+}
+
 /* Wrapper routine that calls the ip transmit routine. */
 static inline int sctp_v4_xmit(struct sk_buff *skb,
 			       struct sctp_transport *transport)
@@ -876,6 +885,7 @@ static struct sctp_pf sctp_pf_inet = {
 	.supported_addrs = sctp_inet_supported_addrs,
 	.create_accept_sk = sctp_v4_create_accept_sk,
 	.addr_v4map	= sctp_v4_addr_v4map,
+	.cmsg_recv_ctl = sctp_v4_cmsg_recv_ctl,
 	.af            = &sctp_af_inet
 };
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f694ee1..c8bb106 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1997,11 +1997,8 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk,
 	/* Check if we allow SCTP_SNDRCVINFO. */
 	if (sp->subscribe.sctp_data_io_event)
 		sctp_ulpevent_read_sndrcvinfo(event, msg);
-#if 0
-	/* FIXME: we should be calling IP/IPv6 layers.  */
-	if (sk->sk_protinfo.af_inet.cmsg_flags)
-		ip_cmsg_recv(msg, skb);
-#endif
+
+	sp->pf->cmsg_recv_ctl(sk, msg, skb);
 
 	err = copied;
 


--
To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Networking Development]     [Linux OMAP]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux