Skip to content

Commit e6afc8a

Browse files
samanthakumardavem330
authored andcommitted
udp: remove headers from UDP packets before queueing
Remove UDP transport headers before queueing packets for reception. This change simplifies a follow-up patch to add MSG_PEEK support. Signed-off-by: Sam Kumar <[email protected]> Signed-off-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b9bb53f commit e6afc8a

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

include/net/sock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,7 @@ void sk_reset_timer(struct sock *sk, struct timer_list *timer,
18641864

18651865
void sk_stop_timer(struct sock *sk, struct timer_list *timer);
18661866

1867+
int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
18671868
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
18681869

18691870
int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb);

include/net/udp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ static inline __sum16 udp_v4_check(int len, __be32 saddr,
158158
void udp_set_csum(bool nocheck, struct sk_buff *skb,
159159
__be32 saddr, __be32 daddr, int len);
160160

161+
static inline void udp_csum_pull_header(struct sk_buff *skb)
162+
{
163+
if (skb->ip_summed == CHECKSUM_NONE)
164+
skb->csum = csum_partial(udp_hdr(skb), sizeof(struct udphdr),
165+
skb->csum);
166+
skb_pull_rcsum(skb, sizeof(struct udphdr));
167+
UDP_SKB_CB(skb)->cscov -= sizeof(struct udphdr);
168+
}
169+
161170
struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
162171
struct udphdr *uh);
163172
int udp_gro_complete(struct sk_buff *skb, int nhoff);

net/core/sock.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,8 @@ static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
402402
}
403403

404404

405-
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
405+
int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
406406
{
407-
int err;
408407
unsigned long flags;
409408
struct sk_buff_head *list = &sk->sk_receive_queue;
410409

@@ -414,10 +413,6 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
414413
return -ENOMEM;
415414
}
416415

417-
err = sk_filter(sk, skb);
418-
if (err)
419-
return err;
420-
421416
if (!sk_rmem_schedule(sk, skb, skb->truesize)) {
422417
atomic_inc(&sk->sk_drops);
423418
return -ENOBUFS;
@@ -440,6 +435,18 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
440435
sk->sk_data_ready(sk);
441436
return 0;
442437
}
438+
EXPORT_SYMBOL(__sock_queue_rcv_skb);
439+
440+
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
441+
{
442+
int err;
443+
444+
err = sk_filter(sk, skb);
445+
if (err)
446+
return err;
447+
448+
return __sock_queue_rcv_skb(sk, skb);
449+
}
443450
EXPORT_SYMBOL(sock_queue_rcv_skb);
444451

445452
int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)

net/ipv4/udp.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
13091309
if (!skb)
13101310
goto out;
13111311

1312-
ulen = skb->len - sizeof(struct udphdr);
1312+
ulen = skb->len;
13131313
copied = len;
13141314
if (copied > ulen)
13151315
copied = ulen;
@@ -1329,11 +1329,9 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
13291329
}
13301330

13311331
if (checksum_valid || skb_csum_unnecessary(skb))
1332-
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
1333-
msg, copied);
1332+
err = skb_copy_datagram_msg(skb, 0, msg, copied);
13341333
else {
1335-
err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr),
1336-
msg);
1334+
err = skb_copy_and_csum_datagram_msg(skb, 0, msg);
13371335

13381336
if (err == -EINVAL)
13391337
goto csum_copy_err;
@@ -1500,7 +1498,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
15001498
sk_incoming_cpu_update(sk);
15011499
}
15021500

1503-
rc = sock_queue_rcv_skb(sk, skb);
1501+
rc = __sock_queue_rcv_skb(sk, skb);
15041502
if (rc < 0) {
15051503
int is_udplite = IS_UDPLITE(sk);
15061504

@@ -1616,10 +1614,14 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
16161614
}
16171615
}
16181616

1619-
if (rcu_access_pointer(sk->sk_filter) &&
1620-
udp_lib_checksum_complete(skb))
1621-
goto csum_error;
1617+
if (rcu_access_pointer(sk->sk_filter)) {
1618+
if (udp_lib_checksum_complete(skb))
1619+
goto csum_error;
1620+
if (sk_filter(sk, skb))
1621+
goto drop;
1622+
}
16221623

1624+
udp_csum_pull_header(skb);
16231625
if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) {
16241626
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
16251627
is_udplite);

net/ipv6/udp.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
376376
if (!skb)
377377
goto out;
378378

379-
ulen = skb->len - sizeof(struct udphdr);
379+
ulen = skb->len;
380380
copied = len;
381381
if (copied > ulen)
382382
copied = ulen;
@@ -398,10 +398,9 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
398398
}
399399

400400
if (checksum_valid || skb_csum_unnecessary(skb))
401-
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
402-
msg, copied);
401+
err = skb_copy_datagram_msg(skb, 0, msg, copied);
403402
else {
404-
err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
403+
err = skb_copy_and_csum_datagram_msg(skb, 0, msg);
405404
if (err == -EINVAL)
406405
goto csum_copy_err;
407406
}
@@ -554,7 +553,7 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
554553
sk_incoming_cpu_update(sk);
555554
}
556555

557-
rc = sock_queue_rcv_skb(sk, skb);
556+
rc = __sock_queue_rcv_skb(sk, skb);
558557
if (rc < 0) {
559558
int is_udplite = IS_UDPLITE(sk);
560559

@@ -648,8 +647,11 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
648647
if (rcu_access_pointer(sk->sk_filter)) {
649648
if (udp_lib_checksum_complete(skb))
650649
goto csum_error;
650+
if (sk_filter(sk, skb))
651+
goto drop;
651652
}
652653

654+
udp_csum_pull_header(skb);
653655
if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) {
654656
UDP6_INC_STATS_BH(sock_net(sk),
655657
UDP_MIB_RCVBUFERRORS, is_udplite);

0 commit comments

Comments
 (0)