@@ -22,5 +22,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
void sock_diag_save_cookie(void *sk, __u32 *cookie);
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
+int sock_diag_put_filterinfo(struct sock *sk, struct sk_buff *skb,
+ int attrtype);
#endif
@@ -17,6 +17,7 @@ struct packet_diag_req {
#define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */
#define PACKET_SHOW_FANOUT 0x00000008
#define PACKET_SHOW_MEMINFO 0x00000010
+#define PACKET_SHOW_FILTER 0x00000020
struct packet_diag_msg {
__u8 pdiag_family;
@@ -35,6 +36,7 @@ enum {
PACKET_DIAG_FANOUT,
PACKET_DIAG_UID,
PACKET_DIAG_MEMINFO,
+ PACKET_DIAG_FILTER,
__PACKET_DIAG_MAX,
};
@@ -49,6 +49,33 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
}
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
+int sock_diag_put_filterinfo(struct sock *sk, struct sk_buff *skb, int attrtype)
+{
+ struct nlattr *attr;
+ struct sk_filter *filter;
+ unsigned int len;
+ int err = 0;
+
+ rcu_read_lock();
+
+ filter = rcu_dereference(sk->sk_filter);
+ len = filter ? filter->len * sizeof(struct sock_filter) : 0;
+
+ attr = nla_reserve(skb, attrtype, len);
+ if (attr == NULL) {
+ err = -EMSGSIZE;
+ goto out;
+ }
+
+ if (filter)
+ memcpy(nla_data(attr), filter->insns, len);
+
+out:
+ rcu_read_unlock();
+ return err;
+}
+EXPORT_SYMBOL(sock_diag_put_filterinfo);
+
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
{
mutex_lock(&sock_diag_table_mutex);
@@ -170,6 +170,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
goto out_nlmsg_trim;
+ if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
+ sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER))
+ goto out_nlmsg_trim;
+
return nlmsg_end(skb, nlh);
out_nlmsg_trim:
This patch allows to dump BPF filters attached to a socket. For now, only packet sockets use this feature. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> --- include/linux/sock_diag.h | 2 ++ include/uapi/linux/packet_diag.h | 2 ++ net/core/sock_diag.c | 27 +++++++++++++++++++++++++++ net/packet/diag.c | 4 ++++ 4 files changed, 35 insertions(+)