From 37ab3ad1acdc652a6694e6f45e67767a8a80592b Mon Sep 17 00:00:00 2001
From: WingMan Kwok <w-kwok2@ti.com>
Date: Tue, 7 May 2019 16:15:05 -0400
Subject: [PATCH] net: socket: pass on redundant net info to sock_recv_errqueue

Along the same idea as passing a packet's tx timestamp
back to user space application through a socket's errqueue,
this patch adds the passing of a packet's tx redundant network
information back to user space application through a
socket's errqueue. The redundant network information could
include information from HSR TAG or PRP RCT, or the
redundant network port on which the packet is sent.

Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 net/core/skbuff.c | 8 ++++++++
 net/core/sock.c   | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 973a71f4bc898..c9a4a8ff84ad0 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4573,6 +4573,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
 {
 	struct sk_buff *skb;
 	bool tsonly, opt_stats = false;
+	struct skb_redundant_info *sred, *orig_sred;
 
 	if (!sk)
 		return;
@@ -4607,6 +4608,13 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
 		skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
 	}
 
+	/* FIXME: should check sk flags */
+	orig_sred = skb_redinfo(orig_skb);
+	if (orig_sred->lsdu_size) {
+		sred = skb_redinfo(skb);
+		memcpy(sred, orig_sred, sizeof(*sred));
+	}
+
 	if (hwtstamps)
 		*skb_hwtstamps(skb) = *hwtstamps;
 	else
diff --git a/net/core/sock.c b/net/core/sock.c
index 69c02ac06c595..371f30e353eaa 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3070,6 +3070,7 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
 	struct sock_exterr_skb *serr;
 	struct sk_buff *skb;
 	int copied, err;
+	struct skb_redundant_info *sred;
 
 	err = -EAGAIN;
 	skb = sock_dequeue_err_skb(sk);
@@ -3087,6 +3088,9 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
 
 	sock_recv_timestamp(msg, sk, skb);
 
+	sred = skb_redinfo(skb);
+	put_cmsg(msg, SOL_SOCKET, SCM_REDUNDANT, sizeof(*sred), sred);
+
 	serr = SKB_EXT_ERR(skb);
 	put_cmsg(msg, level, type, sizeof(serr->ee), &serr->ee);
 
-- 
GitLab