aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2016-06-23 21:42:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-28 05:25:04 -0400
commit637c841dd7a5f9bd97b75cbe90b526fa1a52e530 (patch)
treec508dea977e73a40f8a52827e1606491d4a687f8 /net/ipv4
parent1ba44a1f4d8160387bdaab0f414bdbcc74f2d59b (diff)
net: diag: Add support to filter on device index
Add support to inet_diag facility to filter sockets based on device index. If an interface index is in the filter only sockets bound to that index (sk_bound_dev_if) are returned. Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/inet_diag.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 25af1243649b..38c2c47fe0e8 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -44,6 +44,7 @@ struct inet_diag_entry {
44 u16 dport; 44 u16 dport;
45 u16 family; 45 u16 family;
46 u16 userlocks; 46 u16 userlocks;
47 u32 ifindex;
47}; 48};
48 49
49static DEFINE_MUTEX(inet_diag_table_mutex); 50static DEFINE_MUTEX(inet_diag_table_mutex);
@@ -571,6 +572,14 @@ static int inet_diag_bc_run(const struct nlattr *_bc,
571 yes = 0; 572 yes = 0;
572 break; 573 break;
573 } 574 }
575 case INET_DIAG_BC_DEV_COND: {
576 u32 ifindex;
577
578 ifindex = *((const u32 *)(op + 1));
579 if (ifindex != entry->ifindex)
580 yes = 0;
581 break;
582 }
574 } 583 }
575 584
576 if (yes) { 585 if (yes) {
@@ -613,6 +622,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
613 entry_fill_addrs(&entry, sk); 622 entry_fill_addrs(&entry, sk);
614 entry.sport = inet->inet_num; 623 entry.sport = inet->inet_num;
615 entry.dport = ntohs(inet->inet_dport); 624 entry.dport = ntohs(inet->inet_dport);
625 entry.ifindex = sk->sk_bound_dev_if;
616 entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0; 626 entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0;
617 627
618 return inet_diag_bc_run(bc, &entry); 628 return inet_diag_bc_run(bc, &entry);
@@ -636,6 +646,17 @@ static int valid_cc(const void *bc, int len, int cc)
636 return 0; 646 return 0;
637} 647}
638 648
649/* data is u32 ifindex */
650static bool valid_devcond(const struct inet_diag_bc_op *op, int len,
651 int *min_len)
652{
653 /* Check ifindex space. */
654 *min_len += sizeof(u32);
655 if (len < *min_len)
656 return false;
657
658 return true;
659}
639/* Validate an inet_diag_hostcond. */ 660/* Validate an inet_diag_hostcond. */
640static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, 661static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
641 int *min_len) 662 int *min_len)
@@ -700,6 +721,10 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
700 if (!valid_hostcond(bc, len, &min_len)) 721 if (!valid_hostcond(bc, len, &min_len))
701 return -EINVAL; 722 return -EINVAL;
702 break; 723 break;
724 case INET_DIAG_BC_DEV_COND:
725 if (!valid_devcond(bc, len, &min_len))
726 return -EINVAL;
727 break;
703 case INET_DIAG_BC_S_GE: 728 case INET_DIAG_BC_S_GE:
704 case INET_DIAG_BC_S_LE: 729 case INET_DIAG_BC_S_LE:
705 case INET_DIAG_BC_D_GE: 730 case INET_DIAG_BC_D_GE: