Netlink: Restrict route replace for IPv6
Seems like the previous patch was too optimistic, as route replace is still broken even in Linux 4.19 LTS (but fixed in Linux 5.10 LTS) for: ip route add 2001:db8::/32 via fe80::1 dev eth0 ip route replace 2001:db8::/32 dev eth0 It ends with two routes instead of just the second. The issue is limited to direct and special type (e.g. unreachable) routes, the patch restricts route replace for cases when the new route is a regular route (with a next hop address).
This commit is contained in:
parent
722daa9500
commit
ddb1bdf281
1 changed files with 27 additions and 1 deletions
|
@ -1459,12 +1459,38 @@ done:
|
||||||
return nl_exchange(&r->h, (op == NL_OP_DELETE));
|
return nl_exchange(&r->h, (op == NL_OP_DELETE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
nl_allow_replace(struct krt_proto *p, rte *new)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We use NL_OP_REPLACE for IPv4, it has an issue with not checking for
|
||||||
|
* matching rtm_protocol, but that is OK when dedicated priority is used.
|
||||||
|
*
|
||||||
|
* For IPv6, the NL_OP_REPLACE is still broken even in Linux 4.19 LTS
|
||||||
|
* (although it seems to be fixed in Linux 5.10 LTS) for sequence:
|
||||||
|
*
|
||||||
|
* ip route add 2001:db8::/32 via fe80::1 dev eth0
|
||||||
|
* ip route replace 2001:db8::/32 dev eth0
|
||||||
|
*
|
||||||
|
* (it ends with two routes instead of replacing the first by the second one)
|
||||||
|
*
|
||||||
|
* Replacing with direct and special type (e.g. unreachable) routes does not
|
||||||
|
* work, but replacing with regular routes work reliably
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (krt_ipv4(p))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
rta *a = new->attrs;
|
||||||
|
return (a->dest == RTD_UNICAST) && ipa_nonzero(a->nh.gw);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
krt_replace_rte(struct krt_proto *p, net *n UNUSED, rte *new, rte *old)
|
krt_replace_rte(struct krt_proto *p, net *n UNUSED, rte *new, rte *old)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (old && new)
|
if (old && new && nl_allow_replace(p, new))
|
||||||
{
|
{
|
||||||
err = nl_send_route(p, new, NL_OP_REPLACE);
|
err = nl_send_route(p, new, NL_OP_REPLACE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue