OSDN Git Service

ip: expose inet sockopts through inet_diag
authorWei Wang <weiwan@google.com>
Tue, 1 Sep 2020 22:10:08 +0000 (15:10 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Sep 2020 22:17:28 +0000 (15:17 -0700)
Expose all exisiting inet sockopt bits through inet_diag for debug purpose.
Corresponding changes in iproute2 ss will be submitted to output all
these values.

Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/inet_diag.h
include/uapi/linux/inet_diag.h
net/ipv4/inet_diag.c

index 0ef2d80..84abb30 100644 (file)
@@ -75,6 +75,8 @@ static inline size_t inet_diag_msg_attrs_size(void)
 #ifdef CONFIG_SOCK_CGROUP_DATA
                + nla_total_size_64bit(sizeof(u64))  /* INET_DIAG_CGROUP_ID */
 #endif
+               + nla_total_size(sizeof(struct inet_diag_sockopt))
+                                                    /* INET_DIAG_SOCKOPT */
                ;
 }
 int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
index 5ba122c..20ee93f 100644 (file)
@@ -160,6 +160,7 @@ enum {
        INET_DIAG_ULP_INFO,
        INET_DIAG_SK_BPF_STORAGES,
        INET_DIAG_CGROUP_ID,
+       INET_DIAG_SOCKOPT,
        __INET_DIAG_MAX,
 };
 
@@ -183,6 +184,23 @@ struct inet_diag_meminfo {
        __u32   idiag_tmem;
 };
 
+/* INET_DIAG_SOCKOPT */
+
+struct inet_diag_sockopt {
+       __u8    recverr:1,
+               is_icsk:1,
+               freebind:1,
+               hdrincl:1,
+               mc_loop:1,
+               transparent:1,
+               mc_all:1,
+               nodefrag:1;
+       __u8    bind_address_no_port:1,
+               recverr_rfc4884:1,
+               defer_connect:1,
+               unused:5;
+};
+
 /* INET_DIAG_VEGASINFO */
 
 struct tcpvegas_info {
index 4a98dd7..93816d4 100644 (file)
@@ -125,6 +125,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
                             bool net_admin)
 {
        const struct inet_sock *inet = inet_sk(sk);
+       struct inet_diag_sockopt inet_sockopt;
 
        if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
                goto errout;
@@ -180,6 +181,22 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
        r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
        r->idiag_inode = sock_i_ino(sk);
 
+       memset(&inet_sockopt, 0, sizeof(inet_sockopt));
+       inet_sockopt.recverr    = inet->recverr;
+       inet_sockopt.is_icsk    = inet->is_icsk;
+       inet_sockopt.freebind   = inet->freebind;
+       inet_sockopt.hdrincl    = inet->hdrincl;
+       inet_sockopt.mc_loop    = inet->mc_loop;
+       inet_sockopt.transparent = inet->transparent;
+       inet_sockopt.mc_all     = inet->mc_all;
+       inet_sockopt.nodefrag   = inet->nodefrag;
+       inet_sockopt.bind_address_no_port = inet->bind_address_no_port;
+       inet_sockopt.recverr_rfc4884 = inet->recverr_rfc4884;
+       inet_sockopt.defer_connect = inet->defer_connect;
+       if (nla_put(skb, INET_DIAG_SOCKOPT, sizeof(inet_sockopt),
+                   &inet_sockopt))
+               goto errout;
+
        return 0;
 errout:
        return 1;