]> git.itanic.dy.fi Git - linux-stable/commitdiff
IPv4: add extack info for IPv4 address add/delete
authorHangbin Liu <liuhangbin@gmail.com>
Fri, 18 Aug 2023 08:25:23 +0000 (16:25 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 21 Aug 2023 06:35:59 +0000 (07:35 +0100)
Add extack info for IPv4 address add/delete, which would be useful for
users to understand the problem without having to read kernel code.

No extack message for the ifa_local checking in __inet_insert_ifa() as
it has been checked in find_matching_ifa().

Suggested-by: Ido Schimmel <idosch@idosch.org>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/devinet.c

index 5deac0517ef708f92e4f0540f174931117b3f1ca..c3658b8755bca5ea08e8b8f1fc08709dbc24d221 100644 (file)
@@ -509,6 +509,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
                                return -EEXIST;
                        }
                        if (ifa1->ifa_scope != ifa->ifa_scope) {
+                               NL_SET_ERR_MSG(extack, "ipv4: Invalid scope value");
                                inet_free_ifa(ifa);
                                return -EINVAL;
                        }
@@ -664,6 +665,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
        ifm = nlmsg_data(nlh);
        in_dev = inetdev_by_index(net, ifm->ifa_index);
        if (!in_dev) {
+               NL_SET_ERR_MSG(extack, "ipv4: Device not found");
                err = -ENODEV;
                goto errout;
        }
@@ -688,6 +690,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
                return 0;
        }
 
+       NL_SET_ERR_MSG(extack, "ipv4: Address not found");
        err = -EADDRNOTAVAIL;
 errout:
        return err;
@@ -839,13 +842,23 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
 
        ifm = nlmsg_data(nlh);
        err = -EINVAL;
-       if (ifm->ifa_prefixlen > 32 || !tb[IFA_LOCAL])
+
+       if (ifm->ifa_prefixlen > 32) {
+               NL_SET_ERR_MSG(extack, "ipv4: Invalid prefix length");
+               goto errout;
+       }
+
+       if (!tb[IFA_LOCAL]) {
+               NL_SET_ERR_MSG(extack, "ipv4: Local address is not supplied");
                goto errout;
+       }
 
        dev = __dev_get_by_index(net, ifm->ifa_index);
        err = -ENODEV;
-       if (!dev)
+       if (!dev) {
+               NL_SET_ERR_MSG(extack, "ipv4: Device not found");
                goto errout;
+       }
 
        in_dev = __in_dev_get_rtnl(dev);
        err = -ENOBUFS;
@@ -897,6 +910,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
 
                ci = nla_data(tb[IFA_CACHEINFO]);
                if (!ci->ifa_valid || ci->ifa_prefered > ci->ifa_valid) {
+                       NL_SET_ERR_MSG(extack, "ipv4: address lifetime invalid");
                        err = -EINVAL;
                        goto errout_free;
                }
@@ -954,6 +968,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
                        int ret = ip_mc_autojoin_config(net, true, ifa);
 
                        if (ret < 0) {
+                               NL_SET_ERR_MSG(extack, "ipv4: Multicast auto join failed");
                                inet_free_ifa(ifa);
                                return ret;
                        }
@@ -967,8 +982,10 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
                inet_free_ifa(ifa);
 
                if (nlh->nlmsg_flags & NLM_F_EXCL ||
-                   !(nlh->nlmsg_flags & NLM_F_REPLACE))
+                   !(nlh->nlmsg_flags & NLM_F_REPLACE)) {
+                       NL_SET_ERR_MSG(extack, "ipv4: Address already assigned");
                        return -EEXIST;
+               }
                ifa = ifa_existing;
 
                if (ifa->ifa_rt_priority != new_metric) {