Merge branch 'idr-4.11' of git://git.infradead.org/users/willy/linux-dax
[linux-2.6-microblaze.git] / net / ipv6 / ip6_fib.c
index ef54852..e426674 100644 (file)
@@ -318,6 +318,16 @@ static int fib6_dump_node(struct fib6_walker *w)
                        w->leaf = rt;
                        return 1;
                }
+
+               /* Multipath routes are dumped in one route with the
+                * RTA_MULTIPATH attribute. Jump 'rt' to point to the
+                * last sibling of this route (no need to dump the
+                * sibling routes again)
+                */
+               if (rt->rt6i_nsiblings)
+                       rt = list_last_entry(&rt->rt6i_siblings,
+                                            struct rt6_info,
+                                            rt6i_siblings);
        }
        w->leaf = NULL;
        return 0;
@@ -746,6 +756,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
        u16 nlflags = NLM_F_EXCL;
        int err;
 
+       if (info->nlh && (info->nlh->nlmsg_flags & NLM_F_APPEND))
+               nlflags |= NLM_F_APPEND;
+
        ins = &fn->leaf;
 
        for (iter = fn->leaf; iter; iter = iter->dst.rt6_next) {
@@ -868,7 +881,8 @@ add:
                *ins = rt;
                rt->rt6i_node = fn;
                atomic_inc(&rt->rt6i_ref);
-               inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
+               if (!info->skip_notify)
+                       inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
                info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
 
                if (!(fn->fn_flags & RTN_RTINFO)) {
@@ -894,7 +908,8 @@ add:
                rt->rt6i_node = fn;
                rt->dst.rt6_next = iter->dst.rt6_next;
                atomic_inc(&rt->rt6i_ref);
-               inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE);
+               if (!info->skip_notify)
+                       inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE);
                if (!(fn->fn_flags & RTN_RTINFO)) {
                        info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
                        fn->fn_flags |= RTN_RTINFO;
@@ -1439,7 +1454,8 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
 
        fib6_purge_rt(rt, fn, net);
 
-       inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
+       if (!info->skip_notify)
+               inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
        rt6_release(rt);
 }