]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/ipv4/fib_frontend.c
net: ipv4: Plumb extack through route add functions
[mirror_ubuntu-bionic-kernel.git] / net / ipv4 / fib_frontend.c
index 39bd1edee67649af86eb582c0ea478713360a506..511edff76c018173dd02229a669defbdec98fc52 100644 (file)
@@ -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;
 }
@@ -763,7 +765,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
        unsigned int e = 0, s_e;
        struct fib_table *tb;
        struct hlist_head *head;
-       int dumped = 0;
+       int dumped = 0, err;
 
        if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
            ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED)
@@ -783,20 +785,27 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
                        if (dumped)
                                memset(&cb->args[2], 0, sizeof(cb->args) -
                                                 2 * sizeof(cb->args[0]));
-                       if (fib_table_dump(tb, skb, cb) < 0)
-                               goto out;
+                       err = fib_table_dump(tb, skb, cb);
+                       if (err < 0) {
+                               if (likely(skb->len))
+                                       goto out;
+
+                               goto out_err;
+                       }
                        dumped = 1;
 next:
                        e++;
                }
        }
 out:
+       err = skb->len;
+out_err:
        rcu_read_unlock();
 
        cb->args[1] = e;
        cb->args[0] = h;
 
-       return skb->len;
+       return err;
 }
 
 /* Prepare and feed intra-kernel routing request.
@@ -838,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);
 }