Commit f7ad74fe authored by Benjamin LaHaise's avatar Benjamin LaHaise Committed by David S. Miller

net/ipv6/udp: UDP encapsulation: break backlog_rcv into __udpv6_queue_rcv_skb

This is the first step in reworking the IPv6 UDP code to be structured more
like the IPv4 UDP code.  This patch creates __udpv6_queue_rcv_skb() with
the equivalent sematics to __udp_queue_rcv_skb(), and wires it up to the
backlog_rcv method.
Signed-off-by: default avatarBenjamin LaHaise <bcrl@kvack.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a319726a
...@@ -496,6 +496,28 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -496,6 +496,28 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
sock_put(sk); sock_put(sk);
} }
static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
int rc;
if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
sock_rps_save_rxhash(sk, skb);
rc = sock_queue_rcv_skb(sk, skb);
if (rc < 0) {
int is_udplite = IS_UDPLITE(sk);
/* Note that an ENOMEM error is charged twice */
if (rc == -ENOMEM)
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_RCVBUFERRORS, is_udplite);
UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
kfree_skb(skb);
return -1;
}
return 0;
}
static __inline__ void udpv6_err(struct sk_buff *skb, static __inline__ void udpv6_err(struct sk_buff *skb,
struct inet6_skb_parm *opt, u8 type, struct inet6_skb_parm *opt, u8 type,
u8 code, int offset, __be32 info ) u8 code, int offset, __be32 info )
...@@ -503,15 +525,12 @@ static __inline__ void udpv6_err(struct sk_buff *skb, ...@@ -503,15 +525,12 @@ static __inline__ void udpv6_err(struct sk_buff *skb,
__udp6_lib_err(skb, opt, type, code, offset, info, &udp_table); __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table);
} }
int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ {
struct udp_sock *up = udp_sk(sk); struct udp_sock *up = udp_sk(sk);
int rc; int rc;
int is_udplite = IS_UDPLITE(sk); int is_udplite = IS_UDPLITE(sk);
if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
sock_rps_save_rxhash(sk, skb);
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto drop; goto drop;
...@@ -540,19 +559,12 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) ...@@ -540,19 +559,12 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
} }
skb_dst_drop(skb); skb_dst_drop(skb);
rc = sock_queue_rcv_skb(sk, skb);
if (rc < 0) {
/* Note that an ENOMEM error is charged twice */
if (rc == -ENOMEM)
UDP6_INC_STATS_BH(sock_net(sk),
UDP_MIB_RCVBUFERRORS, is_udplite);
goto drop_no_sk_drops_inc;
}
return 0; rc = __udpv6_queue_rcv_skb(sk, skb);
return rc;
drop: drop:
atomic_inc(&sk->sk_drops); atomic_inc(&sk->sk_drops);
drop_no_sk_drops_inc:
UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
...@@ -1471,7 +1483,7 @@ struct proto udpv6_prot = { ...@@ -1471,7 +1483,7 @@ struct proto udpv6_prot = {
.getsockopt = udpv6_getsockopt, .getsockopt = udpv6_getsockopt,
.sendmsg = udpv6_sendmsg, .sendmsg = udpv6_sendmsg,
.recvmsg = udpv6_recvmsg, .recvmsg = udpv6_recvmsg,
.backlog_rcv = udpv6_queue_rcv_skb, .backlog_rcv = __udpv6_queue_rcv_skb,
.hash = udp_lib_hash, .hash = udp_lib_hash,
.unhash = udp_lib_unhash, .unhash = udp_lib_unhash,
.rehash = udp_v6_rehash, .rehash = udp_v6_rehash,
......
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