net: filter: simplify socket charging
attaching bpf program to a socket involves multiple socket memory arithmetic, since size of 'sk_filter' is changing when classic BPF is converted to eBPF. Also common path of program creation has to deal with two ways of freeing the memory. Simplify the code by delaying socket charging until program is ready and its size is known Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
4330487acf
commit
278571baca
@@ -1474,6 +1474,7 @@ static void sk_update_clone(const struct sock *sk, struct sock *newsk)
|
||||
struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||
{
|
||||
struct sock *newsk;
|
||||
bool is_charged = true;
|
||||
|
||||
newsk = sk_prot_alloc(sk->sk_prot, priority, sk->sk_family);
|
||||
if (newsk != NULL) {
|
||||
@@ -1518,9 +1519,13 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||
|
||||
filter = rcu_dereference_protected(newsk->sk_filter, 1);
|
||||
if (filter != NULL)
|
||||
sk_filter_charge(newsk, filter);
|
||||
/* though it's an empty new sock, the charging may fail
|
||||
* if sysctl_optmem_max was changed between creation of
|
||||
* original socket and cloning
|
||||
*/
|
||||
is_charged = sk_filter_charge(newsk, filter);
|
||||
|
||||
if (unlikely(xfrm_sk_clone_policy(newsk))) {
|
||||
if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk))) {
|
||||
/* It is still raw copy of parent, so invalidate
|
||||
* destructor and make plain sk_free() */
|
||||
newsk->sk_destruct = NULL;
|
||||
|
Reference in New Issue
Block a user