diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2016-06-23 21:42:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-28 05:25:04 -0400 |
commit | 637c841dd7a5f9bd97b75cbe90b526fa1a52e530 (patch) | |
tree | c508dea977e73a40f8a52827e1606491d4a687f8 /net/ipv4 | |
parent | 1ba44a1f4d8160387bdaab0f414bdbcc74f2d59b (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.c | 25 |
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 | ||
49 | static DEFINE_MUTEX(inet_diag_table_mutex); | 50 | static 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 */ | ||
650 | static 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. */ |
640 | static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, | 661 | static 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: |