diff options
Diffstat (limited to 'net/core/sock_diag.c')
| -rw-r--r-- | net/core/sock_diag.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index a29e90cf36b..a4216a4c957 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -49,6 +49,41 @@ 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(bool may_report_filterinfo, struct sock *sk, + struct sk_buff *skb, int attrtype) +{ + struct sock_fprog_kern *fprog; + struct sk_filter *filter; + struct nlattr *attr; + unsigned int flen; + int err = 0; + + if (!may_report_filterinfo) { + nla_reserve(skb, attrtype, 0); + return 0; + } + + rcu_read_lock(); + filter = rcu_dereference(sk->sk_filter); + if (!filter) + goto out; + + fprog = filter->orig_prog; + flen = sk_filter_proglen(fprog); + + attr = nla_reserve(skb, attrtype, flen); + if (attr == NULL) { + err = -EMSGSIZE; + goto out; + } + + memcpy(nla_data(attr), fprog->filter, flen); +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); |
