net: Add extack for route add/delete failures
Subsystems (3)
cover net: Add extack for route add/delete failures
Use the extack feature to improve error messages to user on route add and delete failures.
David Ahern (4):
net: ipv4: Plumb extack through route add functions
net: ipv4: Add extack messages for route add failures
net: ipv6: Plumb extack through route add functions
net: ipv6: Add extack messages for route add failures
include/linux/netlink.h | 5 ++ include/net/ip6_fib.h | 3 +- include/net/ip6_route.h | 2 +- include/net/ip_fib.h | 3 +- net/ipv4/fib_frontend.c | 18 ++++--- net/ipv4/fib_lookup.h | 3 +- net/ipv4/fib_semantics.c | 133 ++++++++++++++++++++++++++++++++++++----------- net/ipv4/fib_trie.c | 4 +- net/ipv6/addrconf.c | 4 +- net/ipv6/ip6_fib.c | 18 +++++-- net/ipv6/route.c | 97 ++++++++++++++++++++++------------ 11 files changed, 208 insertions(+), 82 deletions(-)
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH 1/4 net: ipv4: Plumb extack through route add functions
Plumb extack argument down to route add functions.
--- include/net/ip_fib.h | 3 ++- net/ipv4/fib_frontend.c | 16 +++++++++------- net/ipv4/fib_lookup.h | 3 ++- net/ipv4/fib_semantics.c | 22 +++++++++++++--------- net/ipv4/fib_trie.c | 4 ++-- 5 files changed, 28 insertions(+), 20 deletions(-)
include/net/ip_fib.h +2 -1
@@ -263,7 +263,8 @@ struct fib_table {int fib_table_lookup (struct fib_table *tb,const struct flowi4 *flp,struct fib_result *res,int fib_flags); -int fib_table_insert (struct net *,struct fib_table *,struct fib_config *); +int fib_table_insert (struct net *,struct fib_table *,struct fib_config *, +struct netlink_ext_ack *extack);int fib_table_delete (struct net *,struct fib_table *,struct fib_config *);int fib_table_dump (struct fib_table *table,struct sk_buff *skb,struct netlink_callback *cb);
net/ipv4/fib_frontend.c +9 -7
@@ -594,7 +594,8 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) }else { tb =fib_new_table (net, cfg.fc_table);if (tb) - err =fib_table_insert (net, tb, &cfg); + err =fib_table_insert (net, tb, + &cfg,NULL );else err = -ENOBUFS ; }
@@ -626,14 +627,15 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = { };static int rtm_to_fib_config (struct net *net,struct sk_buff *skb, -struct nlmsghdr *nlh,struct fib_config *cfg) +struct nlmsghdr *nlh,struct fib_config *cfg, +struct netlink_ext_ack *extack) {struct nlattr *attr;int err, remaining;struct rtmsg *rtm; err =nlmsg_validate (nlh,sizeof (*rtm),RTA_MAX , rtm_ipv4_policy, -NULL ); + extack);if (err <0 ) goto errout;
@@ -718,7 +720,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,struct fib_table *tb;int err; - err =rtm_to_fib_config (net, skb, nlh, &cfg); + err =rtm_to_fib_config (net, skb, nlh, &cfg, extack);if (err <0 ) goto errout;
@@ -741,7 +743,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,struct fib_table *tb;int err; - err =rtm_to_fib_config (net, skb, nlh, &cfg); + err =rtm_to_fib_config (net, skb, nlh, &cfg, extack);if (err <0 ) goto errout;
@@ -751,7 +753,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, goto errout; } - err =fib_table_insert (net, tb, &cfg); + err =fib_table_insert (net, tb, &cfg, extack); errout:return err; }
@@ -845,7 +847,7 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad cfg.fc_scope =RT_SCOPE_HOST ;if (cmd ==RTM_NEWROUTE ) -fib_table_insert (net, tb, &cfg); +fib_table_insert (net, tb, &cfg,NULL );else fib_table_delete (net, tb, &cfg); }
net/ipv4/fib_lookup.h +2 -1
@@ -28,7 +28,8 @@ static inline void fib_alias_accessed(struct fib_alias *fa)/* Exported by fib_semantics.c */ void fib_release_info (struct fib_info *); -struct fib_info *fib_create_info (struct fib_config *cfg); +struct fib_info *fib_create_info (struct fib_config *cfg, +struct netlink_ext_ack *extack);int fib_nh_match (struct fib_config *cfg,struct fib_info *fi); int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos, struct fib_info *fi,
net/ipv4/fib_semantics.c +13 -9
@@ -454,7 +454,8 @@ static int fib_detect_death(struct fib_info *fi, int order,#ifdef CONFIG_IP_ROUTE_MULTIPATH -static int fib_count_nexthops (struct rtnexthop *rtnh,int remaining) +static int fib_count_nexthops (struct rtnexthop *rtnh,int remaining, +struct netlink_ext_ack *extack) {int nhs =0 ;
@@ -468,7 +469,8 @@ static int fib_count_nexthops(struct rtnexthop *rtnh, int remaining) }static int fib_get_nhs (struct fib_info *fi,struct rtnexthop *rtnh, -int remaining,struct fib_config *cfg) +int remaining,struct fib_config *cfg, +struct netlink_ext_ack *extack) {int ret;
@@ -714,7 +716,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)* |-> {local prefix} (terminal node) */ static int fib_check_nh (struct fib_config *cfg,struct fib_info *fi, -struct fib_nh *nh) +struct fib_nh *nh,struct netlink_ext_ack *extack) {int err =0 ;struct net *net;
@@ -797,7 +799,6 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,if (nh->nh_flags & (RTNH_F_PERVASIVE |RTNH_F_ONLINK ))return -EINVAL ; -rcu_read_lock (); err = -ENODEV ; in_dev =inetdev_by_index (net, nh->nh_oif);
@@ -980,7 +981,8 @@ fib_convert_metrics(struct fib_info *fi, const struct fib_config *cfg)return 0 ; } -struct fib_info *fib_create_info (struct fib_config *cfg) +struct fib_info *fib_create_info (struct fib_config *cfg, +struct netlink_ext_ack *extack) {int err;struct fib_info *fi =NULL ;
@@ -1000,7 +1002,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)#ifdef CONFIG_IP_ROUTE_MULTIPATH if (cfg->fc_mp) { - nhs =fib_count_nexthops (cfg->fc_mp, cfg->fc_mp_len); + nhs =fib_count_nexthops (cfg->fc_mp, cfg->fc_mp_len, extack);if (nhs ==0 ) goto err_inval; }
@@ -1062,7 +1064,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)if (cfg->fc_mp) {#ifdef CONFIG_IP_ROUTE_MULTIPATH - err =fib_get_nhs (fi, cfg->fc_mp, cfg->fc_mp_len, cfg); + err =fib_get_nhs (fi, cfg->fc_mp, cfg->fc_mp_len, cfg, extack);if (err !=0 ) goto failure;if (cfg->fc_oif && fi->fib_nh->nh_oif != cfg->fc_oif)
@@ -1129,7 +1131,9 @@ struct fib_info *fib_create_info(struct fib_config *cfg)struct fib_nh *nh = fi->fib_nh;/* Local address is added. */ -if (nhs !=1 || nh->nh_gw) +if (nhs !=1 ) + goto err_inval; +if (nh->nh_gw) goto err_inval; nh->nh_scope =RT_SCOPE_NOWHERE ; nh->nh_dev =dev_get_by_index (net, fi->fib_nh->nh_oif);
@@ -1140,7 +1144,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)int linkdown =0 ;change_nexthops (fi) { - err =fib_check_nh (cfg, fi, nexthop_nh); + err =fib_check_nh (cfg, fi, nexthop_nh, extack);if (err !=0 ) goto failure;if (nexthop_nh->nh_flags &RTNH_F_LINKDOWN )
net/ipv4/fib_trie.c +2 -2
@@ -1101,7 +1101,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp,/* Caller must hold RTNL. */ int fib_table_insert (struct net *net,struct fib_table *tb, -struct fib_config *cfg) +struct fib_config *cfg,struct netlink_ext_ack *extack) {enum fib_event_type event =FIB_EVENT_ENTRY_ADD ;struct trie *t = (struct trie *)tb->tb_data;
@@ -1125,7 +1125,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,if ((plen <KEYLENGTH ) && (key << plen))return -EINVAL ; - fi =fib_create_info (cfg); + fi =fib_create_info (cfg, extack);if (IS_ERR (fi)) { err =PTR_ERR (fi); goto err;
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH 2/4 net: ipv4: Add extack messages for route add failures
In reply to David AhernAdd messages for non-obvious errors (e.g, no need to add text for malloc failures or ENODEV failures). This mostly covers the annoying EINVAL errors Some message strings violate the 80-columns but searchable strings need to trump that rule.
--- include/linux/netlink.h | 5 +++ net/ipv4/fib_frontend.c | 2 + net/ipv4/fib_semantics.c | 115 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 100 insertions(+), 22 deletions(-)
include/linux/netlink.h +5 -0
@@ -97,6 +97,11 @@ struct netlink_ext_ack {#define NL_SET_ERR_MSG_MOD (extack, msg) \ NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg) +#define NL_SET_BAD_ATTR (extack, attr) do { \ + if ((extack)) \ + (extack)->bad_attr = (attr); \ +} while (0) +extern void netlink_kernel_release (struct sock *sk);extern int __netlink_change_ngroups (struct sock *sk,unsigned int groups);extern int netlink_change_ngroups (struct sock *sk,unsigned int groups);
net/ipv4/fib_frontend.c +2 -0
@@ -656,6 +656,7 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, cfg->fc_nlinfo.nl_net = net;if (cfg->fc_type >RTN_MAX ) { +NL_SET_ERR_MSG (extack,"Invalid route type" ); err = -EINVAL ; goto errout; }
@@ -726,6 +727,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, tb =fib_get_table (net, cfg.fc_table);if (!tb) { +NL_SET_ERR_MSG (extack,"FIB table does not exist" ); err = -ESRCH ; goto errout; }
net/ipv4/fib_semantics.c +93 -22
246 lines not on this page · raw message
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH 3/4 net: ipv6: Plumb extack through route add functions
In reply to David AhernPlumb extack argument down to route add functions.
--- include/net/ip6_fib.h | 3 ++- include/net/ip6_route.h | 2 +- net/ipv6/addrconf.c | 4 ++-- net/ipv6/ip6_fib.c | 14 +++++++----- net/ipv6/route.c | 57 +++++++++++++++++++++++++++---------------------- 5 files changed, 46 insertions(+), 34 deletions(-)
include/net/ip6_fib.h +2 -1
@@ -277,7 +277,8 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg), void *arg);int fib6_add (struct fib6_node *root,struct rt6_info *rt, -struct nl_info *info,struct mx6_config *mxc); +struct nl_info *info,struct mx6_config *mxc, +struct netlink_ext_ack *extack);int fib6_del (struct rt6_info *rt,struct nl_info *info); void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
include/net/ip6_route.h +1 -1
@@ -90,7 +90,7 @@ void ip6_route_cleanup(void);int ipv6_route_ioctl (struct net *net,unsigned int cmd,void __user *arg); -int ip6_route_add (struct fib6_config *cfg); +int ip6_route_add (struct fib6_config *cfg,struct netlink_ext_ack *extack);int ip6_ins_rt (struct rt6_info *);int ip6_del_rt (struct rt6_info *);
net/ipv6/addrconf.c +2 -2
@@ -2280,7 +2280,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, cfg.fc_flags |=RTF_NONEXTHOP ;#endif -ip6_route_add (&cfg); +ip6_route_add (&cfg,NULL ); }
@@ -2335,7 +2335,7 @@ static void addrconf_add_mroute(struct net_device *dev)ipv6_addr_set (&cfg.fc_dst,htonl (0xFF000000 ),0 ,0 ,0 ); -ip6_route_add (&cfg); +ip6_route_add (&cfg,NULL ); }static struct inet6_dev *addrconf_add_dev (struct net_device *dev)
net/ipv6/ip6_fib.c +9 -5
@@ -473,7 +473,8 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)static struct fib6_node *fib6_add_1 (struct fib6_node *root,struct in6_addr *addr,int plen,int offset,int allow_create, -int replace_required,int sernum) +int replace_required,int sernum, +struct netlink_ext_ack *extack) {struct fib6_node *fn, *in, *ln;struct fib6_node *pn =NULL ;
@@ -964,7 +965,8 @@ void fib6_force_start_gc(struct net *net)*/ int fib6_add (struct fib6_node *root,struct rt6_info *rt, -struct nl_info *info,struct mx6_config *mxc) +struct nl_info *info,struct mx6_config *mxc, +struct netlink_ext_ack *extack) {struct fib6_node *fn, *pn =NULL ;int err = -ENOMEM ;
@@ -987,7 +989,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, fn =fib6_add_1 (root, &rt->rt6i_dst.addr, rt->rt6i_dst.plen, offsetof(struct rt6_info , rt6i_dst), allow_create, - replace_required, sernum); + replace_required, sernum, extack);if (IS_ERR (fn)) { err =PTR_ERR (fn); fn =NULL ;
@@ -1028,7 +1030,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, sn =fib6_add_1 (sfn, &rt->rt6i_src.addr, rt->rt6i_src.plen, offsetof(struct rt6_info , rt6i_src), - allow_create, replace_required, sernum); + allow_create, replace_required, sernum, + extack);if (IS_ERR (sn)) {/* If it is failed, discard just allocated
@@ -1047,7 +1050,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, sn =fib6_add_1 (fn->subtree, &rt->rt6i_src.addr, rt->rt6i_src.plen, offsetof(struct rt6_info , rt6i_src), - allow_create, replace_required, sernum); + allow_create, replace_required, sernum, + extack);if (IS_ERR (sn)) { err =PTR_ERR (sn);
net/ipv6/route.c +32 -25
189 lines not on this page · raw message
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH 4/4 net: ipv6: Add extack messages for route add failures
In reply to David AhernAdd messages for non-obvious errors (e.g, no need to add text for malloc failures or ENODEV failures). This mostly covers the annoying EINVAL errors Some message strings violate the 80-columns but searchable strings need to trump that rule.
--- net/ipv6/ip6_fib.c | 4 ++++ net/ipv6/route.c | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-)
net/ipv6/ip6_fib.c +4 -0
@@ -498,6 +498,8 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root, !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) {if (!allow_create) {if (replace_required) { +NL_SET_ERR_MSG (extack, +"Can not replace route - no match found" );pr_warn ("Can't replace route, no match found\n" );return ERR_PTR (-ENOENT ); }
@@ -544,6 +546,8 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root,* That would keep IPv6 consistent with IPv4 */ if (replace_required) { +NL_SET_ERR_MSG (extack, +"Can not replace route - no match found" );pr_warn ("Can't replace route, no match found\n" );return ERR_PTR (-ENOENT ); }
net/ipv6/route.c +32 -8
@@ -1857,14 +1857,25 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,int err = -EINVAL ;/* RTF_PCPU is an internal flag; can not be set by userspace */ -if (cfg->fc_flags &RTF_PCPU ) +if (cfg->fc_flags &RTF_PCPU ) { +NL_SET_ERR_MSG (extack,"Userspace can not set RTF_PCPU" ); goto out; + } -if (cfg->fc_dst_len >128 || cfg->fc_src_len >128 ) +if (cfg->fc_dst_len >128 ) { +NL_SET_ERR_MSG (extack,"Invalid prefix length" ); + goto out; + } +if (cfg->fc_src_len >128 ) { +NL_SET_ERR_MSG (extack,"Invalid source address length" ); goto out; + }#ifndef CONFIG_IPV6_SUBTREES -if (cfg->fc_src_len) +if (cfg->fc_src_len) { +NL_SET_ERR_MSG (extack, +"Specifying source address requires IPV6_SUBTREES to be enabled" ); goto out; + }#endif if (cfg->fc_ifindex) { err = -ENODEV ;
@@ -2015,9 +2026,10 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, err = -EINVAL ;if (ipv6_chk_addr_and_flags (net, gw_addr, gwa_type &IPV6_ADDR_LINKLOCAL ? - dev :NULL ,0 ,0 )) + dev :NULL ,0 ,0 )) { +NL_SET_ERR_MSG (extack,"Invalid gateway address" ); goto out; - + } rt->rt6i_gateway = *gw_addr;if (gwa_type != (IPV6_ADDR_LINKLOCAL |IPV6_ADDR_UNICAST )) {
@@ -2033,8 +2045,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,addressing */ if (!(gwa_type & (IPV6_ADDR_UNICAST | -IPV6_ADDR_MAPPED ))) +IPV6_ADDR_MAPPED ))) { +NL_SET_ERR_MSG (extack, +"Invalid gateway address" ); goto out; + }if (cfg->fc_table) { grt =ip6_nh_lookup_table (net, cfg, gw_addr);
@@ -2074,8 +2089,14 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, goto out; } err = -EINVAL ; -if (!dev || (dev->flags &IFF_LOOPBACK )) +if (!dev) { +NL_SET_ERR_MSG (extack,"Egress device not specified" ); + goto out; + }else if (dev->flags &IFF_LOOPBACK ) { +NL_SET_ERR_MSG (extack, +"Egress device can not be loopback device for this route" ); goto out; + } } err = -ENODEV ;
@@ -2084,6 +2105,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,if (!ipv6_addr_any (&cfg->fc_prefsrc)) {if (!ipv6_chk_addr (net, &cfg->fc_prefsrc, dev,0 )) { +NL_SET_ERR_MSG (extack,"Invalid source address" ); err = -EINVAL ; goto out; }
@@ -2234,8 +2256,10 @@ static int ip6_route_del(struct fib6_config *cfg,int err = -ESRCH ; table =fib6_get_table (cfg->fc_nlinfo.nl_net, cfg->fc_table); -if (!table) +if (!table) { +NL_SET_ERR_MSG (extack,"FIB table does not exist" );return err; + }read_lock_bh (&table->tb6_lock);
Signature · 1 line
2.11.0 (Apple Git-81)
David Miller
maintainerFrom: David Ahern <[email protected]>
Date: Sun, 21 May 2017 10:12:01 -0600
Quoted 2 lines
Use the extack feature to improve error messages to user on route add and delete failures.
Looks good, series applied.
Thanks.