diff options
author | Pavel Emelyanov <xemul@parallels.com> | 2011-12-09 01:23:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-09 14:14:08 -0500 |
commit | 3c4d05c8056724aff3abc20650807dd828fded54 (patch) | |
tree | 5aed510034ceed980de3409587cbce8845229e77 /net/ipv4/inet_diag.c | |
parent | 8d07d1518a074a08b90be02eee5ee15e60ac9779 (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.c | 53 |
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 | ||
73 | static int inet_csk_diag_fill(struct sock *sk, | 73 | int 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 | ||
181 | out: | ||
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 | } |
190 | EXPORT_SYMBOL_GPL(inet_sk_diag_fill); | ||
191 | |||
192 | static 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 | ||
186 | static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | 201 | static 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, |