diff options
author | David Ahern <dsahern@gmail.com> | 2017-05-28 01:19:26 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-30 18:55:31 +0300 |
commit | 78055998954b7a3e6c31eb24d1d26f0b63a7ec0d (patch) | |
tree | ad1f4fd34da0b9faee5219a3490cbf729228ba96 | |
parent | ba277e8e05dbd4aa13f74f859e276d5d54467eab (diff) | |
download | linux-78055998954b7a3e6c31eb24d1d26f0b63a7ec0d.tar.xz |
net: ipv4: Add extack message for invalid prefix or length
Add extack error message for invalid prefix length and invalid prefix.
Example of the latter is a route spec containing 172.16.100.1/24, where
the /24 mask means the lower 8-bits should be 0. Amazing how easy that
one is to overlook when an EINVAL is returned.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/ip_fib.h | 3 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 7 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 17 |
3 files changed, 17 insertions, 10 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index dcbfd5dfd25e..3dbfd5e6a347 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -266,7 +266,8 @@ 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 *, struct netlink_ext_ack *extack); -int fib_table_delete(struct net *, struct fib_table *, struct fib_config *); +int fib_table_delete(struct net *, struct fib_table *, struct fib_config *, + struct netlink_ext_ack *extack); int fib_table_dump(struct fib_table *table, struct sk_buff *skb, struct netlink_callback *cb); int fib_table_flush(struct net *net, struct fib_table *table); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 14d2f7bd7c76..715b7967d8ea 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -588,7 +588,8 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) if (cmd == SIOCDELRT) { tb = fib_get_table(net, cfg.fc_table); if (tb) - err = fib_table_delete(net, tb, &cfg); + err = fib_table_delete(net, tb, &cfg, + NULL); else err = -ESRCH; } else { @@ -732,7 +733,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, goto errout; } - err = fib_table_delete(net, tb, &cfg); + err = fib_table_delete(net, tb, &cfg, extack); errout: return err; } @@ -851,7 +852,7 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad if (cmd == RTM_NEWROUTE) fib_table_insert(net, tb, &cfg, NULL); else - fib_table_delete(net, tb, &cfg); + fib_table_delete(net, tb, &cfg, NULL); } void fib_add_ifaddr(struct in_ifaddr *ifa) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 9bd46e1e1037..a624d380c81d 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1099,13 +1099,18 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp, return 0; } -static bool fib_valid_key_len(u32 key, u8 plen) +static bool fib_valid_key_len(u32 key, u8 plen, struct netlink_ext_ack *extack) { - if (plen > KEYLENGTH) + if (plen > KEYLENGTH) { + NL_SET_ERR_MSG(extack, "Invalid prefix length"); return false; + } - if ((plen < KEYLENGTH) && (key << plen)) + if ((plen < KEYLENGTH) && (key << plen)) { + NL_SET_ERR_MSG(extack, + "Invalid prefix for given prefix length"); return false; + } return true; } @@ -1128,7 +1133,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, key = ntohl(cfg->fc_dst); - if (!fib_valid_key_len(key, plen)) + if (!fib_valid_key_len(key, plen, extack)) return -EINVAL; pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); @@ -1516,7 +1521,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, /* Caller must hold RTNL. */ int fib_table_delete(struct net *net, struct fib_table *tb, - struct fib_config *cfg) + struct fib_config *cfg, struct netlink_ext_ack *extack) { struct trie *t = (struct trie *) tb->tb_data; struct fib_alias *fa, *fa_to_delete; @@ -1528,7 +1533,7 @@ int fib_table_delete(struct net *net, struct fib_table *tb, key = ntohl(cfg->fc_dst); - if (!fib_valid_key_len(key, plen)) + if (!fib_valid_key_len(key, plen, extack)) return -EINVAL; l = fib_find_node(t, &tp, key); |