mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
Merge branch 'newroute-creation-flags'
Guillaume Nault says: ==================== ip: fix creation flags reported in RTM_NEWROUTE events Netlink messages sent to user-space upon RTM_NEWROUTE events have their nlmsg_flags field inconsistently set. While the NLM_F_REPLACE and NLM_F_APPEND bits are correctly handled, NLM_F_CREATE and NLM_F_EXCL are always 0. This series sets the NLM_F_CREATE and NLM_F_EXCL bits when applicable, for IPv4 and IPv6. Since IPv6 ignores the NLM_F_APPEND flags in requests, this flag isn't reported in RTM_NEWROUTE IPv6 events. This keeps IPv6 internal consistency (same flag semantic for user requests and kernel events) at the cost of bringing different flag interpretation for IPv4 and IPv6. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a349fcc85f
@ -1081,7 +1081,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
struct trie *t = (struct trie *)tb->tb_data;
|
||||
struct fib_alias *fa, *new_fa;
|
||||
struct key_vector *l, *tp;
|
||||
unsigned int nlflags = 0;
|
||||
u16 nlflags = NLM_F_EXCL;
|
||||
struct fib_info *fi;
|
||||
u8 plen = cfg->fc_dst_len;
|
||||
u8 slen = KEYLENGTH - plen;
|
||||
@ -1126,6 +1126,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
if (cfg->fc_nlflags & NLM_F_EXCL)
|
||||
goto out;
|
||||
|
||||
nlflags &= ~NLM_F_EXCL;
|
||||
|
||||
/* We have 2 goals:
|
||||
* 1. Find exact match for type, scope, fib_info to avoid
|
||||
* duplicate routes
|
||||
@ -1151,6 +1153,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
struct fib_info *fi_drop;
|
||||
u8 state;
|
||||
|
||||
nlflags |= NLM_F_REPLACE;
|
||||
fa = fa_first;
|
||||
if (fa_match) {
|
||||
if (fa == fa_match)
|
||||
@ -1191,7 +1194,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
if (state & FA_S_ACCESSED)
|
||||
rt_cache_flush(cfg->fc_nlinfo.nl_net);
|
||||
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
|
||||
tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
|
||||
tb->tb_id, &cfg->fc_nlinfo, nlflags);
|
||||
|
||||
goto succeeded;
|
||||
}
|
||||
@ -1203,7 +1206,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
goto out;
|
||||
|
||||
if (cfg->fc_nlflags & NLM_F_APPEND)
|
||||
nlflags = NLM_F_APPEND;
|
||||
nlflags |= NLM_F_APPEND;
|
||||
else
|
||||
fa = fa_first;
|
||||
}
|
||||
@ -1211,6 +1214,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
|
||||
if (!(cfg->fc_nlflags & NLM_F_CREATE))
|
||||
goto out;
|
||||
|
||||
nlflags |= NLM_F_CREATE;
|
||||
err = -ENOBUFS;
|
||||
new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
|
||||
if (!new_fa)
|
||||
|
@ -743,6 +743,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||
(info->nlh->nlmsg_flags & NLM_F_CREATE));
|
||||
int found = 0;
|
||||
bool rt_can_ecmp = rt6_qualify_for_ecmp(rt);
|
||||
u16 nlflags = NLM_F_EXCL;
|
||||
int err;
|
||||
|
||||
ins = &fn->leaf;
|
||||
@ -759,6 +760,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||
if (info->nlh &&
|
||||
(info->nlh->nlmsg_flags & NLM_F_EXCL))
|
||||
return -EEXIST;
|
||||
|
||||
nlflags &= ~NLM_F_EXCL;
|
||||
if (replace) {
|
||||
if (rt_can_ecmp == rt6_qualify_for_ecmp(iter)) {
|
||||
found++;
|
||||
@ -856,6 +859,7 @@ next_iter:
|
||||
pr_warn("NLM_F_CREATE should be set when creating new route\n");
|
||||
|
||||
add:
|
||||
nlflags |= NLM_F_CREATE;
|
||||
err = fib6_commit_metrics(&rt->dst, mxc);
|
||||
if (err)
|
||||
return err;
|
||||
@ -864,7 +868,7 @@ add:
|
||||
*ins = rt;
|
||||
rt->rt6i_node = fn;
|
||||
atomic_inc(&rt->rt6i_ref);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, 0);
|
||||
inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags);
|
||||
info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
|
||||
|
||||
if (!(fn->fn_flags & RTN_RTINFO)) {
|
||||
|
Loading…
Reference in New Issue
Block a user