diff options
author | Thomas Graf <tgraf@suug.ch> | 2012-06-26 19:36:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-27 18:36:44 -0400 |
commit | 6e277ed59a45544786f4c4643a69527138c24fc1 (patch) | |
tree | 272ab01155287f9b6156c48c0c19c562ea5a5fcd /net/ipv4/inet_diag.c | |
parent | 7b46866dd0a6fe38ecee523eb27eda9c8f484dc5 (diff) |
inet_diag: Do not use RTA_PUT() macros
Also, no need to trim on nlmsg_put() failure, nothing has been added
yet. We also want to use nlmsg_end(), nlmsg_new() and nlmsg_free().
Signed-off-by: Thomas Graf <tgraf@suug.ch>
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 | 112 |
1 files changed, 53 insertions, 59 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 27640e734cfd..38064a285cca 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -46,9 +46,6 @@ struct inet_diag_entry { | |||
46 | u16 userlocks; | 46 | u16 userlocks; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define INET_DIAG_PUT(skb, attrtype, attrlen) \ | ||
50 | RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) | ||
51 | |||
52 | static DEFINE_MUTEX(inet_diag_table_mutex); | 49 | static DEFINE_MUTEX(inet_diag_table_mutex); |
53 | 50 | ||
54 | static const struct inet_diag_handler *inet_diag_lock_handler(int proto) | 51 | static const struct inet_diag_handler *inet_diag_lock_handler(int proto) |
@@ -78,28 +75,22 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
78 | const struct inet_sock *inet = inet_sk(sk); | 75 | const struct inet_sock *inet = inet_sk(sk); |
79 | struct inet_diag_msg *r; | 76 | struct inet_diag_msg *r; |
80 | struct nlmsghdr *nlh; | 77 | struct nlmsghdr *nlh; |
78 | struct nlattr *attr; | ||
81 | void *info = NULL; | 79 | void *info = NULL; |
82 | struct inet_diag_meminfo *minfo = NULL; | ||
83 | unsigned char *b = skb_tail_pointer(skb); | ||
84 | const struct inet_diag_handler *handler; | 80 | const struct inet_diag_handler *handler; |
85 | int ext = req->idiag_ext; | 81 | int ext = req->idiag_ext; |
86 | 82 | ||
87 | handler = inet_diag_table[req->sdiag_protocol]; | 83 | handler = inet_diag_table[req->sdiag_protocol]; |
88 | BUG_ON(handler == NULL); | 84 | BUG_ON(handler == NULL); |
89 | 85 | ||
90 | nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); | 86 | nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), |
91 | if (!nlh) { | 87 | nlmsg_flags); |
92 | nlmsg_trim(skb, b); | 88 | if (!nlh) |
93 | return -EMSGSIZE; | 89 | return -EMSGSIZE; |
94 | } | ||
95 | nlh->nlmsg_flags = nlmsg_flags; | ||
96 | 90 | ||
97 | r = nlmsg_data(nlh); | 91 | r = nlmsg_data(nlh); |
98 | BUG_ON(sk->sk_state == TCP_TIME_WAIT); | 92 | BUG_ON(sk->sk_state == TCP_TIME_WAIT); |
99 | 93 | ||
100 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) | ||
101 | minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo)); | ||
102 | |||
103 | r->idiag_family = sk->sk_family; | 94 | r->idiag_family = sk->sk_family; |
104 | r->idiag_state = sk->sk_state; | 95 | r->idiag_state = sk->sk_state; |
105 | r->idiag_timer = 0; | 96 | r->idiag_timer = 0; |
@@ -117,7 +108,8 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
117 | * hence this needs to be included regardless of socket family. | 108 | * hence this needs to be included regardless of socket family. |
118 | */ | 109 | */ |
119 | if (ext & (1 << (INET_DIAG_TOS - 1))) | 110 | if (ext & (1 << (INET_DIAG_TOS - 1))) |
120 | RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos); | 111 | if (nla_put_u8(skb, INET_DIAG_TOS, inet->tos) < 0) |
112 | goto errout; | ||
121 | 113 | ||
122 | #if IS_ENABLED(CONFIG_IPV6) | 114 | #if IS_ENABLED(CONFIG_IPV6) |
123 | if (r->idiag_family == AF_INET6) { | 115 | if (r->idiag_family == AF_INET6) { |
@@ -125,24 +117,31 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
125 | 117 | ||
126 | *(struct in6_addr *)r->id.idiag_src = np->rcv_saddr; | 118 | *(struct in6_addr *)r->id.idiag_src = np->rcv_saddr; |
127 | *(struct in6_addr *)r->id.idiag_dst = np->daddr; | 119 | *(struct in6_addr *)r->id.idiag_dst = np->daddr; |
120 | |||
128 | if (ext & (1 << (INET_DIAG_TCLASS - 1))) | 121 | if (ext & (1 << (INET_DIAG_TCLASS - 1))) |
129 | RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass); | 122 | if (nla_put_u8(skb, INET_DIAG_TCLASS, np->tclass) < 0) |
123 | goto errout; | ||
130 | } | 124 | } |
131 | #endif | 125 | #endif |
132 | 126 | ||
133 | r->idiag_uid = sock_i_uid(sk); | 127 | r->idiag_uid = sock_i_uid(sk); |
134 | r->idiag_inode = sock_i_ino(sk); | 128 | r->idiag_inode = sock_i_ino(sk); |
135 | 129 | ||
136 | if (minfo) { | 130 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { |
137 | minfo->idiag_rmem = sk_rmem_alloc_get(sk); | 131 | struct inet_diag_meminfo minfo = { |
138 | minfo->idiag_wmem = sk->sk_wmem_queued; | 132 | .idiag_rmem = sk_rmem_alloc_get(sk), |
139 | minfo->idiag_fmem = sk->sk_forward_alloc; | 133 | .idiag_wmem = sk->sk_wmem_queued, |
140 | minfo->idiag_tmem = sk_wmem_alloc_get(sk); | 134 | .idiag_fmem = sk->sk_forward_alloc, |
135 | .idiag_tmem = sk_wmem_alloc_get(sk), | ||
136 | }; | ||
137 | |||
138 | if (nla_put(skb, INET_DIAG_MEMINFO, sizeof(minfo), &minfo) < 0) | ||
139 | goto errout; | ||
141 | } | 140 | } |
142 | 141 | ||
143 | if (ext & (1 << (INET_DIAG_SKMEMINFO - 1))) | 142 | if (ext & (1 << (INET_DIAG_SKMEMINFO - 1))) |
144 | if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO)) | 143 | if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO)) |
145 | goto rtattr_failure; | 144 | goto errout; |
146 | 145 | ||
147 | if (icsk == NULL) { | 146 | if (icsk == NULL) { |
148 | handler->idiag_get_info(sk, r, NULL); | 147 | handler->idiag_get_info(sk, r, NULL); |
@@ -169,16 +168,20 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
169 | } | 168 | } |
170 | #undef EXPIRES_IN_MS | 169 | #undef EXPIRES_IN_MS |
171 | 170 | ||
172 | if (ext & (1 << (INET_DIAG_INFO - 1))) | 171 | if (ext & (1 << (INET_DIAG_INFO - 1))) { |
173 | info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info)); | 172 | attr = nla_reserve(skb, INET_DIAG_INFO, |
173 | sizeof(struct tcp_info)); | ||
174 | if (!attr) | ||
175 | goto errout; | ||
174 | 176 | ||
175 | if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) { | 177 | info = nla_data(attr); |
176 | const size_t len = strlen(icsk->icsk_ca_ops->name); | ||
177 | |||
178 | strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1), | ||
179 | icsk->icsk_ca_ops->name); | ||
180 | } | 178 | } |
181 | 179 | ||
180 | if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) | ||
181 | if (nla_put_string(skb, INET_DIAG_CONG, | ||
182 | icsk->icsk_ca_ops->name) < 0) | ||
183 | goto errout; | ||
184 | |||
182 | handler->idiag_get_info(sk, r, info); | 185 | handler->idiag_get_info(sk, r, info); |
183 | 186 | ||
184 | if (sk->sk_state < TCP_TIME_WAIT && | 187 | if (sk->sk_state < TCP_TIME_WAIT && |
@@ -186,11 +189,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
186 | icsk->icsk_ca_ops->get_info(sk, ext, skb); | 189 | icsk->icsk_ca_ops->get_info(sk, ext, skb); |
187 | 190 | ||
188 | out: | 191 | out: |
189 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 192 | return nlmsg_end(skb, nlh); |
190 | return skb->len; | ||
191 | 193 | ||
192 | rtattr_failure: | 194 | errout: |
193 | nlmsg_trim(skb, b); | 195 | nlmsg_cancel(skb, nlh); |
194 | return -EMSGSIZE; | 196 | return -EMSGSIZE; |
195 | } | 197 | } |
196 | EXPORT_SYMBOL_GPL(inet_sk_diag_fill); | 198 | EXPORT_SYMBOL_GPL(inet_sk_diag_fill); |
@@ -211,20 +213,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
211 | { | 213 | { |
212 | long tmo; | 214 | long tmo; |
213 | struct inet_diag_msg *r; | 215 | struct inet_diag_msg *r; |
214 | const unsigned char *previous_tail = skb_tail_pointer(skb); | 216 | struct nlmsghdr *nlh; |
215 | struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, | ||
216 | unlh->nlmsg_type, sizeof(*r), 0); | ||
217 | 217 | ||
218 | if (!nlh) { | 218 | nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), |
219 | nlmsg_trim(skb, previous_tail); | 219 | nlmsg_flags); |
220 | if (!nlh) | ||
220 | return -EMSGSIZE; | 221 | return -EMSGSIZE; |
221 | } | ||
222 | 222 | ||
223 | r = nlmsg_data(nlh); | 223 | r = nlmsg_data(nlh); |
224 | BUG_ON(tw->tw_state != TCP_TIME_WAIT); | 224 | BUG_ON(tw->tw_state != TCP_TIME_WAIT); |
225 | 225 | ||
226 | nlh->nlmsg_flags = nlmsg_flags; | ||
227 | |||
228 | tmo = tw->tw_ttd - jiffies; | 226 | tmo = tw->tw_ttd - jiffies; |
229 | if (tmo < 0) | 227 | if (tmo < 0) |
230 | tmo = 0; | 228 | tmo = 0; |
@@ -253,8 +251,8 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
253 | *(struct in6_addr *)r->id.idiag_dst = tw6->tw_v6_daddr; | 251 | *(struct in6_addr *)r->id.idiag_dst = tw6->tw_v6_daddr; |
254 | } | 252 | } |
255 | #endif | 253 | #endif |
256 | nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail; | 254 | |
257 | return skb->len; | 255 | return nlmsg_end(skb, nlh); |
258 | } | 256 | } |
259 | 257 | ||
260 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | 258 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, |
@@ -303,20 +301,20 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s | |||
303 | if (err) | 301 | if (err) |
304 | goto out; | 302 | goto out; |
305 | 303 | ||
306 | err = -ENOMEM; | 304 | rep = nlmsg_new(sizeof(struct inet_diag_msg) + |
307 | rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) + | 305 | sizeof(struct inet_diag_meminfo) + |
308 | sizeof(struct inet_diag_meminfo) + | 306 | sizeof(struct tcp_info) + 64, GFP_KERNEL); |
309 | sizeof(struct tcp_info) + 64)), | 307 | if (!rep) { |
310 | GFP_KERNEL); | 308 | err = -ENOMEM; |
311 | if (!rep) | ||
312 | goto out; | 309 | goto out; |
310 | } | ||
313 | 311 | ||
314 | err = sk_diag_fill(sk, rep, req, | 312 | err = sk_diag_fill(sk, rep, req, |
315 | NETLINK_CB(in_skb).pid, | 313 | NETLINK_CB(in_skb).pid, |
316 | nlh->nlmsg_seq, 0, nlh); | 314 | nlh->nlmsg_seq, 0, nlh); |
317 | if (err < 0) { | 315 | if (err < 0) { |
318 | WARN_ON(err == -EMSGSIZE); | 316 | WARN_ON(err == -EMSGSIZE); |
319 | kfree_skb(rep); | 317 | nlmsg_free(rep); |
320 | goto out; | 318 | goto out; |
321 | } | 319 | } |
322 | err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, | 320 | err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, |
@@ -597,19 +595,16 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
597 | { | 595 | { |
598 | const struct inet_request_sock *ireq = inet_rsk(req); | 596 | const struct inet_request_sock *ireq = inet_rsk(req); |
599 | struct inet_sock *inet = inet_sk(sk); | 597 | struct inet_sock *inet = inet_sk(sk); |
600 | unsigned char *b = skb_tail_pointer(skb); | ||
601 | struct inet_diag_msg *r; | 598 | struct inet_diag_msg *r; |
602 | struct nlmsghdr *nlh; | 599 | struct nlmsghdr *nlh; |
603 | long tmo; | 600 | long tmo; |
604 | 601 | ||
605 | nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 0); | 602 | nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), |
606 | if (!nlh) { | 603 | NLM_F_MULTI); |
607 | nlmsg_trim(skb, b); | 604 | if (!nlh) |
608 | return -1; | 605 | return -EMSGSIZE; |
609 | } | ||
610 | nlh->nlmsg_flags = NLM_F_MULTI; | ||
611 | r = nlmsg_data(nlh); | ||
612 | 606 | ||
607 | r = nlmsg_data(nlh); | ||
613 | r->idiag_family = sk->sk_family; | 608 | r->idiag_family = sk->sk_family; |
614 | r->idiag_state = TCP_SYN_RECV; | 609 | r->idiag_state = TCP_SYN_RECV; |
615 | r->idiag_timer = 1; | 610 | r->idiag_timer = 1; |
@@ -637,9 +632,8 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
637 | *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; | 632 | *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; |
638 | } | 633 | } |
639 | #endif | 634 | #endif |
640 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | ||
641 | 635 | ||
642 | return skb->len; | 636 | return nlmsg_end(skb, nlh); |
643 | } | 637 | } |
644 | 638 | ||
645 | static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | 639 | static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, |