Commit 25995ff5 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[SOCK]: Introduce sk_receive_skb

Its common enough to to justify that, TCP still can't use it as it has the
prequeueing stuff, still to be made generic in the not so distant future :-)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce1d4d3e
...@@ -383,8 +383,6 @@ static int pppoe_rcv(struct sk_buff *skb, ...@@ -383,8 +383,6 @@ static int pppoe_rcv(struct sk_buff *skb,
{ {
struct pppoe_hdr *ph; struct pppoe_hdr *ph;
struct pppox_sock *po; struct pppox_sock *po;
struct sock *sk;
int ret;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto drop; goto drop;
...@@ -395,24 +393,8 @@ static int pppoe_rcv(struct sk_buff *skb, ...@@ -395,24 +393,8 @@ static int pppoe_rcv(struct sk_buff *skb,
ph = (struct pppoe_hdr *) skb->nh.raw; ph = (struct pppoe_hdr *) skb->nh.raw;
po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
if (!po) if (po != NULL)
goto drop; return sk_receive_skb(sk_pppox(po), skb);
sk = sk_pppox(po);
bh_lock_sock(sk);
/* Socket state is unknown, must put skb into backlog. */
if (sock_owned_by_user(sk) != 0) {
sk_add_backlog(sk, skb);
ret = NET_RX_SUCCESS;
} else {
ret = pppoe_rcv_core(sk, skb);
}
bh_unlock_sock(sk);
sock_put(sk);
return ret;
drop: drop:
kfree_skb(skb); kfree_skb(skb);
out: out:
......
...@@ -926,6 +926,29 @@ static inline void sock_put(struct sock *sk) ...@@ -926,6 +926,29 @@ static inline void sock_put(struct sock *sk)
sk_free(sk); sk_free(sk);
} }
static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
{
int rc = NET_RX_SUCCESS;
if (sk_filter(sk, skb, 0))
goto discard_and_relse;
skb->dev = NULL;
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
rc = sk->sk_backlog_rcv(sk, skb);
else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
out:
sock_put(sk);
return rc;
discard_and_relse:
kfree_skb(skb);
goto out;
}
/* Detach socket from process context. /* Detach socket from process context.
* Announce socket dead, detach it from wait queue and inode. * Announce socket dead, detach it from wait queue and inode.
* Note that parent inode held reference count on this struct sock, * Note that parent inode held reference count on this struct sock,
......
...@@ -914,7 +914,6 @@ int dccp_v4_rcv(struct sk_buff *skb) ...@@ -914,7 +914,6 @@ int dccp_v4_rcv(struct sk_buff *skb)
{ {
const struct dccp_hdr *dh; const struct dccp_hdr *dh;
struct sock *sk; struct sock *sk;
int rc;
/* Step 1: Check header basics: */ /* Step 1: Check header basics: */
...@@ -984,28 +983,10 @@ int dccp_v4_rcv(struct sk_buff *skb) ...@@ -984,28 +983,10 @@ int dccp_v4_rcv(struct sk_buff *skb)
goto do_time_wait; goto do_time_wait;
} }
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) { if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
dccp_pr_debug("xfrm4_policy_check failed\n");
goto discard_and_relse; goto discard_and_relse;
}
if (sk_filter(sk, skb, 0)) {
dccp_pr_debug("sk_filter failed\n");
goto discard_and_relse;
}
skb->dev = NULL;
bh_lock_sock(sk); return sk_receive_skb(sk, skb);
rc = 0;
if (!sock_owned_by_user(sk))
rc = dccp_v4_do_rcv(sk, skb);
else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
sock_put(sk);
return rc;
no_dccp_socket: no_dccp_socket:
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
......
...@@ -1032,7 +1032,6 @@ static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) ...@@ -1032,7 +1032,6 @@ static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
const struct dccp_hdr *dh; const struct dccp_hdr *dh;
struct sk_buff *skb = *pskb; struct sk_buff *skb = *pskb;
struct sock *sk; struct sock *sk;
int rc;
/* Step 1: Check header basics: */ /* Step 1: Check header basics: */
...@@ -1077,21 +1076,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) ...@@ -1077,21 +1076,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse; goto discard_and_relse;
if (sk_filter(sk, skb, 0)) return sk_receive_skb(sk, skb) ? -1 : 0;
goto discard_and_relse;
skb->dev = NULL;
bh_lock_sock(sk);
rc = 0;
if (!sock_owned_by_user(sk))
rc = dccp_v6_do_rcv(sk, skb);
else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
sock_put(sk);
return rc ? -1 : 0;
no_dccp_socket: no_dccp_socket:
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
......
...@@ -793,7 +793,6 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) ...@@ -793,7 +793,6 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
got_it: got_it:
if (sk != NULL) { if (sk != NULL) {
struct dn_scp *scp = DN_SK(sk); struct dn_scp *scp = DN_SK(sk);
int ret;
/* Reset backoff */ /* Reset backoff */
scp->nsp_rxtshift = 0; scp->nsp_rxtshift = 0;
...@@ -807,21 +806,7 @@ got_it: ...@@ -807,21 +806,7 @@ got_it:
goto free_out; goto free_out;
} }
bh_lock_sock(sk); return sk_receive_skb(sk, skb);
ret = NET_RX_SUCCESS;
if (decnet_debug_level & 8)
printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
(int)cb->rt_flags, (int)cb->nsp_flags,
(int)cb->src_port, (int)cb->dst_port,
!!sock_owned_by_user(sk));
if (!sock_owned_by_user(sk))
ret = dn_nsp_backlog_rcv(sk, skb);
else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
sock_put(sk);
return ret;
} }
return dn_nsp_no_socket(skb, reason); return dn_nsp_no_socket(skb, reason);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment