Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Conflicts: net/xfrm/xfrm_policy.c Minor merge conflict in xfrm_policy.c, consisting of overlapping changes which were trivial to resolve. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
296c10639a
@ -3,16 +3,6 @@
|
|||||||
|
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
|
|
||||||
struct crypto_aead;
|
|
||||||
|
|
||||||
struct esp_data {
|
|
||||||
/* 0..255 */
|
|
||||||
int padlen;
|
|
||||||
|
|
||||||
/* Confidentiality & Integrity */
|
|
||||||
struct crypto_aead *aead;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
|
void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
|
||||||
|
|
||||||
struct ip_esp_hdr;
|
struct ip_esp_hdr;
|
||||||
|
@ -121,7 +121,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
struct aead_givcrypt_request *req;
|
struct aead_givcrypt_request *req;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
struct scatterlist *asg;
|
struct scatterlist *asg;
|
||||||
struct esp_data *esp;
|
|
||||||
struct sk_buff *trailer;
|
struct sk_buff *trailer;
|
||||||
void *tmp;
|
void *tmp;
|
||||||
u8 *iv;
|
u8 *iv;
|
||||||
@ -139,8 +138,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
|
|
||||||
/* skb is pure payload to encrypt */
|
/* skb is pure payload to encrypt */
|
||||||
|
|
||||||
esp = x->data;
|
aead = x->data;
|
||||||
aead = esp->aead;
|
|
||||||
alen = crypto_aead_authsize(aead);
|
alen = crypto_aead_authsize(aead);
|
||||||
|
|
||||||
tfclen = 0;
|
tfclen = 0;
|
||||||
@ -154,8 +152,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
clen = ALIGN(skb->len + 2 + tfclen, blksize);
|
clen = ALIGN(skb->len + 2 + tfclen, blksize);
|
||||||
if (esp->padlen)
|
|
||||||
clen = ALIGN(clen, esp->padlen);
|
|
||||||
plen = clen - skb->len - tfclen;
|
plen = clen - skb->len - tfclen;
|
||||||
|
|
||||||
err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
|
err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
|
||||||
@ -280,8 +276,7 @@ static int esp_input_done2(struct sk_buff *skb, int err)
|
|||||||
{
|
{
|
||||||
const struct iphdr *iph;
|
const struct iphdr *iph;
|
||||||
struct xfrm_state *x = xfrm_input_state(skb);
|
struct xfrm_state *x = xfrm_input_state(skb);
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
struct crypto_aead *aead = esp->aead;
|
|
||||||
int alen = crypto_aead_authsize(aead);
|
int alen = crypto_aead_authsize(aead);
|
||||||
int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
|
int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
|
||||||
int elen = skb->len - hlen;
|
int elen = skb->len - hlen;
|
||||||
@ -376,8 +371,7 @@ static void esp_input_done(struct crypto_async_request *base, int err)
|
|||||||
static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ip_esp_hdr *esph;
|
struct ip_esp_hdr *esph;
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
struct crypto_aead *aead = esp->aead;
|
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
struct sk_buff *trailer;
|
struct sk_buff *trailer;
|
||||||
int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
|
int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
|
||||||
@ -459,9 +453,8 @@ out:
|
|||||||
|
|
||||||
static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
|
static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
|
u32 blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
u32 align = max_t(u32, blksize, esp->padlen);
|
|
||||||
unsigned int net_adj;
|
unsigned int net_adj;
|
||||||
|
|
||||||
switch (x->props.mode) {
|
switch (x->props.mode) {
|
||||||
@ -476,8 +469,8 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
|
return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
|
||||||
net_adj) & ~(align - 1)) + net_adj - 2;
|
net_adj) & ~(blksize - 1)) + net_adj - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esp4_err(struct sk_buff *skb, u32 info)
|
static void esp4_err(struct sk_buff *skb, u32 info)
|
||||||
@ -511,18 +504,16 @@ static void esp4_err(struct sk_buff *skb, u32 info)
|
|||||||
|
|
||||||
static void esp_destroy(struct xfrm_state *x)
|
static void esp_destroy(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
|
|
||||||
if (!esp)
|
if (!aead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
crypto_free_aead(esp->aead);
|
crypto_free_aead(aead);
|
||||||
kfree(esp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int esp_init_aead(struct xfrm_state *x)
|
static int esp_init_aead(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -531,7 +522,7 @@ static int esp_init_aead(struct xfrm_state *x)
|
|||||||
if (IS_ERR(aead))
|
if (IS_ERR(aead))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
esp->aead = aead;
|
x->data = aead;
|
||||||
|
|
||||||
err = crypto_aead_setkey(aead, x->aead->alg_key,
|
err = crypto_aead_setkey(aead, x->aead->alg_key,
|
||||||
(x->aead->alg_key_len + 7) / 8);
|
(x->aead->alg_key_len + 7) / 8);
|
||||||
@ -548,7 +539,6 @@ error:
|
|||||||
|
|
||||||
static int esp_init_authenc(struct xfrm_state *x)
|
static int esp_init_authenc(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
struct crypto_authenc_key_param *param;
|
struct crypto_authenc_key_param *param;
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
@ -583,7 +573,7 @@ static int esp_init_authenc(struct xfrm_state *x)
|
|||||||
if (IS_ERR(aead))
|
if (IS_ERR(aead))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
esp->aead = aead;
|
x->data = aead;
|
||||||
|
|
||||||
keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
|
keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
|
||||||
(x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
|
(x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
|
||||||
@ -638,16 +628,11 @@ error:
|
|||||||
|
|
||||||
static int esp_init_state(struct xfrm_state *x)
|
static int esp_init_state(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
u32 align;
|
u32 align;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
esp = kzalloc(sizeof(*esp), GFP_KERNEL);
|
x->data = NULL;
|
||||||
if (esp == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
x->data = esp;
|
|
||||||
|
|
||||||
if (x->aead)
|
if (x->aead)
|
||||||
err = esp_init_aead(x);
|
err = esp_init_aead(x);
|
||||||
@ -657,9 +642,7 @@ static int esp_init_state(struct xfrm_state *x)
|
|||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
aead = esp->aead;
|
aead = x->data;
|
||||||
|
|
||||||
esp->padlen = 0;
|
|
||||||
|
|
||||||
x->props.header_len = sizeof(struct ip_esp_hdr) +
|
x->props.header_len = sizeof(struct ip_esp_hdr) +
|
||||||
crypto_aead_ivsize(aead);
|
crypto_aead_ivsize(aead);
|
||||||
@ -683,9 +666,7 @@ static int esp_init_state(struct xfrm_state *x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
align = ALIGN(crypto_aead_blocksize(aead), 4);
|
align = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
if (esp->padlen)
|
x->props.trailer_len = align + 1 + crypto_aead_authsize(aead);
|
||||||
align = max_t(u32, align, esp->padlen);
|
|
||||||
x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return err;
|
return err;
|
||||||
|
@ -164,10 +164,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
u8 *iv;
|
u8 *iv;
|
||||||
u8 *tail;
|
u8 *tail;
|
||||||
__be32 *seqhi;
|
__be32 *seqhi;
|
||||||
struct esp_data *esp = x->data;
|
|
||||||
|
|
||||||
/* skb is pure payload to encrypt */
|
/* skb is pure payload to encrypt */
|
||||||
aead = esp->aead;
|
aead = x->data;
|
||||||
alen = crypto_aead_authsize(aead);
|
alen = crypto_aead_authsize(aead);
|
||||||
|
|
||||||
tfclen = 0;
|
tfclen = 0;
|
||||||
@ -181,8 +180,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
clen = ALIGN(skb->len + 2 + tfclen, blksize);
|
clen = ALIGN(skb->len + 2 + tfclen, blksize);
|
||||||
if (esp->padlen)
|
|
||||||
clen = ALIGN(clen, esp->padlen);
|
|
||||||
plen = clen - skb->len - tfclen;
|
plen = clen - skb->len - tfclen;
|
||||||
|
|
||||||
err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
|
err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
|
||||||
@ -271,8 +268,7 @@ error:
|
|||||||
static int esp_input_done2(struct sk_buff *skb, int err)
|
static int esp_input_done2(struct sk_buff *skb, int err)
|
||||||
{
|
{
|
||||||
struct xfrm_state *x = xfrm_input_state(skb);
|
struct xfrm_state *x = xfrm_input_state(skb);
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
struct crypto_aead *aead = esp->aead;
|
|
||||||
int alen = crypto_aead_authsize(aead);
|
int alen = crypto_aead_authsize(aead);
|
||||||
int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
|
int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
|
||||||
int elen = skb->len - hlen;
|
int elen = skb->len - hlen;
|
||||||
@ -325,8 +321,7 @@ static void esp_input_done(struct crypto_async_request *base, int err)
|
|||||||
static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ip_esp_hdr *esph;
|
struct ip_esp_hdr *esph;
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
struct crypto_aead *aead = esp->aead;
|
|
||||||
struct aead_request *req;
|
struct aead_request *req;
|
||||||
struct sk_buff *trailer;
|
struct sk_buff *trailer;
|
||||||
int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
|
int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
|
||||||
@ -414,9 +409,8 @@ out:
|
|||||||
|
|
||||||
static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
|
static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
|
u32 blksize = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
u32 align = max_t(u32, blksize, esp->padlen);
|
|
||||||
unsigned int net_adj;
|
unsigned int net_adj;
|
||||||
|
|
||||||
if (x->props.mode != XFRM_MODE_TUNNEL)
|
if (x->props.mode != XFRM_MODE_TUNNEL)
|
||||||
@ -424,8 +418,8 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
|
|||||||
else
|
else
|
||||||
net_adj = 0;
|
net_adj = 0;
|
||||||
|
|
||||||
return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
|
return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
|
||||||
net_adj) & ~(align - 1)) + net_adj - 2;
|
net_adj) & ~(blksize - 1)) + net_adj - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||||
@ -454,18 +448,16 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
|||||||
|
|
||||||
static void esp6_destroy(struct xfrm_state *x)
|
static void esp6_destroy(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
struct crypto_aead *aead = x->data;
|
||||||
|
|
||||||
if (!esp)
|
if (!aead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
crypto_free_aead(esp->aead);
|
crypto_free_aead(aead);
|
||||||
kfree(esp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int esp_init_aead(struct xfrm_state *x)
|
static int esp_init_aead(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -474,7 +466,7 @@ static int esp_init_aead(struct xfrm_state *x)
|
|||||||
if (IS_ERR(aead))
|
if (IS_ERR(aead))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
esp->aead = aead;
|
x->data = aead;
|
||||||
|
|
||||||
err = crypto_aead_setkey(aead, x->aead->alg_key,
|
err = crypto_aead_setkey(aead, x->aead->alg_key,
|
||||||
(x->aead->alg_key_len + 7) / 8);
|
(x->aead->alg_key_len + 7) / 8);
|
||||||
@ -491,7 +483,6 @@ error:
|
|||||||
|
|
||||||
static int esp_init_authenc(struct xfrm_state *x)
|
static int esp_init_authenc(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp = x->data;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
struct crypto_authenc_key_param *param;
|
struct crypto_authenc_key_param *param;
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
@ -526,7 +517,7 @@ static int esp_init_authenc(struct xfrm_state *x)
|
|||||||
if (IS_ERR(aead))
|
if (IS_ERR(aead))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
esp->aead = aead;
|
x->data = aead;
|
||||||
|
|
||||||
keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
|
keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
|
||||||
(x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
|
(x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
|
||||||
@ -581,7 +572,6 @@ error:
|
|||||||
|
|
||||||
static int esp6_init_state(struct xfrm_state *x)
|
static int esp6_init_state(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct esp_data *esp;
|
|
||||||
struct crypto_aead *aead;
|
struct crypto_aead *aead;
|
||||||
u32 align;
|
u32 align;
|
||||||
int err;
|
int err;
|
||||||
@ -589,11 +579,7 @@ static int esp6_init_state(struct xfrm_state *x)
|
|||||||
if (x->encap)
|
if (x->encap)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
esp = kzalloc(sizeof(*esp), GFP_KERNEL);
|
x->data = NULL;
|
||||||
if (esp == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
x->data = esp;
|
|
||||||
|
|
||||||
if (x->aead)
|
if (x->aead)
|
||||||
err = esp_init_aead(x);
|
err = esp_init_aead(x);
|
||||||
@ -603,9 +589,7 @@ static int esp6_init_state(struct xfrm_state *x)
|
|||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
aead = esp->aead;
|
aead = x->data;
|
||||||
|
|
||||||
esp->padlen = 0;
|
|
||||||
|
|
||||||
x->props.header_len = sizeof(struct ip_esp_hdr) +
|
x->props.header_len = sizeof(struct ip_esp_hdr) +
|
||||||
crypto_aead_ivsize(aead);
|
crypto_aead_ivsize(aead);
|
||||||
@ -625,9 +609,7 @@ static int esp6_init_state(struct xfrm_state *x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
align = ALIGN(crypto_aead_blocksize(aead), 4);
|
align = ALIGN(crypto_aead_blocksize(aead), 4);
|
||||||
if (esp->padlen)
|
x->props.trailer_len = align + 1 + crypto_aead_authsize(aead);
|
||||||
align = max_t(u32, align, esp->padlen);
|
|
||||||
x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return err;
|
return err;
|
||||||
|
@ -220,8 +220,8 @@ static void ipcomp_free_scratches(void)
|
|||||||
|
|
||||||
static void * __percpu *ipcomp_alloc_scratches(void)
|
static void * __percpu *ipcomp_alloc_scratches(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
void * __percpu *scratches;
|
void * __percpu *scratches;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ipcomp_scratch_users++)
|
if (ipcomp_scratch_users++)
|
||||||
return ipcomp_scratches;
|
return ipcomp_scratches;
|
||||||
@ -233,7 +233,9 @@ static void * __percpu *ipcomp_alloc_scratches(void)
|
|||||||
ipcomp_scratches = scratches;
|
ipcomp_scratches = scratches;
|
||||||
|
|
||||||
for_each_possible_cpu(i) {
|
for_each_possible_cpu(i) {
|
||||||
void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE);
|
void *scratch;
|
||||||
|
|
||||||
|
scratch = vmalloc_node(IPCOMP_SCRATCH_SIZE, cpu_to_node(i));
|
||||||
if (!scratch)
|
if (!scratch)
|
||||||
return NULL;
|
return NULL;
|
||||||
*per_cpu_ptr(scratches, i) = scratch;
|
*per_cpu_ptr(scratches, i) = scratch;
|
||||||
|
@ -1844,6 +1844,13 @@ static int xdst_queue_output(struct sk_buff *skb)
|
|||||||
struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
|
struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
|
||||||
struct xfrm_policy *pol = xdst->pols[0];
|
struct xfrm_policy *pol = xdst->pols[0];
|
||||||
struct xfrm_policy_queue *pq = &pol->polq;
|
struct xfrm_policy_queue *pq = &pol->polq;
|
||||||
|
const struct sk_buff *fclone = skb + 1;
|
||||||
|
|
||||||
|
if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
|
||||||
|
fclone->fclone == SKB_FCLONE_CLONE)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) {
|
if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user