diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2016-06-23 18:42:51 -0700 |
---|---|---|
committer | Ben Fennema <fennema@google.com> | 2017-01-17 15:30:02 -0800 |
commit | 8dba8544f680b049e063747eddd005eefa87e360 (patch) | |
tree | 43ca4aa40d6f72e1622f11e2d61b69001cb2ad70 | |
parent | 4aa8c49b16abc55dc1d7118a2ef96f806d127f14 (diff) | |
download | mediatek-8dba8544f680b049e063747eddd005eefa87e360.tar.gz |
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.
[backport of net-next 637c841dd7a5f9bd97b75cbe90b526fa1a52e530]
Change-Id: Ib430cfb44f1b3b1a771a561247ee9140737e52fd
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/uapi/linux/inet_diag.h | 1 | ||||
-rw-r--r-- | net/ipv4/inet_diag.c | 25 |
2 files changed, 26 insertions, 0 deletions
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index bbde90fa5838..43601eaf63ef 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h @@ -72,6 +72,7 @@ enum { INET_DIAG_BC_AUTO, INET_DIAG_BC_S_COND, INET_DIAG_BC_D_COND, + INET_DIAG_BC_DEV_COND, /* u32 ifindex */ }; struct inet_diag_hostcond { diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index b7527bfdc6a7..8fd708193e42 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -48,6 +48,7 @@ struct inet_diag_entry { struct in6_addr saddr_storage; /* for IPv4-mapped-IPv6 addresses */ struct in6_addr daddr_storage; /* for IPv4-mapped-IPv6 addresses */ #endif + u32 ifindex; }; static DEFINE_MUTEX(inet_diag_table_mutex); @@ -504,6 +505,14 @@ static int inet_diag_bc_run(const struct nlattr *_bc, yes = 0; break; } + case INET_DIAG_BC_DEV_COND: { + u32 ifindex; + + ifindex = *((const u32 *)(op + 1)); + if (ifindex != entry->ifindex) + yes = 0; + break; + } } if (yes) { @@ -540,6 +549,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) } entry.sport = inet->inet_num; entry.dport = ntohs(inet->inet_dport); + entry.ifindex = sk->sk_bound_dev_if; entry.userlocks = sk->sk_userlocks; return inet_diag_bc_run(bc, &entry); @@ -563,6 +573,17 @@ static int valid_cc(const void *bc, int len, int cc) return 0; } +/* data is u32 ifindex */ +static bool valid_devcond(const struct inet_diag_bc_op *op, int len, + int *min_len) +{ + /* Check ifindex space. */ + *min_len += sizeof(u32); + if (len < *min_len) + return false; + + return true; +} /* Validate an inet_diag_hostcond. */ static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, int *min_len) @@ -628,6 +649,10 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) if (!valid_hostcond(bc, len, &min_len)) return -EINVAL; break; + case INET_DIAG_BC_DEV_COND: + if (!valid_devcond(bc, len, &min_len)) + return -EINVAL; + break; case INET_DIAG_BC_S_GE: case INET_DIAG_BC_S_LE: case INET_DIAG_BC_D_GE: |