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

inet: introduce dst_rtable() helper

I added dst_rt6_info() in commit
e8dfd42c17fa ("ipv6: introduce dst_rt6_info() helper")

This patch does a similar change for IPv4.

Instead of (struct rtable *)dst casts, we can use :

#define dst_rtable(_ptr) \
container_of_const(_ptr, struct rtable, dst)

Patch is smaller than IPv6 one, because IPv4 has skb_rtable() helper.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://lore.kernel.org/r/20240429133009.1227754-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
05d6d492 b4517670

+64 -70
+3 -9
drivers/infiniband/core/addr.c
··· 348 348 349 349 static bool has_gateway(const struct dst_entry *dst, sa_family_t family) 350 350 { 351 - const struct rtable *rt; 352 - const struct rt6_info *rt6; 351 + if (family == AF_INET) 352 + return dst_rtable(dst)->rt_uses_gateway; 353 353 354 - if (family == AF_INET) { 355 - rt = container_of(dst, struct rtable, dst); 356 - return rt->rt_uses_gateway; 357 - } 358 - 359 - rt6 = dst_rt6_info(dst); 360 - return rt6->rt6i_flags & RTF_GATEWAY; 354 + return dst_rt6_info(dst)->rt6i_flags & RTF_GATEWAY; 361 355 } 362 356 363 357 static int fetch_ha(const struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
+1 -1
drivers/net/vrf.c
··· 860 860 static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb) 861 861 { 862 862 struct dst_entry *dst = skb_dst(skb); 863 - struct rtable *rt = (struct rtable *)dst; 863 + struct rtable *rt = dst_rtable(dst); 864 864 struct net_device *dev = dst->dev; 865 865 unsigned int hh_len = LL_RESERVED_SPACE(dev); 866 866 struct neighbour *neigh;
+2 -3
drivers/s390/net/qeth_core.h
··· 970 970 static inline __be32 qeth_next_hop_v4_rcu(struct sk_buff *skb, 971 971 struct dst_entry *dst) 972 972 { 973 - struct rtable *rt = (struct rtable *) dst; 974 - 975 - return (rt) ? rt_nexthop(rt, ip_hdr(skb)->daddr) : ip_hdr(skb)->daddr; 973 + return (dst) ? rt_nexthop(dst_rtable(dst), ip_hdr(skb)->daddr) : 974 + ip_hdr(skb)->daddr; 976 975 } 977 976 978 977 static inline struct in6_addr *qeth_next_hop_v6_rcu(struct sk_buff *skb,
-9
include/linux/skbuff.h
··· 1180 1180 return (skb->_skb_refdst & SKB_DST_NOREF) && skb_dst(skb); 1181 1181 } 1182 1182 1183 - /** 1184 - * skb_rtable - Returns the skb &rtable 1185 - * @skb: buffer 1186 - */ 1187 - static inline struct rtable *skb_rtable(const struct sk_buff *skb) 1188 - { 1189 - return (struct rtable *)skb_dst(skb); 1190 - } 1191 - 1192 1183 /* For mangling skb->pkt_type from user space side from applications 1193 1184 * such as nft, tc, etc, we only allow a conservative subset of 1194 1185 * possible pkt_types to be set.
+2 -2
include/net/ip.h
··· 423 423 424 424 static inline int ip_mtu_locked(const struct dst_entry *dst) 425 425 { 426 - const struct rtable *rt = (const struct rtable *)dst; 426 + const struct rtable *rt = dst_rtable(dst); 427 427 428 428 return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU); 429 429 } ··· 461 461 static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, 462 462 bool forwarding) 463 463 { 464 - const struct rtable *rt = container_of(dst, struct rtable, dst); 464 + const struct rtable *rt = dst_rtable(dst); 465 465 struct net *net = dev_net(dst->dev); 466 466 unsigned int mtu; 467 467
+11
include/net/route.h
··· 75 75 rt_pmtu:31; 76 76 }; 77 77 78 + #define dst_rtable(_ptr) container_of_const(_ptr, struct rtable, dst) 79 + 80 + /** 81 + * skb_rtable - Returns the skb &rtable 82 + * @skb: buffer 83 + */ 84 + static inline struct rtable *skb_rtable(const struct sk_buff *skb) 85 + { 86 + return dst_rtable(skb_dst(skb)); 87 + } 88 + 78 89 static inline bool rt_is_input_route(const struct rtable *rt) 79 90 { 80 91 return rt->rt_is_input != 0;
+1 -1
net/atm/clip.c
··· 345 345 dev->stats.tx_dropped++; 346 346 return NETDEV_TX_OK; 347 347 } 348 - rt = (struct rtable *) dst; 348 + rt = dst_rtable(dst); 349 349 if (rt->rt_gw_family == AF_INET) 350 350 daddr = &rt->rt_gw4; 351 351 else
+1 -1
net/core/dst_cache.c
··· 83 83 return NULL; 84 84 85 85 *saddr = idst->in_saddr.s_addr; 86 - return container_of(dst, struct rtable, dst); 86 + return dst_rtable(dst); 87 87 } 88 88 EXPORT_SYMBOL_GPL(dst_cache_get_ip4); 89 89
+1 -2
net/core/filter.c
··· 2317 2317 2318 2318 rcu_read_lock(); 2319 2319 if (!nh) { 2320 - struct dst_entry *dst = skb_dst(skb); 2321 - struct rtable *rt = container_of(dst, struct rtable, dst); 2320 + struct rtable *rt = skb_rtable(skb); 2322 2321 2323 2322 neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); 2324 2323 } else if (nh->nh_family == AF_INET6) {
+1 -1
net/ipv4/af_inet.c
··· 1307 1307 1308 1308 int inet_sk_rebuild_header(struct sock *sk) 1309 1309 { 1310 + struct rtable *rt = dst_rtable(__sk_dst_check(sk, 0)); 1310 1311 struct inet_sock *inet = inet_sk(sk); 1311 - struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); 1312 1312 __be32 daddr; 1313 1313 struct ip_options_rcu *inet_opt; 1314 1314 struct flowi4 *fl4;
+14 -12
net/ipv4/icmp.c
··· 483 483 struct icmp_bxm *param) 484 484 { 485 485 struct net_device *route_lookup_dev; 486 + struct dst_entry *dst, *dst2; 486 487 struct rtable *rt, *rt2; 487 488 struct flowi4 fl4_dec; 488 489 int err; ··· 509 508 /* No need to clone since we're just using its address. */ 510 509 rt2 = rt; 511 510 512 - rt = (struct rtable *) xfrm_lookup(net, &rt->dst, 513 - flowi4_to_flowi(fl4), NULL, 0); 514 - if (!IS_ERR(rt)) { 511 + dst = xfrm_lookup(net, &rt->dst, 512 + flowi4_to_flowi(fl4), NULL, 0); 513 + rt = dst_rtable(dst); 514 + if (!IS_ERR(dst)) { 515 515 if (rt != rt2) 516 516 return rt; 517 - } else if (PTR_ERR(rt) == -EPERM) { 517 + } else if (PTR_ERR(dst) == -EPERM) { 518 518 rt = NULL; 519 - } else 519 + } else { 520 520 return rt; 521 - 521 + } 522 522 err = xfrm_decode_session_reverse(net, skb_in, flowi4_to_flowi(&fl4_dec), AF_INET); 523 523 if (err) 524 524 goto relookup_failed; ··· 553 551 if (err) 554 552 goto relookup_failed; 555 553 556 - rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, 557 - flowi4_to_flowi(&fl4_dec), NULL, 558 - XFRM_LOOKUP_ICMP); 559 - if (!IS_ERR(rt2)) { 554 + dst2 = xfrm_lookup(net, &rt2->dst, flowi4_to_flowi(&fl4_dec), NULL, 555 + XFRM_LOOKUP_ICMP); 556 + rt2 = dst_rtable(dst2); 557 + if (!IS_ERR(dst2)) { 560 558 dst_release(&rt->dst); 561 559 memcpy(fl4, &fl4_dec, sizeof(*fl4)); 562 560 rt = rt2; 563 - } else if (PTR_ERR(rt2) == -EPERM) { 561 + } else if (PTR_ERR(dst2) == -EPERM) { 564 562 if (rt) 565 563 dst_release(&rt->dst); 566 564 return rt2; 567 565 } else { 568 - err = PTR_ERR(rt2); 566 + err = PTR_ERR(dst2); 569 567 goto relookup_failed; 570 568 } 571 569 return rt;
+1 -1
net/ipv4/ip_input.c
··· 616 616 dst = skb_dst(skb); 617 617 if (curr_dst != dst) { 618 618 hint = ip_extract_route_hint(net, skb, 619 - ((struct rtable *)dst)->rt_type); 619 + dst_rtable(dst)->rt_type); 620 620 621 621 /* dispatch old sublist */ 622 622 if (!list_empty(&sublist))
+4 -4
net/ipv4/ip_output.c
··· 198 198 static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb) 199 199 { 200 200 struct dst_entry *dst = skb_dst(skb); 201 - struct rtable *rt = (struct rtable *)dst; 201 + struct rtable *rt = dst_rtable(dst); 202 202 struct net_device *dev = dst->dev; 203 203 unsigned int hh_len = LL_RESERVED_SPACE(dev); 204 204 struct neighbour *neigh; ··· 475 475 goto packet_routed; 476 476 477 477 /* Make sure we can route this packet. */ 478 - rt = (struct rtable *)__sk_dst_check(sk, 0); 478 + rt = dst_rtable(__sk_dst_check(sk, 0)); 479 479 if (!rt) { 480 480 __be32 daddr; 481 481 ··· 971 971 bool zc = false; 972 972 unsigned int maxfraglen, fragheaderlen, maxnonfragsize; 973 973 int csummode = CHECKSUM_NONE; 974 - struct rtable *rt = (struct rtable *)cork->dst; 974 + struct rtable *rt = dst_rtable(cork->dst); 975 975 bool paged, hold_tskey, extra_uref = false; 976 976 unsigned int wmem_alloc_delta = 0; 977 977 u32 tskey = 0; ··· 1390 1390 struct inet_sock *inet = inet_sk(sk); 1391 1391 struct net *net = sock_net(sk); 1392 1392 struct ip_options *opt = NULL; 1393 - struct rtable *rt = (struct rtable *)cork->dst; 1393 + struct rtable *rt = dst_rtable(cork->dst); 1394 1394 struct iphdr *iph; 1395 1395 u8 pmtudisc, ttl; 1396 1396 __be16 df = 0;
+11 -13
net/ipv4/route.c
··· 819 819 u32 mark = skb->mark; 820 820 __u8 tos = iph->tos; 821 821 822 - rt = (struct rtable *) dst; 822 + rt = dst_rtable(dst); 823 823 824 824 __build_flow_key(net, &fl4, sk, iph, oif, tos, prot, mark, 0); 825 825 __ip_do_redirect(rt, skb, &fl4, true); ··· 827 827 828 828 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) 829 829 { 830 - struct rtable *rt = (struct rtable *)dst; 830 + struct rtable *rt = dst_rtable(dst); 831 831 struct dst_entry *ret = dst; 832 832 833 833 if (rt) { ··· 1044 1044 struct sk_buff *skb, u32 mtu, 1045 1045 bool confirm_neigh) 1046 1046 { 1047 - struct rtable *rt = (struct rtable *) dst; 1047 + struct rtable *rt = dst_rtable(dst); 1048 1048 struct flowi4 fl4; 1049 1049 1050 1050 ip_rt_build_flow_key(&fl4, sk, skb); ··· 1115 1115 1116 1116 __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0); 1117 1117 1118 - rt = (struct rtable *)odst; 1118 + rt = dst_rtable(odst); 1119 1119 if (odst->obsolete && !odst->ops->check(odst, 0)) { 1120 1120 rt = ip_route_output_flow(sock_net(sk), &fl4, sk); 1121 1121 if (IS_ERR(rt)) ··· 1124 1124 new = true; 1125 1125 } 1126 1126 1127 - __ip_rt_update_pmtu((struct rtable *)xfrm_dst_path(&rt->dst), &fl4, mtu); 1127 + __ip_rt_update_pmtu(dst_rtable(xfrm_dst_path(&rt->dst)), &fl4, mtu); 1128 1128 1129 1129 if (!dst_check(&rt->dst, 0)) { 1130 1130 if (new) ··· 1181 1181 INDIRECT_CALLABLE_SCOPE struct dst_entry *ipv4_dst_check(struct dst_entry *dst, 1182 1182 u32 cookie) 1183 1183 { 1184 - struct rtable *rt = (struct rtable *) dst; 1184 + struct rtable *rt = dst_rtable(dst); 1185 1185 1186 1186 /* All IPV4 dsts are created with ->obsolete set to the value 1187 1187 * DST_OBSOLETE_FORCE_CHK which forces validation calls down ··· 1516 1516 1517 1517 static void ipv4_dst_destroy(struct dst_entry *dst) 1518 1518 { 1519 - struct rtable *rt = (struct rtable *)dst; 1520 - 1521 1519 ip_dst_metrics_put(dst); 1522 - rt_del_uncached_list(rt); 1520 + rt_del_uncached_list(dst_rtable(dst)); 1523 1521 } 1524 1522 1525 1523 void rt_flush_dev(struct net_device *dev) ··· 2818 2820 2819 2821 struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) 2820 2822 { 2821 - struct rtable *ort = (struct rtable *) dst_orig; 2823 + struct rtable *ort = dst_rtable(dst_orig); 2822 2824 struct rtable *rt; 2823 2825 2824 2826 rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, DST_OBSOLETE_DEAD, 0); ··· 2863 2865 2864 2866 if (flp4->flowi4_proto) { 2865 2867 flp4->flowi4_oif = rt->dst.dev->ifindex; 2866 - rt = (struct rtable *)xfrm_lookup_route(net, &rt->dst, 2867 - flowi4_to_flowi(flp4), 2868 - sk, 0); 2868 + rt = dst_rtable(xfrm_lookup_route(net, &rt->dst, 2869 + flowi4_to_flowi(flp4), 2870 + sk, 0)); 2869 2871 } 2870 2872 2871 2873 return rt;
+1 -1
net/ipv4/udp.c
··· 1217 1217 } 1218 1218 1219 1219 if (connected) 1220 - rt = (struct rtable *)sk_dst_check(sk, 0); 1220 + rt = dst_rtable(sk_dst_check(sk, 0)); 1221 1221 1222 1222 if (!rt) { 1223 1223 struct net *net = sock_net(sk);
+1 -1
net/ipv4/xfrm4_policy.c
··· 69 69 static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, 70 70 const struct flowi *fl) 71 71 { 72 - struct rtable *rt = (struct rtable *)xdst->route; 72 + struct rtable *rt = dst_rtable(xdst->route); 73 73 const struct flowi4 *fl4 = &fl->u.ip4; 74 74 75 75 xdst->u.rt.rt_iif = fl4->flowi4_iif;
+1 -1
net/l2tp/l2tp_ip.c
··· 459 459 460 460 fl4 = &inet->cork.fl.u.ip4; 461 461 if (connected) 462 - rt = (struct rtable *)__sk_dst_check(sk, 0); 462 + rt = dst_rtable(__sk_dst_check(sk, 0)); 463 463 464 464 rcu_read_lock(); 465 465 if (!rt) {
+1 -1
net/mpls/mpls_iptunnel.c
··· 81 81 ttl = net->mpls.default_ttl; 82 82 else 83 83 ttl = ip_hdr(skb)->ttl; 84 - rt = (struct rtable *)dst; 84 + rt = dst_rtable(dst); 85 85 } else if (dst->ops->family == AF_INET6) { 86 86 if (tun_encap_info->ttl_propagate == MPLS_TTL_PROP_DISABLED) 87 87 ttl = tun_encap_info->default_ttl;
+1 -1
net/netfilter/ipvs/ip_vs_xmit.c
··· 318 318 if (dest) { 319 319 dest_dst = __ip_vs_dst_check(dest); 320 320 if (likely(dest_dst)) 321 - rt = (struct rtable *) dest_dst->dst_cache; 321 + rt = dst_rtable(dest_dst->dst_cache); 322 322 else { 323 323 dest_dst = ip_vs_dest_dst_alloc(); 324 324 spin_lock_bh(&dest->dst_lock);
+2 -2
net/netfilter/nf_flow_table_ip.c
··· 434 434 return NF_ACCEPT; 435 435 436 436 if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { 437 - rt = (struct rtable *)tuplehash->tuple.dst_cache; 437 + rt = dst_rtable(tuplehash->tuple.dst_cache); 438 438 memset(skb->cb, 0, sizeof(struct inet_skb_parm)); 439 439 IPCB(skb)->iif = skb->dev->ifindex; 440 440 IPCB(skb)->flags = IPSKB_FORWARDED; ··· 446 446 447 447 switch (tuplehash->tuple.xmit_type) { 448 448 case FLOW_OFFLOAD_XMIT_NEIGH: 449 - rt = (struct rtable *)tuplehash->tuple.dst_cache; 449 + rt = dst_rtable(tuplehash->tuple.dst_cache); 450 450 outdev = rt->dst.dev; 451 451 skb->dev = outdev; 452 452 nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
+1 -1
net/netfilter/nft_rt.c
··· 73 73 if (nft_pf(pkt) != NFPROTO_IPV4) 74 74 goto err; 75 75 76 - *dest = (__force u32)rt_nexthop((const struct rtable *)dst, 76 + *dest = (__force u32)rt_nexthop(dst_rtable(dst), 77 77 ip_hdr(skb)->daddr); 78 78 break; 79 79 case NFT_RT_NEXTHOP6:
+2 -2
net/sctp/protocol.c
··· 552 552 struct flowi *fl) 553 553 { 554 554 union sctp_addr *saddr = &t->saddr; 555 - struct rtable *rt = (struct rtable *)t->dst; 555 + struct rtable *rt = dst_rtable(t->dst); 556 556 557 557 if (rt) { 558 558 saddr->v4.sin_family = AF_INET; ··· 1085 1085 skb_reset_inner_mac_header(skb); 1086 1086 skb_reset_inner_transport_header(skb); 1087 1087 skb_set_inner_ipproto(skb, IPPROTO_SCTP); 1088 - udp_tunnel_xmit_skb((struct rtable *)dst, sk, skb, fl4->saddr, 1088 + udp_tunnel_xmit_skb(dst_rtable(dst), sk, skb, fl4->saddr, 1089 1089 fl4->daddr, dscp, ip4_dst_hoplimit(dst), df, 1090 1090 sctp_sk(sk)->udp_port, t->encap_port, false, false); 1091 1091 return 0;
+1 -1
net/tipc/udp_media.c
··· 174 174 local_bh_disable(); 175 175 ndst = dst_cache_get(cache); 176 176 if (dst->proto == htons(ETH_P_IP)) { 177 - struct rtable *rt = (struct rtable *)ndst; 177 + struct rtable *rt = dst_rtable(ndst); 178 178 179 179 if (!rt) { 180 180 struct flowi4 fl = {