Commit 6324d0fa authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

ipv4: Replace route in list before notifying

Subsequent patches will add an offload / trap indication to routes which
will signal if the route is present in hardware or not.

After programming the route to the hardware, drivers will have to ask
the IPv4 code to set the flags by passing the route's key.

In the case of route replace, the new route is notified before it is
actually inserted into the FIB alias list. This can prevent simple
drivers (e.g., netdevsim) that program the route to the hardware in the
same context it is notified in from being able to set the flag.

Solve this by first inserting the new route to the list and rollback the
operation in case the route was vetoed.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0fadc0a2
...@@ -1221,23 +1221,26 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1221,23 +1221,26 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
new_fa->tb_id = tb->tb_id; new_fa->tb_id = tb->tb_id;
new_fa->fa_default = -1; new_fa->fa_default = -1;
hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list);
if (fib_find_alias(&l->leaf, fa->fa_slen, 0, 0, if (fib_find_alias(&l->leaf, fa->fa_slen, 0, 0,
tb->tb_id, true) == fa) { tb->tb_id, true) == new_fa) {
enum fib_event_type fib_event; enum fib_event_type fib_event;
fib_event = FIB_EVENT_ENTRY_REPLACE; fib_event = FIB_EVENT_ENTRY_REPLACE;
err = call_fib_entry_notifiers(net, fib_event, err = call_fib_entry_notifiers(net, fib_event,
key, plen, key, plen,
new_fa, extack); new_fa, extack);
if (err) if (err) {
hlist_replace_rcu(&new_fa->fa_list,
&fa->fa_list);
goto out_free_new_fa; goto out_free_new_fa;
} }
}
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
tb->tb_id, &cfg->fc_nlinfo, nlflags); tb->tb_id, &cfg->fc_nlinfo, nlflags);
hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list);
alias_free_mem_rcu(fa); alias_free_mem_rcu(fa);
fib_release_info(fi_drop); fib_release_info(fi_drop);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment