aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/inet_diag.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index c3b334871707..4c4ae4aaf8f6 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -51,8 +51,8 @@ static struct sock *idiagnl;
51 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) 51 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
52 52
53static int inet_diag_fill(struct sk_buff *skb, struct sock *sk, 53static int inet_diag_fill(struct sk_buff *skb, struct sock *sk,
54 int ext, u32 pid, u32 seq, u16 nlmsg_flags, 54 int ext, u32 pid, u32 seq, u16 nlmsg_flags,
55 const struct nlmsghdr *unlh) 55 const struct nlmsghdr *unlh)
56{ 56{
57 const struct inet_sock *inet = inet_sk(sk); 57 const struct inet_sock *inet = inet_sk(sk);
58 const struct inet_connection_sock *icsk = inet_csk(sk); 58 const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -77,7 +77,7 @@ static int inet_diag_fill(struct sk_buff *skb, struct sock *sk,
77 if (ext & (1 << (INET_DIAG_INFO - 1))) 77 if (ext & (1 << (INET_DIAG_INFO - 1)))
78 info = INET_DIAG_PUT(skb, INET_DIAG_INFO, 78 info = INET_DIAG_PUT(skb, INET_DIAG_INFO,
79 handler->idiag_info_size); 79 handler->idiag_info_size);
80 80
81 if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) { 81 if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
82 size_t len = strlen(icsk->icsk_ca_ops->name); 82 size_t len = strlen(icsk->icsk_ca_ops->name);
83 strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1), 83 strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
@@ -185,7 +185,8 @@ nlmsg_failure:
185 return -1; 185 return -1;
186} 186}
187 187
188static int inet_diag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh) 188static int inet_diag_get_exact(struct sk_buff *in_skb,
189 const struct nlmsghdr *nlh)
189{ 190{
190 int err; 191 int err;
191 struct sock *sk; 192 struct sock *sk;
@@ -283,7 +284,7 @@ static int bitstring_match(const u32 *a1, const u32 *a2, int bits)
283 284
284 285
285static int inet_diag_bc_run(const void *bc, int len, 286static int inet_diag_bc_run(const void *bc, int len,
286 const struct inet_diag_entry *entry) 287 const struct inet_diag_entry *entry)
287{ 288{
288 while (len > 0) { 289 while (len > 0) {
289 int yes = 1; 290 int yes = 1;
@@ -322,7 +323,7 @@ static int inet_diag_bc_run(const void *bc, int len,
322 yes = 0; 323 yes = 0;
323 break; 324 break;
324 } 325 }
325 326
326 if (cond->prefix_len == 0) 327 if (cond->prefix_len == 0)
327 break; 328 break;
328 329
@@ -331,7 +332,8 @@ static int inet_diag_bc_run(const void *bc, int len,
331 else 332 else
332 addr = entry->daddr; 333 addr = entry->daddr;
333 334
334 if (bitstring_match(addr, cond->addr, cond->prefix_len)) 335 if (bitstring_match(addr, cond->addr,
336 cond->prefix_len))
335 break; 337 break;
336 if (entry->family == AF_INET6 && 338 if (entry->family == AF_INET6 &&
337 cond->family == AF_INET) { 339 cond->family == AF_INET) {
@@ -346,7 +348,7 @@ static int inet_diag_bc_run(const void *bc, int len,
346 } 348 }
347 } 349 }
348 350
349 if (yes) { 351 if (yes) {
350 len -= op->yes; 352 len -= op->yes;
351 bc += op->yes; 353 bc += op->yes;
352 } else { 354 } else {
@@ -407,14 +409,14 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
407 default: 409 default:
408 return -EINVAL; 410 return -EINVAL;
409 } 411 }
410 bc += op->yes; 412 bc += op->yes;
411 len -= op->yes; 413 len -= op->yes;
412 } 414 }
413 return len == 0 ? 0 : -EINVAL; 415 return len == 0 ? 0 : -EINVAL;
414} 416}
415 417
416static int inet_diag_dump_sock(struct sk_buff *skb, struct sock *sk, 418static int inet_diag_dump_sock(struct sk_buff *skb, struct sock *sk,
417 struct netlink_callback *cb) 419 struct netlink_callback *cb)
418{ 420{
419 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 421 struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
420 422
@@ -445,13 +447,12 @@ static int inet_diag_dump_sock(struct sk_buff *skb, struct sock *sk,
445 } 447 }
446 448
447 return inet_diag_fill(skb, sk, r->idiag_ext, NETLINK_CB(cb->skb).pid, 449 return inet_diag_fill(skb, sk, r->idiag_ext, NETLINK_CB(cb->skb).pid,
448 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 450 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
449} 451}
450 452
451static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, 453static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
452 struct request_sock *req, 454 struct request_sock *req, u32 pid, u32 seq,
453 u32 pid, u32 seq, 455 const struct nlmsghdr *unlh)
454 const struct nlmsghdr *unlh)
455{ 456{
456 const struct inet_request_sock *ireq = inet_rsk(req); 457 const struct inet_request_sock *ireq = inet_rsk(req);
457 struct inet_sock *inet = inet_sk(sk); 458 struct inet_sock *inet = inet_sk(sk);
@@ -504,7 +505,7 @@ nlmsg_failure:
504} 505}
505 506
506static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, 507static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
507 struct netlink_callback *cb) 508 struct netlink_callback *cb)
508{ 509{
509 struct inet_diag_entry entry; 510 struct inet_diag_entry entry;
510 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 511 struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
@@ -556,7 +557,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
556 inet6_rsk(req)->loc_addr.s6_addr32 : 557 inet6_rsk(req)->loc_addr.s6_addr32 :
557#endif 558#endif
558 &ireq->loc_addr; 559 &ireq->loc_addr;
559 entry.daddr = 560 entry.daddr =
560#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 561#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
561 (entry.family == AF_INET6) ? 562 (entry.family == AF_INET6) ?
562 inet6_rsk(req)->rmt_addr.s6_addr32 : 563 inet6_rsk(req)->rmt_addr.s6_addr32 :
@@ -599,7 +600,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
599 handler = inet_diag_table[cb->nlh->nlmsg_type]; 600 handler = inet_diag_table[cb->nlh->nlmsg_type];
600 BUG_ON(handler == NULL); 601 BUG_ON(handler == NULL);
601 hashinfo = handler->idiag_hashinfo; 602 hashinfo = handler->idiag_hashinfo;
602 603
603 s_i = cb->args[1]; 604 s_i = cb->args[1];
604 s_num = num = cb->args[2]; 605 s_num = num = cb->args[2];
605 606
@@ -672,7 +673,6 @@ skip_listen_ht:
672 s_num = 0; 673 s_num = 0;
673 674
674 read_lock_bh(&head->lock); 675 read_lock_bh(&head->lock);
675
676 num = 0; 676 num = 0;
677 sk_for_each(sk, node, &head->chain) { 677 sk_for_each(sk, node, &head->chain) {
678 struct inet_sock *inet = inet_sk(sk); 678 struct inet_sock *inet = inet_sk(sk);
@@ -684,7 +684,8 @@ skip_listen_ht:
684 if (r->id.idiag_sport != inet->sport && 684 if (r->id.idiag_sport != inet->sport &&
685 r->id.idiag_sport) 685 r->id.idiag_sport)
686 goto next_normal; 686 goto next_normal;
687 if (r->id.idiag_dport != inet->dport && r->id.idiag_dport) 687 if (r->id.idiag_dport != inet->dport &&
688 r->id.idiag_dport)
688 goto next_normal; 689 goto next_normal;
689 if (inet_diag_dump_sock(skb, sk, cb) < 0) { 690 if (inet_diag_dump_sock(skb, sk, cb) < 0) {
690 read_unlock_bh(&head->lock); 691 read_unlock_bh(&head->lock);
@@ -724,8 +725,7 @@ done:
724 return skb->len; 725 return skb->len;
725} 726}
726 727
727static __inline__ int 728static inline int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
728inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
729{ 729{
730 if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) 730 if (!(nlh->nlmsg_flags&NLM_F_REQUEST))
731 return 0; 731 return 0;
@@ -755,9 +755,8 @@ inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
755 } 755 }
756 return netlink_dump_start(idiagnl, skb, nlh, 756 return netlink_dump_start(idiagnl, skb, nlh,
757 inet_diag_dump, NULL); 757 inet_diag_dump, NULL);
758 } else { 758 } else
759 return inet_diag_get_exact(skb, nlh); 759 return inet_diag_get_exact(skb, nlh);
760 }
761 760
762err_inval: 761err_inval:
763 return -EINVAL; 762 return -EINVAL;
@@ -766,15 +765,15 @@ err_inval:
766 765
767static inline void inet_diag_rcv_skb(struct sk_buff *skb) 766static inline void inet_diag_rcv_skb(struct sk_buff *skb)
768{ 767{
769 int err;
770 struct nlmsghdr * nlh;
771
772 if (skb->len >= NLMSG_SPACE(0)) { 768 if (skb->len >= NLMSG_SPACE(0)) {
773 nlh = (struct nlmsghdr *)skb->data; 769 int err;
774 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 770 struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
771
772 if (nlh->nlmsg_len < sizeof(*nlh) ||
773 skb->len < nlh->nlmsg_len)
775 return; 774 return;
776 err = inet_diag_rcv_msg(skb, nlh); 775 err = inet_diag_rcv_msg(skb, nlh);
777 if (err || nlh->nlmsg_flags & NLM_F_ACK) 776 if (err || nlh->nlmsg_flags & NLM_F_ACK)
778 netlink_ack(skb, nlh, err); 777 netlink_ack(skb, nlh, err);
779 } 778 }
780} 779}