@@ -66,7 +66,7 @@ static void inet_diag_unlock_handler(const struct inet_diag_handler *handler)
66
66
mutex_unlock (& inet_diag_table_mutex );
67
67
}
68
68
69
- static void inet_diag_msg_common_fill (struct inet_diag_msg * r , struct sock * sk )
69
+ void inet_diag_msg_common_fill (struct inet_diag_msg * r , struct sock * sk )
70
70
{
71
71
r -> idiag_family = sk -> sk_family ;
72
72
@@ -89,6 +89,7 @@ static void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk)
89
89
r -> id .idiag_dst [0 ] = sk -> sk_daddr ;
90
90
}
91
91
}
92
+ EXPORT_SYMBOL_GPL (inet_diag_msg_common_fill );
92
93
93
94
static size_t inet_sk_attr_size (void )
94
95
{
@@ -104,13 +105,50 @@ static size_t inet_sk_attr_size(void)
104
105
+ 64 ;
105
106
}
106
107
108
+ int inet_diag_msg_attrs_fill (struct sock * sk , struct sk_buff * skb ,
109
+ struct inet_diag_msg * r , int ext ,
110
+ struct user_namespace * user_ns )
111
+ {
112
+ const struct inet_sock * inet = inet_sk (sk );
113
+
114
+ if (nla_put_u8 (skb , INET_DIAG_SHUTDOWN , sk -> sk_shutdown ))
115
+ goto errout ;
116
+
117
+ /* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
118
+ * hence this needs to be included regardless of socket family.
119
+ */
120
+ if (ext & (1 << (INET_DIAG_TOS - 1 )))
121
+ if (nla_put_u8 (skb , INET_DIAG_TOS , inet -> tos ) < 0 )
122
+ goto errout ;
123
+
124
+ #if IS_ENABLED (CONFIG_IPV6 )
125
+ if (r -> idiag_family == AF_INET6 ) {
126
+ if (ext & (1 << (INET_DIAG_TCLASS - 1 )))
127
+ if (nla_put_u8 (skb , INET_DIAG_TCLASS ,
128
+ inet6_sk (sk )-> tclass ) < 0 )
129
+ goto errout ;
130
+
131
+ if (((1 << sk -> sk_state ) & (TCPF_LISTEN | TCPF_CLOSE )) &&
132
+ nla_put_u8 (skb , INET_DIAG_SKV6ONLY , ipv6_only_sock (sk )))
133
+ goto errout ;
134
+ }
135
+ #endif
136
+
137
+ r -> idiag_uid = from_kuid_munged (user_ns , sock_i_uid (sk ));
138
+ r -> idiag_inode = sock_i_ino (sk );
139
+
140
+ return 0 ;
141
+ errout :
142
+ return 1 ;
143
+ }
144
+ EXPORT_SYMBOL_GPL (inet_diag_msg_attrs_fill );
145
+
107
146
int inet_sk_diag_fill (struct sock * sk , struct inet_connection_sock * icsk ,
108
147
struct sk_buff * skb , const struct inet_diag_req_v2 * req ,
109
148
struct user_namespace * user_ns ,
110
149
u32 portid , u32 seq , u16 nlmsg_flags ,
111
150
const struct nlmsghdr * unlh )
112
151
{
113
- const struct inet_sock * inet = inet_sk (sk );
114
152
const struct tcp_congestion_ops * ca_ops ;
115
153
const struct inet_diag_handler * handler ;
116
154
int ext = req -> idiag_ext ;
@@ -135,32 +173,9 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
135
173
r -> idiag_timer = 0 ;
136
174
r -> idiag_retrans = 0 ;
137
175
138
- if (nla_put_u8 ( skb , INET_DIAG_SHUTDOWN , sk -> sk_shutdown ))
176
+ if (inet_diag_msg_attrs_fill ( sk , skb , r , ext , user_ns ))
139
177
goto errout ;
140
178
141
- /* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
142
- * hence this needs to be included regardless of socket family.
143
- */
144
- if (ext & (1 << (INET_DIAG_TOS - 1 )))
145
- if (nla_put_u8 (skb , INET_DIAG_TOS , inet -> tos ) < 0 )
146
- goto errout ;
147
-
148
- #if IS_ENABLED (CONFIG_IPV6 )
149
- if (r -> idiag_family == AF_INET6 ) {
150
- if (ext & (1 << (INET_DIAG_TCLASS - 1 )))
151
- if (nla_put_u8 (skb , INET_DIAG_TCLASS ,
152
- inet6_sk (sk )-> tclass ) < 0 )
153
- goto errout ;
154
-
155
- if (((1 << sk -> sk_state ) & (TCPF_LISTEN | TCPF_CLOSE )) &&
156
- nla_put_u8 (skb , INET_DIAG_SKV6ONLY , ipv6_only_sock (sk )))
157
- goto errout ;
158
- }
159
- #endif
160
-
161
- r -> idiag_uid = from_kuid_munged (user_ns , sock_i_uid (sk ));
162
- r -> idiag_inode = sock_i_ino (sk );
163
-
164
179
if (ext & (1 << (INET_DIAG_MEMINFO - 1 ))) {
165
180
struct inet_diag_meminfo minfo = {
166
181
.idiag_rmem = sk_rmem_alloc_get (sk ),
0 commit comments