Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

udp: Don't pass udptable to IPv6 socket lookup functions.

Since UDP and UDP-Lite had dedicated socket hash tables for
each, we have had to pass the pointer down to many socket
lookup functions.

UDP-Lite gone, and we do not need to do that.

Let's fetch net->ipv4.udp_table only where needed in IPv6
stack: __udp6_lib_lookup() and __udp6_lib_mcast_deliver().

__udp6_lib_err() is renamed to udpv6_err() as its wrapper
is no longer needed.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260311052020.1213705-14-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
deffb854 5a88b281

+53 -65
+3 -4
include/net/ipv6_stubs.h
··· 83 83 int (*inet6_bind)(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len, 84 84 u32 flags); 85 85 struct sock *(*udp6_lib_lookup)(const struct net *net, 86 - const struct in6_addr *saddr, __be16 sport, 87 - const struct in6_addr *daddr, __be16 dport, 88 - int dif, int sdif, struct udp_table *tbl, 89 - struct sk_buff *skb); 86 + const struct in6_addr *saddr, __be16 sport, 87 + const struct in6_addr *daddr, __be16 dport, 88 + int dif, int sdif, struct sk_buff *skb); 90 89 int (*ipv6_setsockopt)(struct sock *sk, int level, int optname, 91 90 sockptr_t optval, unsigned int optlen); 92 91 int (*ipv6_getsockopt)(struct sock *sk, int level, int optname,
+1 -2
include/net/udp.h
··· 449 449 struct sock *__udp6_lib_lookup(const struct net *net, 450 450 const struct in6_addr *saddr, __be16 sport, 451 451 const struct in6_addr *daddr, __be16 dport, 452 - int dif, int sdif, struct udp_table *tbl, 453 - struct sk_buff *skb); 452 + int dif, int sdif, struct sk_buff *skb); 454 453 struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, 455 454 __be16 sport, __be16 dport); 456 455 int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
+1 -2
net/core/filter.c
··· 6904 6904 sk = ipv6_bpf_stub->udp6_lib_lookup(net, 6905 6905 src6, tuple->ipv6.sport, 6906 6906 dst6, tuple->ipv6.dport, 6907 - dif, sdif, 6908 - net->ipv4.udp_table, NULL); 6907 + dif, sdif, NULL); 6909 6908 #endif 6910 6909 } 6911 6910
+10 -10
net/ipv4/udp_diag.c
··· 44 44 #if IS_ENABLED(CONFIG_IPV6) 45 45 else if (req->sdiag_family == AF_INET6) 46 46 sk = __udp6_lib_lookup(net, 47 - (struct in6_addr *)req->id.idiag_src, 48 - req->id.idiag_sport, 49 - (struct in6_addr *)req->id.idiag_dst, 50 - req->id.idiag_dport, 51 - req->id.idiag_if, 0, tbl, NULL); 47 + (struct in6_addr *)req->id.idiag_src, 48 + req->id.idiag_sport, 49 + (struct in6_addr *)req->id.idiag_dst, 50 + req->id.idiag_dport, 51 + req->id.idiag_if, 0, NULL); 52 52 #endif 53 53 if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) 54 54 sk = NULL; ··· 185 185 186 186 else 187 187 sk = __udp6_lib_lookup(net, 188 - (struct in6_addr *)req->id.idiag_dst, 189 - req->id.idiag_dport, 190 - (struct in6_addr *)req->id.idiag_src, 191 - req->id.idiag_sport, 192 - req->id.idiag_if, 0, tbl, NULL); 188 + (struct in6_addr *)req->id.idiag_dst, 189 + req->id.idiag_dport, 190 + (struct in6_addr *)req->id.idiag_src, 191 + req->id.idiag_sport, 192 + req->id.idiag_if, 0, NULL); 193 193 } 194 194 #endif 195 195 else {
+37 -45
net/ipv6/udp.c
··· 344 344 struct sock *__udp6_lib_lookup(const struct net *net, 345 345 const struct in6_addr *saddr, __be16 sport, 346 346 const struct in6_addr *daddr, __be16 dport, 347 - int dif, int sdif, struct udp_table *udptable, 348 - struct sk_buff *skb) 347 + int dif, int sdif, struct sk_buff *skb) 349 348 { 349 + struct udp_table *udptable = net->ipv4.udp_table; 350 350 unsigned short hnum = ntohs(dport); 351 351 struct udp_hslot *hslot2; 352 352 struct sock *result, *sk; ··· 406 406 EXPORT_SYMBOL_GPL(__udp6_lib_lookup); 407 407 408 408 static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, 409 - __be16 sport, __be16 dport, 410 - struct udp_table *udptable) 409 + __be16 sport, __be16 dport) 411 410 { 412 411 const struct ipv6hdr *iph = ipv6_hdr(skb); 413 412 414 413 return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, 415 414 &iph->daddr, dport, inet6_iif(skb), 416 - inet6_sdif(skb), udptable, skb); 415 + inet6_sdif(skb), skb); 417 416 } 418 417 419 418 struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, ··· 420 421 { 421 422 const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; 422 423 const struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + offset); 423 - struct net *net = dev_net(skb->dev); 424 424 int iif, sdif; 425 425 426 426 inet6_get_iif_sdif(skb, &iif, &sdif); 427 427 428 - return __udp6_lib_lookup(net, &iph->saddr, sport, 429 - &iph->daddr, dport, iif, 430 - sdif, net->ipv4.udp_table, NULL); 428 + return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, 429 + &iph->daddr, dport, iif, sdif, NULL); 431 430 } 432 431 433 432 /* Must be called under rcu_read_lock(). ··· 437 440 { 438 441 struct sock *sk; 439 442 440 - sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport, 441 - dif, 0, net->ipv4.udp_table, NULL); 443 + sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, 0, NULL); 442 444 if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) 443 445 sk = NULL; 444 446 return sk; ··· 638 642 static struct sock *__udp6_lib_err_encap(struct net *net, 639 643 const struct ipv6hdr *hdr, int offset, 640 644 struct udphdr *uh, 641 - struct udp_table *udptable, 642 645 struct sock *sk, 643 646 struct sk_buff *skb, 644 647 struct inet6_skb_parm *opt, ··· 668 673 669 674 sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source, 670 675 &hdr->saddr, uh->dest, 671 - inet6_iif(skb), 0, udptable, skb); 676 + inet6_iif(skb), 0, skb); 672 677 if (sk) { 673 678 up = udp_sk(sk); 674 679 ··· 689 694 return sk; 690 695 } 691 696 692 - static int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 693 - u8 type, u8 code, int offset, __be32 info, 694 - struct udp_table *udptable) 697 + static int udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 698 + u8 type, u8 code, int offset, __be32 info) 695 699 { 696 - struct ipv6_pinfo *np; 697 700 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; 698 - const struct in6_addr *saddr = &hdr->saddr; 699 - const struct in6_addr *daddr = seg6_get_daddr(skb, opt) ? : &hdr->daddr; 700 - struct udphdr *uh = (struct udphdr *)(skb->data+offset); 701 + struct udphdr *uh = (struct udphdr *)(skb->data + offset); 702 + const struct in6_addr *saddr, *daddr; 703 + struct net *net = dev_net(skb->dev); 704 + struct ipv6_pinfo *np; 701 705 bool tunnel = false; 702 706 struct sock *sk; 703 707 int harderr; 704 708 int err; 705 - struct net *net = dev_net(skb->dev); 706 709 710 + daddr = seg6_get_daddr(skb, opt) ? : &hdr->daddr; 711 + saddr = &hdr->saddr; 707 712 sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, 708 - inet6_iif(skb), inet6_sdif(skb), udptable, NULL); 713 + inet6_iif(skb), inet6_sdif(skb), NULL); 709 714 710 715 if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) { 711 716 /* No socket for error: try tunnels before discarding */ 712 717 if (static_branch_unlikely(&udpv6_encap_needed_key)) { 713 - sk = __udp6_lib_err_encap(net, hdr, offset, uh, 714 - udptable, sk, skb, 718 + sk = __udp6_lib_err_encap(net, hdr, offset, uh, sk, skb, 715 719 opt, type, code, info); 716 720 if (!sk) 717 721 return 0; ··· 800 806 } 801 807 802 808 return 0; 803 - } 804 - 805 - static __inline__ int udpv6_err(struct sk_buff *skb, 806 - struct inet6_skb_parm *opt, u8 type, 807 - u8 code, int offset, __be32 info) 808 - { 809 - return __udp6_lib_err(skb, opt, type, code, offset, info, 810 - dev_net(skb->dev)->ipv4.udp_table); 811 809 } 812 810 813 811 static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) ··· 933 947 * so we don't need to lock the hashes. 934 948 */ 935 949 static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, 936 - const struct in6_addr *saddr, const struct in6_addr *daddr, 937 - struct udp_table *udptable, int proto) 950 + const struct in6_addr *saddr, 951 + const struct in6_addr *daddr, 952 + int proto) 938 953 { 939 - struct sock *sk, *first = NULL; 954 + struct udp_table *udptable = net->ipv4.udp_table; 940 955 const struct udphdr *uh = udp_hdr(skb); 956 + unsigned int hash2, hash2_any, offset; 941 957 unsigned short hnum = ntohs(uh->dest); 942 - struct udp_hslot *hslot = udp_hashslot(udptable, net, hnum); 943 - unsigned int offset = offsetof(typeof(*sk), sk_node); 944 - unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10); 945 - int dif = inet6_iif(skb); 958 + struct sock *sk, *first = NULL; 946 959 int sdif = inet6_sdif(skb); 960 + int dif = inet6_iif(skb); 947 961 struct hlist_node *node; 962 + struct udp_hslot *hslot; 948 963 struct sk_buff *nskb; 964 + bool use_hash2; 965 + 966 + hash2_any = 0; 967 + hash2 = 0; 968 + hslot = udp_hashslot(udptable, net, hnum); 969 + use_hash2 = hslot->count > 10; 970 + offset = offsetof(typeof(*sk), sk_node); 949 971 950 972 if (use_hash2) { 951 973 hash2_any = ipv6_portaddr_hash(net, &in6addr_any, hnum) & ··· 1063 1069 return 0; 1064 1070 } 1065 1071 1066 - static int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, 1067 - int proto) 1072 + static int __udp6_lib_rcv(struct sk_buff *skb, int proto) 1068 1073 { 1069 1074 enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; 1070 1075 const struct in6_addr *saddr, *daddr; ··· 1132 1139 * Multicast receive code 1133 1140 */ 1134 1141 if (ipv6_addr_is_multicast(daddr)) 1135 - return __udp6_lib_mcast_deliver(net, skb, 1136 - saddr, daddr, udptable, proto); 1142 + return __udp6_lib_mcast_deliver(net, skb, saddr, daddr, proto); 1137 1143 1138 1144 /* Unicast */ 1139 - sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); 1145 + sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest); 1140 1146 if (sk) { 1141 1147 if (!uh->check && !udp_get_no_check6_rx(sk)) 1142 1148 goto report_csum_error; ··· 1253 1261 1254 1262 INDIRECT_CALLABLE_SCOPE int udpv6_rcv(struct sk_buff *skb) 1255 1263 { 1256 - return __udp6_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP); 1264 + return __udp6_lib_rcv(skb, IPPROTO_UDP); 1257 1265 } 1258 1266 1259 1267 /*
+1 -2
net/ipv6/udp_offload.c
··· 128 128 inet6_get_iif_sdif(skb, &iif, &sdif); 129 129 130 130 return __udp6_lib_lookup(net, &iph->saddr, sport, 131 - &iph->daddr, dport, iif, 132 - sdif, net->ipv4.udp_table, NULL); 131 + &iph->daddr, dport, iif, sdif, NULL); 133 132 } 134 133 135 134 struct sk_buff *udp6_gro_receive(struct list_head *head, struct sk_buff *skb)