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.

Merge branch 'ipv4-consolidate-route-lookups-from-ipv4-sockets'

Guillaume Nault says:

====================
ipv4: Consolidate route lookups from IPv4 sockets.

Create inet_sk_init_flowi4() so that the different IPv4 code paths that
need to do a route lookup based on an IPv4 socket don't need to
reimplement that logic.
====================

Link: https://patch.msgid.link/cover.1734357769.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+44 -55
+28
include/net/route.h
··· 28 28 #include <net/arp.h> 29 29 #include <net/ndisc.h> 30 30 #include <net/inet_dscp.h> 31 + #include <net/sock.h> 31 32 #include <linux/in_route.h> 32 33 #include <linux/rtnetlink.h> 33 34 #include <linux/rcupdate.h> ··· 130 129 int ip_rt_init(void); 131 130 void rt_cache_flush(struct net *net); 132 131 void rt_flush_dev(struct net_device *dev); 132 + 133 + static inline void inet_sk_init_flowi4(const struct inet_sock *inet, 134 + struct flowi4 *fl4) 135 + { 136 + const struct ip_options_rcu *ip4_opt; 137 + const struct sock *sk; 138 + __be32 daddr; 139 + 140 + rcu_read_lock(); 141 + ip4_opt = rcu_dereference(inet->inet_opt); 142 + 143 + /* Source routing option overrides the socket destination address */ 144 + if (ip4_opt && ip4_opt->opt.srr) 145 + daddr = ip4_opt->opt.faddr; 146 + else 147 + daddr = inet->inet_daddr; 148 + rcu_read_unlock(); 149 + 150 + sk = &inet->sk; 151 + flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark), 152 + ip_sock_rt_tos(sk), ip_sock_rt_scope(sk), 153 + sk->sk_protocol, inet_sk_flowi_flags(sk), daddr, 154 + inet->inet_saddr, inet->inet_dport, 155 + inet->inet_sport, sk->sk_uid); 156 + security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); 157 + } 158 + 133 159 struct rtable *ip_route_output_key_hash(struct net *net, struct flowi4 *flp, 134 160 const struct sk_buff *skb); 135 161 struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *flp,
+2 -12
net/ipv4/af_inet.c
··· 1309 1309 { 1310 1310 struct rtable *rt = dst_rtable(__sk_dst_check(sk, 0)); 1311 1311 struct inet_sock *inet = inet_sk(sk); 1312 - __be32 daddr; 1313 - struct ip_options_rcu *inet_opt; 1314 1312 struct flowi4 *fl4; 1315 1313 int err; 1316 1314 ··· 1317 1319 return 0; 1318 1320 1319 1321 /* Reroute. */ 1320 - rcu_read_lock(); 1321 - inet_opt = rcu_dereference(inet->inet_opt); 1322 - daddr = inet->inet_daddr; 1323 - if (inet_opt && inet_opt->opt.srr) 1324 - daddr = inet_opt->opt.faddr; 1325 - rcu_read_unlock(); 1326 1322 fl4 = &inet->cork.fl.u.ip4; 1327 - rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr, inet->inet_saddr, 1328 - inet->inet_dport, inet->inet_sport, 1329 - sk->sk_protocol, ip_sock_rt_tos(sk), 1330 - sk->sk_bound_dev_if); 1323 + inet_sk_init_flowi4(inet, fl4); 1324 + rt = ip_route_output_flow(sock_net(sk), fl4, sk); 1331 1325 if (!IS_ERR(rt)) { 1332 1326 err = 0; 1333 1327 sk_setup_caps(sk, &rt->dst);
+2 -9
net/ipv4/datagram.c
··· 102 102 void ip4_datagram_release_cb(struct sock *sk) 103 103 { 104 104 const struct inet_sock *inet = inet_sk(sk); 105 - const struct ip_options_rcu *inet_opt; 106 - __be32 daddr = inet->inet_daddr; 107 105 struct dst_entry *dst; 108 106 struct flowi4 fl4; 109 107 struct rtable *rt; ··· 113 115 rcu_read_unlock(); 114 116 return; 115 117 } 116 - inet_opt = rcu_dereference(inet->inet_opt); 117 - if (inet_opt && inet_opt->opt.srr) 118 - daddr = inet_opt->opt.faddr; 119 - rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr, 120 - inet->inet_saddr, inet->inet_dport, 121 - inet->inet_sport, sk->sk_protocol, 122 - ip_sock_rt_tos(sk), sk->sk_bound_dev_if); 123 118 119 + inet_sk_init_flowi4(inet, &fl4); 120 + rt = ip_route_output_flow(sock_net(sk), &fl4, sk); 124 121 dst = !IS_ERR(rt) ? &rt->dst : NULL; 125 122 sk_dst_set(sk, dst); 126 123
+2 -9
net/ipv4/inet_connection_sock.c
··· 1561 1561 static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl) 1562 1562 { 1563 1563 const struct inet_sock *inet = inet_sk(sk); 1564 - const struct ip_options_rcu *inet_opt; 1565 - __be32 daddr = inet->inet_daddr; 1566 1564 struct flowi4 *fl4; 1567 1565 struct rtable *rt; 1568 1566 1569 1567 rcu_read_lock(); 1570 - inet_opt = rcu_dereference(inet->inet_opt); 1571 - if (inet_opt && inet_opt->opt.srr) 1572 - daddr = inet_opt->opt.faddr; 1573 1568 fl4 = &fl->u.ip4; 1574 - rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr, 1575 - inet->inet_saddr, inet->inet_dport, 1576 - inet->inet_sport, sk->sk_protocol, 1577 - ip_sock_rt_tos(sk), sk->sk_bound_dev_if); 1569 + inet_sk_init_flowi4(inet, fl4); 1570 + rt = ip_route_output_flow(sock_net(sk), fl4, sk); 1578 1571 if (IS_ERR(rt)) 1579 1572 rt = NULL; 1580 1573 if (rt)
+4 -12
net/ipv4/ip_output.c
··· 478 478 /* Make sure we can route this packet. */ 479 479 rt = dst_rtable(__sk_dst_check(sk, 0)); 480 480 if (!rt) { 481 - __be32 daddr; 481 + inet_sk_init_flowi4(inet, fl4); 482 482 483 - /* Use correct destination address if we have options. */ 484 - daddr = inet->inet_daddr; 485 - if (inet_opt && inet_opt->opt.srr) 486 - daddr = inet_opt->opt.faddr; 483 + /* sctp_v4_xmit() uses its own DSCP value */ 484 + fl4->flowi4_tos = tos & INET_DSCP_MASK; 487 485 488 486 /* If this fails, retransmit mechanism of transport layer will 489 487 * keep trying until route appears or the connection times 490 488 * itself out. 491 489 */ 492 - rt = ip_route_output_ports(net, fl4, sk, 493 - daddr, inet->inet_saddr, 494 - inet->inet_dport, 495 - inet->inet_sport, 496 - sk->sk_protocol, 497 - tos & INET_DSCP_MASK, 498 - sk->sk_bound_dev_if); 490 + rt = ip_route_output_flow(net, fl4, sk); 499 491 if (IS_ERR(rt)) 500 492 goto no_route; 501 493 sk_setup_caps(sk, &rt->dst);
+6 -13
net/l2tp/l2tp_ip.c
··· 425 425 int rc; 426 426 struct inet_sock *inet = inet_sk(sk); 427 427 struct rtable *rt = NULL; 428 - struct flowi4 *fl4; 429 428 int connected = 0; 430 429 __be32 daddr; 431 430 ··· 454 455 if (sk->sk_state != TCP_ESTABLISHED) 455 456 goto out; 456 457 457 - daddr = inet->inet_daddr; 458 458 connected = 1; 459 459 } 460 460 ··· 480 482 goto error; 481 483 } 482 484 483 - fl4 = &inet->cork.fl.u.ip4; 484 485 if (connected) 485 486 rt = dst_rtable(__sk_dst_check(sk, 0)); 486 487 487 488 rcu_read_lock(); 488 489 if (!rt) { 489 - const struct ip_options_rcu *inet_opt; 490 + struct flowi4 *fl4 = &inet->cork.fl.u.ip4; 490 491 491 - inet_opt = rcu_dereference(inet->inet_opt); 492 + inet_sk_init_flowi4(inet, fl4); 492 493 493 - /* Use correct destination address if we have options. */ 494 - if (inet_opt && inet_opt->opt.srr) 495 - daddr = inet_opt->opt.faddr; 494 + /* Overwrite ->daddr if msg->msg_name was provided */ 495 + if (!connected) 496 + fl4->daddr = daddr; 496 497 497 498 /* If this fails, retransmit mechanism of transport layer will 498 499 * keep trying until route appears or the connection times 499 500 * itself out. 500 501 */ 501 - rt = ip_route_output_ports(sock_net(sk), fl4, sk, 502 - daddr, inet->inet_saddr, 503 - inet->inet_dport, inet->inet_sport, 504 - sk->sk_protocol, ip_sock_rt_tos(sk), 505 - sk->sk_bound_dev_if); 502 + rt = ip_route_output_flow(sock_net(sk), fl4, sk); 506 503 if (IS_ERR(rt)) 507 504 goto no_route; 508 505 if (connected) {