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.

ipv6: prepare headers for ipv6_stub removal

In preparation for dropping ipv6_stub and converting its users to direct
function calls, introduce static inline dummy functions and fallback
macros in the IPv6 networking headers. In addition, introduce checks on
fib6_nh_init(), ip6_dst_lookup_flow() and ip6_fragment() to avoid a
crash due to ipv6.disable=1 set during booting. The other functions are
safe as they cannot be called with ipv6.disable=1 set.

These fallbacks ensure that when CONFIG_IPV6 is completely disabled,
there are no compiling or linking errors due to code paths not guarded
by preprocessor macro IS_ENABLED(CONFIG_IPV6).

In addition, export ndisc_send_na(), ip6_route_input() and
ip6_fragment().

Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Tested-by: Ricardo B. Marlière <rbm@suse.com>
Link: https://patch.msgid.link/20260325120928.15848-6-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Fernando Fernandez Mancera and committed by
Jakub Kicinski
4b70b202 d2042d35

+88 -1
+32
include/net/ip6_fib.h
··· 486 486 rcu_read_unlock(); 487 487 } 488 488 489 + #if IS_ENABLED(CONFIG_IPV6) 489 490 int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, 490 491 struct fib6_config *cfg, gfp_t gfp_flags, 491 492 struct netlink_ext_ack *extack); 492 493 void fib6_nh_release(struct fib6_nh *fib6_nh); 493 494 void fib6_nh_release_dsts(struct fib6_nh *fib6_nh); 495 + #else 496 + static inline int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, 497 + struct fib6_config *cfg, gfp_t gfp_flags, 498 + struct netlink_ext_ack *extack) 499 + { 500 + NL_SET_ERR_MSG(extack, "IPv6 support not enabled in kernel"); 501 + return -EAFNOSUPPORT; 502 + } 503 + 504 + static inline void fib6_nh_release(struct fib6_nh *fib6_nh) 505 + { 506 + } 507 + 508 + static inline void fib6_nh_release_dsts(struct fib6_nh *fib6_nh) 509 + { 510 + } 511 + #endif 512 + 494 513 495 514 int call_fib6_entry_notifiers(struct net *net, 496 515 enum fib_event_type event_type, ··· 521 502 unsigned int nsiblings, 522 503 struct netlink_ext_ack *extack); 523 504 int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt); 505 + #if IS_ENABLED(CONFIG_IPV6) 524 506 void fib6_rt_update(struct net *net, struct fib6_info *rt, 525 507 struct nl_info *info); 508 + #else 509 + static inline void fib6_rt_update(struct net *net, struct fib6_info *rt, 510 + struct nl_info *info) 511 + { 512 + } 513 + #endif 526 514 void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, 527 515 unsigned int flags); 528 516 ··· 614 588 struct netlink_ext_ack *extack); 615 589 616 590 void fib6_update_sernum(struct net *net, struct fib6_info *rt); 591 + #if IS_ENABLED(CONFIG_IPV6) 617 592 void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt); 593 + #else 594 + static inline void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt) 595 + { 596 + } 597 + #endif 618 598 void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i); 619 599 620 600 void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val);
+26
include/net/ip6_route.h
··· 77 77 f6i->fib6_nh->fib_nh_gw_family; 78 78 } 79 79 80 + #if IS_ENABLED(CONFIG_IPV6) 80 81 void ip6_route_input(struct sk_buff *skb); 82 + #else 83 + static inline void ip6_route_input(struct sk_buff *skb) 84 + { 85 + } 86 + #endif 87 + 81 88 struct dst_entry *ip6_route_input_lookup(struct net *net, 82 89 struct net_device *dev, 83 90 struct flowi6 *fl6, ··· 126 119 int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, 127 120 struct netlink_ext_ack *extack); 128 121 int ip6_ins_rt(struct net *net, struct fib6_info *f6i); 122 + #if IS_ENABLED(CONFIG_IPV6) 129 123 int ip6_del_rt(struct net *net, struct fib6_info *f6i, bool skip_notify); 124 + #else 125 + static inline int ip6_del_rt(struct net *net, struct fib6_info *f6i, 126 + bool skip_notify) 127 + { 128 + return -EAFNOSUPPORT; 129 + } 130 + #endif 130 131 131 132 void rt6_flush_exceptions(struct fib6_info *f6i); 132 133 void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args, ··· 285 270 return __ipv6_anycast_destination(&rt->rt6i_dst, rt->rt6i_flags, daddr); 286 271 } 287 272 273 + #if IS_ENABLED(CONFIG_IPV6) 288 274 int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, 289 275 int (*output)(struct net *, struct sock *, struct sk_buff *)); 276 + #else 277 + static inline int ip6_fragment(struct net *net, struct sock *sk, 278 + struct sk_buff *skb, 279 + int (*output)(struct net *, struct sock *, 280 + struct sk_buff *)) 281 + { 282 + kfree_skb(skb); 283 + return -EAFNOSUPPORT; 284 + } 285 + #endif 290 286 291 287 /* Variant of dst_mtu() for IPv6 users */ 292 288 static inline u32 dst6_mtu(const struct dst_entry *dst)
+10
include/net/ipv6.h
··· 1044 1044 1045 1045 int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, 1046 1046 struct flowi6 *fl6); 1047 + #if IS_ENABLED(CONFIG_IPV6) 1047 1048 struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, 1048 1049 const struct in6_addr *final_dst); 1050 + #else 1051 + static inline struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, 1052 + struct flowi6 *fl6, 1053 + const struct in6_addr *final_dst) 1054 + { 1055 + return ERR_PTR(-EAFNOSUPPORT); 1056 + } 1057 + #endif 1058 + 1049 1059 struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, 1050 1060 const struct in6_addr *final_dst, 1051 1061 bool connected);
+5 -1
include/net/ndisc.h
··· 406 406 static inline struct neighbour *ip_neigh_gw6(struct net_device *dev, 407 407 const void *addr) 408 408 { 409 + #if IS_ENABLED(CONFIG_IPV6) 409 410 struct neighbour *neigh; 410 411 411 412 neigh = __ipv6_neigh_lookup_noref_stub(dev, addr); 412 413 if (unlikely(!neigh)) 413 - neigh = __neigh_create(ipv6_stub->nd_tbl, addr, dev, false); 414 + neigh = __neigh_create(&nd_tbl, addr, dev, false); 414 415 415 416 return neigh; 417 + #else 418 + return ERR_PTR(-EAFNOSUPPORT); 419 + #endif 416 420 } 417 421 418 422 int ndisc_init(void);
+8
net/ipv6/ip6_output.c
··· 873 873 __be32 frag_id; 874 874 u8 *prevhdr, nexthdr = 0; 875 875 876 + if (!ipv6_mod_enabled()) { 877 + kfree_skb(skb); 878 + return -EAFNOSUPPORT; 879 + } 880 + 876 881 err = ip6_find_1stfragopt(skb, &prevhdr); 877 882 if (err < 0) 878 883 goto fail; ··· 1050 1045 kfree_skb(skb); 1051 1046 return err; 1052 1047 } 1048 + EXPORT_SYMBOL_GPL(ip6_fragment); 1053 1049 1054 1050 static inline int ip6_rt_check(const struct rt6key *rt_key, 1055 1051 const struct in6_addr *fl_addr, ··· 1262 1256 struct dst_entry *dst = NULL; 1263 1257 int err; 1264 1258 1259 + if (!ipv6_mod_enabled()) 1260 + return ERR_PTR(-EAFNOSUPPORT); 1265 1261 err = ip6_dst_lookup_tail(net, sk, &dst, fl6); 1266 1262 if (err) 1267 1263 return ERR_PTR(err);
+1
net/ipv6/ndisc.c
··· 576 576 577 577 ndisc_send_skb(skb, daddr, src_addr); 578 578 } 579 + EXPORT_SYMBOL_GPL(ndisc_send_na); 579 580 580 581 static void ndisc_send_unsol_na(struct net_device *dev) 581 582 {
+6
net/ipv6/route.c
··· 2655 2655 skb_dst_set_noref(skb, ip6_route_input_lookup(net, skb->dev, 2656 2656 &fl6, skb, flags)); 2657 2657 } 2658 + EXPORT_SYMBOL_GPL(ip6_route_input); 2658 2659 2659 2660 INDIRECT_CALLABLE_SCOPE struct rt6_info *ip6_pol_route_output(struct net *net, 2660 2661 struct fib6_table *table, ··· 3585 3584 struct net_device *dev = NULL; 3586 3585 struct inet6_dev *idev = NULL; 3587 3586 int err; 3587 + 3588 + if (!ipv6_mod_enabled()) { 3589 + NL_SET_ERR_MSG(extack, "IPv6 support not enabled in kernel"); 3590 + return -EAFNOSUPPORT; 3591 + } 3588 3592 3589 3593 fib6_nh->fib_nh_family = AF_INET6; 3590 3594 #ifdef CONFIG_IPV6_ROUTER_PREF