net/ipv6: followup to fib6_info change
Subsystems (4)
cover net/ipv6: followup to fib6_info change
Followup to fib change for IPv6.
First 2 patches rename fib6_info struct elements to match its name, and rename addrconf_dst_alloc to match what it returns.
Patches 3-7 refactor the code to remove the need for fib6_idev reducing fib6_info by another 8 bytes to 200 bytes.
Patch 8 fixes the gfp flags argument to addrconf_prefix_route in a couple of places.
David Ahern (8):
net/ipv6: Rename fib6_info struct elements
net/ipv6: Rename addrconf_dst_alloc
net/ipv6: Remove aca_idev
net/ipv6: Remove unnecessary checks on fib6_idev net/ipv6: Change ip6_route_get_saddr to get dev from route net/ipv6: Remove compare of fib6_idev from rt6_duplicate_nexthop net/ipv6: Remove fib6_idev
net/ipv6: Fix gfp_flags arg to addrconf_prefix_route
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 56 ++-- include/net/if_inet6.h | 1 - include/net/ip6_fib.h | 42 +-- include/net/ip6_route.h | 34 +- net/ipv6/addrconf.c | 59 ++-- net/ipv6/anycast.c | 24 +- net/ipv6/ip6_fib.c | 168 +++++----- net/ipv6/ndisc.c | 2 +- net/ipv6/route.c | 358 +++++++++++---------- 9 files changed, 375 insertions(+), 369 deletions(-)
Signature · 1 line
2.11.0
PATCH 1/8 net/ipv6: Rename fib6_info struct elements
Change the prefix for fib6_info struct elements from rt6i_ to fib6_. rt6i_pcpu and rt6i_exception_bucket are left as is given that they point to rt6_info entries.
Rename only; not functional change intended.
--- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 56 ++--- include/net/ip6_fib.h | 38 +-- include/net/ip6_route.h | 26 +- net/ipv6/addrconf.c | 24 +- net/ipv6/anycast.c | 8 +- net/ipv6/ip6_fib.c | 170 ++++++------- net/ipv6/ndisc.c | 2 +- net/ipv6/route.c | 272 ++++++++++----------- 8 files changed, 298 insertions(+), 298 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +28 -28
@@ -4705,17 +4705,17 @@ static bool mlxsw_sp_fib6_rt_should_ignore(const struct fib6_info *rt)* are trapped to the CPU, so no need to program specific routes * for them. */ -if (ipv6_addr_type (&rt->rt6i_dst.addr) &IPV6_ADDR_LINKLOCAL ) +if (ipv6_addr_type (&rt->fib6_dst.addr) &IPV6_ADDR_LINKLOCAL )return true;/* Multicast routes aren't supported, so ignore them. Neighbour * Discovery packets are specifically trapped. */ -if (ipv6_addr_type (&rt->rt6i_dst.addr) &IPV6_ADDR_MULTICAST ) +if (ipv6_addr_type (&rt->fib6_dst.addr) &IPV6_ADDR_MULTICAST )return true;/* Cloned routes are irrelevant in the forwarding path. */ -if (rt->rt6i_flags &RTF_CACHE ) +if (rt->fib6_flags &RTF_CACHE )return true;return false;
@@ -4759,7 +4759,7 @@ static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)static bool mlxsw_sp_fib6_rt_can_mp (const struct fib6_info *rt) {/* RTF_CACHE routes are ignored */ -return (rt->rt6i_flags & (RTF_GATEWAY |RTF_ADDRCONF )) ==RTF_GATEWAY ; +return (rt->fib6_flags & (RTF_GATEWAY |RTF_ADDRCONF )) ==RTF_GATEWAY ; } static struct fib6_info *
@@ -4784,16 +4784,16 @@ mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,/* RT6_TABLE_LOCAL and RT6_TABLE_MAIN share the same * virtual router. */ -if (rt->rt6i_table->tb6_id > nrt->rt6i_table->tb6_id) +if (rt->fib6_table->tb6_id > nrt->fib6_table->tb6_id)continue ; -if (rt->rt6i_table->tb6_id != nrt->rt6i_table->tb6_id) +if (rt->fib6_table->tb6_id != nrt->fib6_table->tb6_id)break ; -if (rt->rt6i_metric < nrt->rt6i_metric) +if (rt->fib6_metric < nrt->fib6_metric)continue ; -if (rt->rt6i_metric == nrt->rt6i_metric && +if (rt->fib6_metric == nrt->fib6_metric &&mlxsw_sp_fib6_rt_can_mp (rt))return fib6_entry; -if (rt->rt6i_metric > nrt->rt6i_metric) +if (rt->fib6_metric > nrt->fib6_metric)break ; }
@@ -4899,7 +4899,7 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,static bool mlxsw_sp_rt6_is_gateway (const struct mlxsw_sp *mlxsw_sp,const struct fib6_info *rt) { -return rt->rt6i_flags &RTF_GATEWAY || +return rt->fib6_flags &RTF_GATEWAY ||mlxsw_sp_nexthop6_ipip_type (mlxsw_sp, rt,NULL ); }
@@ -5092,9 +5092,9 @@ static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,* local, which will cause them to be trapped with a lower * priority than packets that need to be locally received. */ -if (rt->rt6i_flags & (RTF_LOCAL |RTF_ANYCAST )) +if (rt->fib6_flags & (RTF_LOCAL |RTF_ANYCAST )) fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_TRAP ; -else if (rt->rt6i_flags &RTF_REJECT ) +else if (rt->fib6_flags &RTF_REJECT ) fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ;else if (mlxsw_sp_rt6_is_gateway (mlxsw_sp, rt)) fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_REMOTE ;
@@ -5175,18 +5175,18 @@ mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node,list_for_each_entry (fib6_entry, &fib_node->entry_list, common.list) {struct fib6_info *rt =mlxsw_sp_fib6_entry_rt (fib6_entry); -if (rt->rt6i_table->tb6_id > nrt->rt6i_table->tb6_id) +if (rt->fib6_table->tb6_id > nrt->fib6_table->tb6_id)continue ; -if (rt->rt6i_table->tb6_id != nrt->rt6i_table->tb6_id) +if (rt->fib6_table->tb6_id != nrt->fib6_table->tb6_id)break ; -if (replace && rt->rt6i_metric == nrt->rt6i_metric) { +if (replace && rt->fib6_metric == nrt->fib6_metric) {if (mlxsw_sp_fib6_rt_can_mp (rt) ==mlxsw_sp_fib6_rt_can_mp (nrt))return fib6_entry;if (mlxsw_sp_fib6_rt_can_mp (nrt)) fallback = fallback ?: fib6_entry; } -if (rt->rt6i_metric > nrt->rt6i_metric) +if (rt->fib6_metric > nrt->fib6_metric)return fallback ?: fib6_entry; }
@@ -5215,7 +5215,7 @@ mlxsw_sp_fib6_node_list_insert(struct mlxsw_sp_fib6_entry *new6_entry,list_for_each_entry (last, &fib_node->entry_list, common.list) {struct fib6_info *rt =mlxsw_sp_fib6_entry_rt (last); -if (nrt->rt6i_table->tb6_id > rt->rt6i_table->tb6_id) +if (nrt->fib6_table->tb6_id > rt->fib6_table->tb6_id)break ; fib6_entry = last; }
@@ -5275,22 +5275,22 @@ mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_fib *fib;struct mlxsw_sp_vr *vr; - vr =mlxsw_sp_vr_find (mlxsw_sp, rt->rt6i_table->tb6_id); + vr =mlxsw_sp_vr_find (mlxsw_sp, rt->fib6_table->tb6_id);if (!vr)return NULL ; fib =mlxsw_sp_vr_fib (vr,MLXSW_SP_L3_PROTO_IPV6 ); - fib_node =mlxsw_sp_fib_node_lookup (fib, &rt->rt6i_dst.addr, -sizeof (rt->rt6i_dst.addr), - rt->rt6i_dst.plen); + fib_node =mlxsw_sp_fib_node_lookup (fib, &rt->fib6_dst.addr, +sizeof (rt->fib6_dst.addr), + rt->fib6_dst.plen);if (!fib_node)return NULL ;list_for_each_entry (fib6_entry, &fib_node->entry_list, common.list) {struct fib6_info *iter_rt =mlxsw_sp_fib6_entry_rt (fib6_entry); -if (rt->rt6i_table->tb6_id == iter_rt->rt6i_table->tb6_id && - rt->rt6i_metric == iter_rt->rt6i_metric && +if (rt->fib6_table->tb6_id == iter_rt->fib6_table->tb6_id && + rt->fib6_metric == iter_rt->fib6_metric &&mlxsw_sp_fib6_entry_rt_find (fib6_entry, rt))return fib6_entry; }
@@ -5325,16 +5325,16 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,if (mlxsw_sp->router->aborted)return 0 ; -if (rt->rt6i_src.plen) +if (rt->fib6_src.plen)return -EINVAL ;if (mlxsw_sp_fib6_rt_should_ignore (rt))return 0 ; - fib_node =mlxsw_sp_fib_node_get (mlxsw_sp, rt->rt6i_table->tb6_id, - &rt->rt6i_dst.addr, -sizeof (rt->rt6i_dst.addr), - rt->rt6i_dst.plen, + fib_node =mlxsw_sp_fib_node_get (mlxsw_sp, rt->fib6_table->tb6_id, + &rt->fib6_dst.addr, +sizeof (rt->fib6_dst.addr), + rt->fib6_dst.plen,MLXSW_SP_L3_PROTO_IPV6 );if (IS_ERR (fib_node))return PTR_ERR (fib_node);
include/net/ip6_fib.h +19 -19
@@ -134,34 +134,34 @@ struct fib6_nh { };struct fib6_info { -struct fib6_table *rt6i_table; +struct fib6_table *fib6_table;struct fib6_info __rcu *rt6_next; -struct fib6_node __rcu *rt6i_node; +struct fib6_node __rcu *fib6_node;/* Multipath routes: * siblings is a list of fib6_info that have the the same metric/weight, * destination, but not the same gateway. nsiblings is just a cache * to speed up lookup. */ -struct list_head rt6i_siblings; -unsigned int rt6i_nsiblings; +struct list_head fib6_siblings; +unsigned int fib6_nsiblings; -atomic_t rt6i_ref; -struct inet6_dev *rt6i_idev; +atomic_t fib6_ref; +struct inet6_dev *fib6_idev;unsigned long expires;struct dst_metrics *fib6_metrics;#define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] -struct rt6key rt6i_dst; -u32 rt6i_flags; -struct rt6key rt6i_src; -struct rt6key rt6i_prefsrc; +struct rt6key fib6_dst; +u32 fib6_flags; +struct rt6key fib6_src; +struct rt6key fib6_prefsrc;struct rt6_info *__percpu *rt6i_pcpu;struct rt6_exception_bucket __rcu *rt6i_exception_bucket; -u32 rt6i_metric; -u8 rt6i_protocol; +u32 fib6_metric; +u8 fib6_protocol;u8 fib6_type;u8 exception_bucket_flushed:1 , should_flush:1,
@@ -206,7 +206,7 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)static inline void fib6_clean_expires (struct fib6_info *f6i) { - f6i->rt6i_flags &= ~RTF_EXPIRES ; + f6i->fib6_flags &= ~RTF_EXPIRES ; f6i->expires =0 ; }
@@ -214,12 +214,12 @@ static inline void fib6_set_expires(struct fib6_info *f6i, unsigned long expires) { f6i->expires = expires; - f6i->rt6i_flags |=RTF_EXPIRES ; + f6i->fib6_flags |=RTF_EXPIRES ; }static inline bool fib6_check_expired (const struct fib6_info *f6i) { -if (f6i->rt6i_flags &RTF_EXPIRES ) +if (f6i->fib6_flags &RTF_EXPIRES )return time_after (jiffies, f6i->expires);return false; }
@@ -250,14 +250,14 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)* Return true if we can get cookie safely * Return false if not */ -static inline bool rt6_get_cookie_safe (const struct fib6_info *rt, +static inline bool rt6_get_cookie_safe (const struct fib6_info *f6i,u32 *cookie) {struct fib6_node *fn;bool status = false;rcu_read_lock (); - fn =rcu_dereference (rt->rt6i_node); + fn =rcu_dereference (f6i->fib6_node);if (fn) { *cookie = fn->fn_sernum;
@@ -295,12 +295,12 @@ void fib6_info_destroy(struct fib6_info *f6i);static inline void fib6_info_hold (struct fib6_info *f6i) { -atomic_inc (&f6i->rt6i_ref); +atomic_inc (&f6i->fib6_ref); }static inline void fib6_info_release (struct fib6_info *f6i) { -if (f6i &&atomic_dec_and_test (&f6i->rt6i_ref)) +if (f6i &&atomic_dec_and_test (&f6i->fib6_ref))fib6_info_destroy (f6i); }
include/net/ip6_route.h +13 -13
@@ -66,9 +66,9 @@ static inline bool rt6_need_strict(const struct in6_addr *daddr) (IPV6_ADDR_MULTICAST |IPV6_ADDR_LINKLOCAL |IPV6_ADDR_LOOPBACK ); } -static inline bool rt6_qualify_for_ecmp (const struct fib6_info *rt) +static inline bool rt6_qualify_for_ecmp (const struct fib6_info *f6i) { -return (rt->rt6i_flags & (RTF_GATEWAY |RTF_ADDRCONF |RTF_DYNAMIC )) == +return (f6i->fib6_flags & (RTF_GATEWAY |RTF_ADDRCONF |RTF_DYNAMIC )) ==RTF_GATEWAY ; }
@@ -102,23 +102,23 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);int ip6_route_add (struct fib6_config *cfg,gfp_t gfp_flags,struct netlink_ext_ack *extack); -int ip6_ins_rt (struct net *net,struct fib6_info *rt); -int ip6_del_rt (struct net *net,struct fib6_info *rt); +int ip6_ins_rt (struct net *net,struct fib6_info *f6i); +int ip6_del_rt (struct net *net,struct fib6_info *f6i); -void rt6_flush_exceptions (struct fib6_info *rt); -void rt6_age_exceptions (struct fib6_info *rt,struct fib6_gc_args *gc_args, +void rt6_flush_exceptions (struct fib6_info *f6i); +void rt6_age_exceptions (struct fib6_info *f6i,struct fib6_gc_args *gc_args,unsigned long now); -static inline int ip6_route_get_saddr (struct net *net,struct fib6_info *rt, +static inline int ip6_route_get_saddr (struct net *net,struct fib6_info *f6i,const struct in6_addr *daddr,unsigned int prefs,struct in6_addr *saddr) { -struct inet6_dev *idev = rt ? rt->rt6i_idev :NULL ; +struct inet6_dev *idev = f6i ? f6i->fib6_idev :NULL ;int err =0 ; -if (rt && rt->rt6i_prefsrc.plen) - *saddr = rt->rt6i_prefsrc.addr; +if (f6i && f6i->fib6_prefsrc.plen) + *saddr = f6i->fib6_prefsrc.addr;else err =ipv6_dev_get_saddr (net, idev ? idev->dev :NULL , daddr, prefs, saddr);
@@ -176,14 +176,14 @@ struct rt6_rtnl_dump_arg {struct net *net; }; -int rt6_dump_route (struct fib6_info *rt,void *p_arg); +int rt6_dump_route (struct fib6_info *f6i,void *p_arg);void rt6_mtu_change (struct net_device *dev,unsigned int mtu);void rt6_remove_prefsrc (struct inet6_ifaddr *ifp);void rt6_clean_tohost (struct net *net,struct in6_addr *gateway);void rt6_sync_up (struct net_device *dev,unsigned int nh_flags);void rt6_disable_ip (struct net_device *dev,unsigned long event);void rt6_sync_down_dev (struct net_device *dev,unsigned long event); -void rt6_multipath_rebalance (struct fib6_info *rt); +void rt6_multipath_rebalance (struct fib6_info *f6i);void rt6_uncached_list_add (struct rt6_info *rt);void rt6_uncached_list_del (struct rt6_info *rt);
@@ -274,7 +274,7 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,static inline bool rt6_duplicate_nexthop (struct fib6_info *a,struct fib6_info *b) {return a->fib6_nh.nh_dev == b->fib6_nh.nh_dev && - a->rt6i_idev == b->rt6i_idev && + a->fib6_idev == b->fib6_idev &&ipv6_addr_equal (&a->fib6_nh.nh_gw, &b->fib6_nh.nh_gw) && !lwtunnel_cmp_encap (a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate); }
net/ipv6/addrconf.c +12 -12
@@ -1178,19 +1178,19 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires)static void cleanup_prefix_route (struct inet6_ifaddr *ifp,unsigned long expires,bool del_rt) { -struct fib6_info *rt; +struct fib6_info *f6i; - rt =addrconf_get_prefix_route (&ifp->addr, + f6i =addrconf_get_prefix_route (&ifp->addr, ifp->prefix_len, ifp->idev->dev,0 ,RTF_GATEWAY |RTF_DEFAULT ); -if (rt) { +if (f6i) {if (del_rt) -ip6_del_rt (dev_net (ifp->idev->dev), rt); +ip6_del_rt (dev_net (ifp->idev->dev), f6i);else { -if (!(rt->rt6i_flags &RTF_EXPIRES )) -fib6_set_expires (rt, expires); -fib6_info_release (rt); +if (!(f6i->fib6_flags &RTF_EXPIRES )) +fib6_set_expires (f6i, expires); +fib6_info_release (f6i); } } }
@@ -2370,9 +2370,9 @@ static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,for_each_fib6_node_rt_rcu (fn) {if (rt->fib6_nh.nh_dev->ifindex != dev->ifindex)continue ; -if ((rt->rt6i_flags & flags) != flags) +if ((rt->fib6_flags & flags) != flags)continue ; -if ((rt->rt6i_flags & noflags) !=0 ) +if ((rt->fib6_flags & noflags) !=0 )continue ;fib6_info_hold (rt);break ;
@@ -3341,11 +3341,11 @@ static int fixup_permanent_addr(struct net *net, struct inet6_dev *idev, struct inet6_ifaddr *ifp) { -/* !rt6i_node means the host route was removed from the +/* !fib6_node means the host route was removed from the * FIB, for example, if 'lo' device is taken down. In that * case regenerate the host route. */ -if (!ifp->rt || !ifp->rt->rt6i_node) { +if (!ifp->rt || !ifp->rt->fib6_node) {struct fib6_info *rt, *prev; rt = addrconf_dst_alloc(net, idev, &ifp->addr, false,
@@ -5612,7 +5612,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)* our DAD process, so we don't need * to do it again */ -if (!rcu_access_pointer (ifp->rt->rt6i_node)) +if (!rcu_access_pointer (ifp->rt->fib6_node))ip6_ins_rt (net, ifp->rt);if (ifp->idev->cnf.forwarding)addrconf_join_anycast (ifp);
net/ipv6/anycast.c +4 -4
@@ -218,10 +218,10 @@ static void aca_put(struct ifacaddr6 *ac) } } -static struct ifacaddr6 *aca_alloc (struct fib6_info *rt, +static struct ifacaddr6 *aca_alloc (struct fib6_info *f6i,const struct in6_addr *addr) { -struct inet6_dev *idev = rt->rt6i_idev; +struct inet6_dev *idev = f6i->fib6_idev;struct ifacaddr6 *aca; aca =kzalloc (sizeof (*aca),GFP_ATOMIC );
@@ -231,8 +231,8 @@ static struct ifacaddr6 *aca_alloc(struct fib6_info *rt, aca->aca_addr = *addr;in6_dev_hold (idev); aca->aca_idev = idev; -fib6_info_hold (rt); - aca->aca_rt = rt; +fib6_info_hold (f6i); + aca->aca_rt = f6i; aca->aca_users =1 ;/* aca_tstamp should be updated upon changes */ aca->aca_cstamp = aca->aca_tstamp = jiffies;
net/ipv6/ip6_fib.c +85 -85
463 lines not on this page · raw message
net/ipv6/ndisc.c +1 -1
@@ -1318,7 +1318,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) } neigh->flags |=NTF_ROUTER ; }else if (rt) { - rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK ) |RTF_PREF (pref); + rt->fib6_flags = (rt->fib6_flags & ~RTF_PREF_MASK ) |RTF_PREF (pref); }if (rt)
net/ipv6/route.c +136 -136
809 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH 2/8 net/ipv6: Rename addrconf_dst_alloc
In reply to David Ahernaddrconf_dst_alloc now returns a fib6_info. Update the name and its users to reflect the change.
Rename only; no functional change intended.
--- include/net/ip6_route.h | 2 +- net/ipv6/addrconf.c | 28 ++++++++++++++-------------- net/ipv6/anycast.c | 14 +++++++------- net/ipv6/route.c | 44 ++++++++++++++++++++++---------------------- 4 files changed, 44 insertions(+), 44 deletions(-)
include/net/ip6_route.h +1 -1
@@ -136,7 +136,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);void fib6_force_start_gc (struct net *net); -struct fib6_info *addrconf_dst_alloc (struct net *net,struct inet6_dev *idev, +struct fib6_info *addrconf_f6i_alloc (struct net *net,struct inet6_dev *idev,const struct in6_addr *addr,bool anycast,gfp_t gfp_flags);
net/ipv6/addrconf.c +14 -14
@@ -994,7 +994,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,gfp_t gfp_flags = can_block ?GFP_KERNEL :GFP_ATOMIC ;struct net *net =dev_net (idev->dev);struct inet6_ifaddr *ifa =NULL ; -struct fib6_info *rt =NULL ; +struct fib6_info *f6i =NULL ;int err =0 ;int addr_type =ipv6_addr_type (addr);
@@ -1036,16 +1036,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, goto out; } - rt =addrconf_dst_alloc (net, idev, addr, false, gfp_flags); -if (IS_ERR (rt)) { - err =PTR_ERR (rt); - rt =NULL ; + f6i =addrconf_f6i_alloc (net, idev, addr, false, gfp_flags); +if (IS_ERR (f6i)) { + err =PTR_ERR (f6i); + f6i =NULL ; goto out; }if (net->ipv6.devconf_all->disable_policy || idev->cnf.disable_policy) - rt->dst_nopolicy = true; + f6i->dst_nopolicy = true;neigh_parms_data_state_setall (idev->nd_parms);
@@ -1067,7 +1067,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, ifa->cstamp = ifa->tstamp = jiffies; ifa->tokenized = false; - ifa->rt = rt; + ifa->rt = f6i; ifa->idev = idev;in6_dev_hold (idev);
@@ -1101,7 +1101,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,inet6addr_notifier_call_chain (NETDEV_UP , ifa); out:if (unlikely (err <0 )) { -fib6_info_release (rt); +fib6_info_release (f6i);if (ifa) {if (ifa->idev)
@@ -3346,17 +3346,17 @@ static int fixup_permanent_addr(struct net *net,* case regenerate the host route. */ if (!ifp->rt || !ifp->rt->fib6_node) { -struct fib6_info *rt, *prev; +struct fib6_info *f6i, *prev; - rt =addrconf_dst_alloc (net, idev, &ifp->addr, false, -GFP_ATOMIC ); -if (IS_ERR (rt)) -return PTR_ERR (rt); + f6i =addrconf_f6i_alloc (net, idev, &ifp->addr, false, +GFP_ATOMIC ); +if (IS_ERR (f6i)) +return PTR_ERR (f6i);/* ifp->rt can be accessed outside of rtnl */ spin_lock (&ifp->lock); prev = ifp->rt; - ifp->rt = rt; + ifp->rt = f6i;spin_unlock (&ifp->lock);fib6_info_release (prev);
net/ipv6/anycast.c +7 -7
@@ -247,7 +247,7 @@ static struct ifacaddr6 *aca_alloc(struct fib6_info *f6i,int __ipv6_dev_ac_inc (struct inet6_dev *idev,const struct in6_addr *addr) {struct ifacaddr6 *aca; -struct fib6_info *rt; +struct fib6_info *f6i;struct net *net;int err;
@@ -268,14 +268,14 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr) } net =dev_net (idev->dev); - rt =addrconf_dst_alloc (net, idev, addr, true,GFP_ATOMIC ); -if (IS_ERR (rt)) { - err =PTR_ERR (rt); + f6i =addrconf_f6i_alloc (net, idev, addr, true,GFP_ATOMIC ); +if (IS_ERR (f6i)) { + err =PTR_ERR (f6i); goto out; } - aca =aca_alloc (rt, addr); + aca =aca_alloc (f6i, addr);if (!aca) { -fib6_info_release (rt); +fib6_info_release (f6i); err = -ENOMEM ; goto out; }
@@ -289,7 +289,7 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)aca_get (aca);write_unlock_bh (&idev->lock); -ip6_ins_rt (net, rt); +ip6_ins_rt (net, f6i);addrconf_join_solict (idev->dev, &aca->aca_addr);
net/ipv6/route.c +22 -22
66 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH 3/8 net/ipv6: Remove aca_idev
In reply to David Ahernaca_idev has only 1 user - inet6_fill_ifacaddr - and it only wants the device index which can be extracted from the fib6_info nexthop.
--- include/net/if_inet6.h | 1 - include/net/ip6_fib.h | 5 +++++ net/ipv6/addrconf.c | 3 ++- net/ipv6/anycast.c | 4 ---- 4 files changed, 7 insertions(+), 6 deletions(-)
include/net/if_inet6.h +0 -1
@@ -143,7 +143,6 @@ struct ipv6_ac_socklist {struct ifacaddr6 {struct in6_addr aca_addr; -struct inet6_dev *aca_idev;struct fib6_info *aca_rt;struct ifacaddr6 *aca_next;int aca_users;
include/net/ip6_fib.h +5 -0
@@ -410,6 +410,11 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt, struct nl_info *info, struct netlink_ext_ack *extack);int fib6_del (struct fib6_info *rt,struct nl_info *info); +static inline struct net_device *fib6_info_nh_dev (const struct fib6_info *f6i) +{ +return f6i->fib6_nh.nh_dev; +} +void inet6_rt_notify (int event,struct fib6_info *rt,struct nl_info *info,unsigned int flags);
net/ipv6/addrconf.c +2 -1
@@ -4817,9 +4817,10 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,static int inet6_fill_ifacaddr (struct sk_buff *skb,struct ifacaddr6 *ifaca,u32 portid,u32 seq,int event,unsigned int flags) { +struct net_device *dev =fib6_info_nh_dev (ifaca->aca_rt); +int ifindex = dev ? dev->ifindex :1 ;struct nlmsghdr *nlh;u8 scope =RT_SCOPE_UNIVERSE ; -int ifindex = ifaca->aca_idev->dev->ifindex;if (ipv6_addr_scope (&ifaca->aca_addr) &IFA_SITE ) scope =RT_SCOPE_SITE ;
net/ipv6/anycast.c +0 -4
@@ -212,7 +212,6 @@ static void aca_get(struct ifacaddr6 *aca)static void aca_put (struct ifacaddr6 *ac) {if (refcount_dec_and_test (&ac->aca_refcnt)) { -in6_dev_put (ac->aca_idev);fib6_info_release (ac->aca_rt);kfree (ac); }
@@ -221,7 +220,6 @@ static void aca_put(struct ifacaddr6 *ac)static struct ifacaddr6 *aca_alloc (struct fib6_info *f6i,const struct in6_addr *addr) { -struct inet6_dev *idev = f6i->fib6_idev;struct ifacaddr6 *aca; aca =kzalloc (sizeof (*aca),GFP_ATOMIC );
@@ -229,8 +227,6 @@ static struct ifacaddr6 *aca_alloc(struct fib6_info *f6i,return NULL ; aca->aca_addr = *addr; -in6_dev_hold (idev); - aca->aca_idev = idev;fib6_info_hold (f6i); aca->aca_rt = f6i; aca->aca_users =1 ;
Signature · 1 line
2.11.0
PATCH 4/8 net/ipv6: Remove unnecessary checks on fib6_idev
In reply to David AhernPrior to 4832c30d5458 ("net: ipv6: put host and anycast routes on device with address") host routes and anycast routes were installed with the device set to loopback (or VRF device once that feature was added). In the older code dst.dev was set to loopback (needed for packet tx) and rt6i_idev was used to denote the actual interface.
Commit 4832c30d5458 changed the code to have dst.dev pointing to the real device with the switch to lo or vrf device done on dst clones. As a consequence of this change a couple of device checks during route lookups are no longer needed. Remove them.
--- net/ipv6/route.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-)
net/ipv6/route.c +2 -22
@@ -455,7 +455,6 @@ static inline struct fib6_info *rt6_device_match(struct net *net, int oif, int flags) { -struct fib6_info *local =NULL ;struct fib6_info *sprt; if (!oif && ipv6_addr_any(saddr) &&
@@ -471,17 +470,6 @@ static inline struct fib6_info *rt6_device_match(struct net *net,if (oif) {if (dev->ifindex == oif)return sprt; -if (dev->flags &IFF_LOOPBACK ) { -if (!sprt->fib6_idev || - sprt->fib6_idev->dev->ifindex != oif) { -if (flags &RT6_LOOKUP_F_IFACE ) -continue ; -if (local && - local->fib6_idev->dev->ifindex == oif) -continue ; - } - local = sprt; - } }else {if (ipv6_chk_addr (net, saddr, dev, flags &RT6_LOOKUP_F_IFACE ))
@@ -489,13 +477,8 @@ static inline struct fib6_info *rt6_device_match(struct net *net, } } -if (oif) { -if (local) -return local; - -if (flags &RT6_LOOKUP_F_IFACE ) -return net->ipv6.fib6_null_entry; - } +if (oif && flags &RT6_LOOKUP_F_IFACE ) +return net->ipv6.fib6_null_entry;return rt->fib6_nh.nh_flags &RTNH_F_DEAD ? net->ipv6.fib6_null_entry : rt; }
@@ -586,9 +569,6 @@ static inline int rt6_check_dev(struct fib6_info *rt, int oif)if (!oif || dev->ifindex == oif)return 2 ; -if ((dev->flags &IFF_LOOPBACK ) && - rt->fib6_idev && rt->fib6_idev->dev->ifindex == oif) -return 1 ;return 0 ; }
Signature · 1 line
2.11.0
PATCH 5/8 net/ipv6: Change ip6_route_get_saddr to get dev from route
In reply to David AhernPrior to 4832c30d5458 ("net: ipv6: put host and anycast routes on device with address") host routes and anycast routes were installed with the device set to loopback (or VRF device once that feature was added). In the older code dst.dev was set to loopback (needed for packet tx) and rt6i_idev was used to denote the actual interface.
Commit 4832c30d5458 changed the code to have dst.dev pointing to the real device with the switch to lo or vrf device done on dst clones. As a consequence of this change ip6_route_get_saddr can just pass the nexthop device to ipv6_dev_get_saddr.
--- include/net/ip6_route.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
include/net/ip6_route.h +6 -5
@@ -114,14 +114,15 @@ static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i,unsigned int prefs, struct in6_addr *saddr) { - struct inet6_dev *idev = f6i ? f6i->fib6_idev : NULL; int err = 0; -if (f6i && f6i->fib6_prefsrc.plen) +if (f6i && f6i->fib6_prefsrc.plen) { *saddr = f6i->fib6_prefsrc.addr; -else - err =ipv6_dev_get_saddr (net, idev ? idev->dev :NULL , - daddr, prefs, saddr); + }else { +struct net_device *dev = f6i ?fib6_info_nh_dev (f6i) :NULL ; + + err =ipv6_dev_get_saddr (net, dev, daddr, prefs, saddr); + }return err; }
Signature · 1 line
2.11.0
PATCH 6/8 net/ipv6: Remove compare of fib6_idev from rt6_duplicate_nexthop
In reply to David AhernAfter 4832c30d5458 ("net: ipv6: put host and anycast routes on device with address") the comparison of idev does not add value since it correlates to the nexthop device which is already compared. Remove the idev comparison.
--- include/net/ip6_route.h | 1 - 1 file changed, 1 deletion(-)
include/net/ip6_route.h +0 -1
@@ -275,7 +275,6 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,static inline bool rt6_duplicate_nexthop (struct fib6_info *a,struct fib6_info *b) {return a->fib6_nh.nh_dev == b->fib6_nh.nh_dev && - a->fib6_idev == b->fib6_idev &&ipv6_addr_equal (&a->fib6_nh.nh_gw, &b->fib6_nh.nh_gw) && !lwtunnel_cmp_encap (a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate); }
Signature · 1 line
2.11.0
PATCH 7/8 net/ipv6: Remove fib6_idev
In reply to David Ahernfib6_idev can be obtained from __in6_dev_get on the nexthop device rather than caching it in the fib6_info. Remove it.
--- include/net/ip6_fib.h | 1 - net/ipv6/ip6_fib.c | 2 -- net/ipv6/route.c | 66 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 22 deletions(-)
include/net/ip6_fib.h +0 -1
@@ -147,7 +147,6 @@ struct fib6_info {unsigned int fib6_nsiblings;atomic_t fib6_ref; -struct inet6_dev *fib6_idev;unsigned long expires;struct dst_metrics *fib6_metrics;#define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1]
net/ipv6/ip6_fib.c +0 -2
@@ -197,8 +197,6 @@ void fib6_info_destroy(struct fib6_info *f6i) } } -if (f6i->fib6_idev) -in6_dev_put (f6i->fib6_idev);if (f6i->fib6_nh.nh_dev)dev_put (f6i->fib6_nh.nh_dev);
net/ipv6/route.c +47 -19
164 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH 8/8 net/ipv6: Fix gfp_flags arg to addrconf_prefix_route
In reply to David AhernEric noticed that __ipv6_ifa_notify is called under rcu_read_lock, so the gfp argument to addrconf_prefix_route can not be GFP_KERNEL.
While scrubbing other calls I noticed addrconf_addr_gen has one place with GFP_ATOMIC that can be GFP_KERNEL.
--- net/ipv6/addrconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv6/addrconf.c +2 -2
@@ -3245,7 +3245,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)addrconf_add_linklocal (idev, &addr,0 ); else if (prefix_route) addrconf_prefix_route(&addr, 64, idev->dev, - 0, 0, GFP_ATOMIC); + 0, 0, GFP_KERNEL);break ;case IN6_ADDR_GEN_MODE_NONE :default :
@@ -5620,7 +5620,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)if (!ipv6_addr_any (&ifp->peer_addr))addrconf_prefix_route (&ifp->peer_addr,128 , ifp->idev->dev,0 ,0 , -GFP_KERNEL ); +GFP_ATOMIC );break ;case RTM_DELADDR :if (ifp->idev->cnf.forwarding)
Signature · 1 line
2.11.0
David Miller
maintainerFrom: David Ahern <[email protected]>
Date: Wed, 18 Apr 2018 15:38:58 -0700
Quoted 10 lines
Followup to fib change for IPv6.
First 2 patches rename
fib6_infostruct elements to match its name, and renameaddrconf_dst_allocto match what it returns.Patches 3-7 refactor the code to remove the need for
fib6_idevreducingfib6_infoby another 8 bytes to 200 bytes.Patch 8 fixes the gfp flags argument to
addrconf_prefix_routein a couple of places.
Series applied.
I'm really happy with how these changes are making the code look.
The disconnect between dst.dev and rt6i_idev always bugged me.