aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_diag.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@parallels.com>2011-12-09 01:23:00 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-09 14:14:08 -0500
commit3c4d05c8056724aff3abc20650807dd828fded54 (patch)
tree5aed510034ceed980de3409587cbce8845229e77 /net/ipv4/inet_diag.c
parent8d07d1518a074a08b90be02eee5ee15e60ac9779 (diff)
inet_diag: Introduce the inet socket dumping routine
The existing inet_csk_diag_fill dumps the inet connection sock info into the netlink inet_diag_message. Prepare this routine to be able to dump only the inet_sock part of a socket if the icsk part is missing. This will be used by UDP diag module when dumping UDP sockets. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_diag.c')
-rw-r--r--net/ipv4/inet_diag.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 08e54989b041..dc8611e3e66f 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -70,13 +70,12 @@ static inline void inet_diag_unlock_handler(
70 mutex_unlock(&inet_diag_table_mutex); 70 mutex_unlock(&inet_diag_table_mutex);
71} 71}
72 72
73static int inet_csk_diag_fill(struct sock *sk, 73int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
74 struct sk_buff *skb, struct inet_diag_req *req, 74 struct sk_buff *skb, struct inet_diag_req *req,
75 u32 pid, u32 seq, u16 nlmsg_flags, 75 u32 pid, u32 seq, u16 nlmsg_flags,
76 const struct nlmsghdr *unlh) 76 const struct nlmsghdr *unlh)
77{ 77{
78 const struct inet_sock *inet = inet_sk(sk); 78 const struct inet_sock *inet = inet_sk(sk);
79 const struct inet_connection_sock *icsk = inet_csk(sk);
80 struct inet_diag_msg *r; 79 struct inet_diag_msg *r;
81 struct nlmsghdr *nlh; 80 struct nlmsghdr *nlh;
82 void *info = NULL; 81 void *info = NULL;
@@ -97,16 +96,6 @@ static int inet_csk_diag_fill(struct sock *sk,
97 if (ext & (1 << (INET_DIAG_MEMINFO - 1))) 96 if (ext & (1 << (INET_DIAG_MEMINFO - 1)))
98 minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo)); 97 minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo));
99 98
100 if (ext & (1 << (INET_DIAG_INFO - 1)))
101 info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info));
102
103 if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
104 const size_t len = strlen(icsk->icsk_ca_ops->name);
105
106 strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
107 icsk->icsk_ca_ops->name);
108 }
109
110 r->idiag_family = sk->sk_family; 99 r->idiag_family = sk->sk_family;
111 r->idiag_state = sk->sk_state; 100 r->idiag_state = sk->sk_state;
112 r->idiag_timer = 0; 101 r->idiag_timer = 0;
@@ -138,6 +127,21 @@ static int inet_csk_diag_fill(struct sock *sk,
138 } 127 }
139#endif 128#endif
140 129
130 r->idiag_uid = sock_i_uid(sk);
131 r->idiag_inode = sock_i_ino(sk);
132
133 if (minfo) {
134 minfo->idiag_rmem = sk_rmem_alloc_get(sk);
135 minfo->idiag_wmem = sk->sk_wmem_queued;
136 minfo->idiag_fmem = sk->sk_forward_alloc;
137 minfo->idiag_tmem = sk_wmem_alloc_get(sk);
138 }
139
140 if (icsk == NULL) {
141 r->idiag_rqueue = r->idiag_wqueue = 0;
142 goto out;
143 }
144
141#define EXPIRES_IN_MS(tmo) DIV_ROUND_UP((tmo - jiffies) * 1000, HZ) 145#define EXPIRES_IN_MS(tmo) DIV_ROUND_UP((tmo - jiffies) * 1000, HZ)
142 146
143 if (icsk->icsk_pending == ICSK_TIME_RETRANS) { 147 if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
@@ -158,14 +162,14 @@ static int inet_csk_diag_fill(struct sock *sk,
158 } 162 }
159#undef EXPIRES_IN_MS 163#undef EXPIRES_IN_MS
160 164
161 r->idiag_uid = sock_i_uid(sk); 165 if (ext & (1 << (INET_DIAG_INFO - 1)))
162 r->idiag_inode = sock_i_ino(sk); 166 info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info));
163 167
164 if (minfo) { 168 if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
165 minfo->idiag_rmem = sk_rmem_alloc_get(sk); 169 const size_t len = strlen(icsk->icsk_ca_ops->name);
166 minfo->idiag_wmem = sk->sk_wmem_queued; 170
167 minfo->idiag_fmem = sk->sk_forward_alloc; 171 strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
168 minfo->idiag_tmem = sk_wmem_alloc_get(sk); 172 icsk->icsk_ca_ops->name);
169 } 173 }
170 174
171 handler->idiag_get_info(sk, r, info); 175 handler->idiag_get_info(sk, r, info);
@@ -174,6 +178,7 @@ static int inet_csk_diag_fill(struct sock *sk,
174 icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info) 178 icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
175 icsk->icsk_ca_ops->get_info(sk, ext, skb); 179 icsk->icsk_ca_ops->get_info(sk, ext, skb);
176 180
181out:
177 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 182 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
178 return skb->len; 183 return skb->len;
179 184
@@ -182,6 +187,16 @@ nlmsg_failure:
182 nlmsg_trim(skb, b); 187 nlmsg_trim(skb, b);
183 return -EMSGSIZE; 188 return -EMSGSIZE;
184} 189}
190EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
191
192static int inet_csk_diag_fill(struct sock *sk,
193 struct sk_buff *skb, struct inet_diag_req *req,
194 u32 pid, u32 seq, u16 nlmsg_flags,
195 const struct nlmsghdr *unlh)
196{
197 return inet_sk_diag_fill(sk, inet_csk(sk),
198 skb, req, pid, seq, nlmsg_flags, unlh);
199}
185 200
186static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, 201static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
187 struct sk_buff *skb, struct inet_diag_req *req, 202 struct sk_buff *skb, struct inet_diag_req *req,