[Devel] [PATCH VZ9] ipv4: fib_semantics: omit excess rtm_flags

Alexander Mikhalitsyn alexander.mikhalitsyn at virtuozzo.com
Fri Jun 10 13:19:59 MSK 2022


During ip route save we may get flags
RTNH_F_DEAD and RTNH_F_LINKDOWN in final dump image.
But we can't set these flags back during restore, because
these flags calculated dynamically in the kernel. It's
an inconsistency between NLM_F_DUMP and NLM_F_CREATE.

It's fully safe to workaround it just by ignoring such flags
in the kernel during RTM_NEWROUTE request processing.

Later, once my patches will be merged to mainstream we
can drop this commit.

Reproducer:
$ ip link add type veth
$ ip addr add 10.0.0.1/24 dev veth0
$ ip link set veth0 up
$ ip route add default via 10.0.0.1
$ ip route save > route_dump
$ ip route restore < route_dump
Error: Invalid rtm_flags - can not contain DEAD or LINKDOWN.

Reference:
[RFC PATCH net-next] rtnetlink: add RTNH_F_REJECT_MASK
[RFC PATCH iproute2] ip route: save: exclude rtnh_flags which can't be set
https://lore.kernel.org/netdev/20211111160240.739294-1-alexander.mikhalitsyn@virtuozzo.com/T/#t

https://jira.sw.ru/browse/PSBM-135303
https://jira.sw.ru/browse/PSBM-140280

Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
---
 net/ipv4/fib_semantics.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e20c16aad81a..c200a2643ef4 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -683,11 +683,24 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
 			return -EINVAL;
 		}
 
+#if 0
 		if (rtnh->rtnh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN)) {
 			NL_SET_ERR_MSG(extack,
 				       "Invalid flags for nexthop - can not contain DEAD or LINKDOWN");
 			return -EINVAL;
 		}
+#else
+		/* We just want to workaround inconsistency between dump and restore.
+		 * During dump the userspace requests:
+		 * nlmsg_type=RTM_GETROUTE, nlmsg_flags=NLM_F_REQUEST|NLM_F_DUMP
+		 * it may get RTNH_F_DEAD and RTNH_F_LINKDOWN bits set on rtnh_flags.
+		 * But during the restore process:
+		 * nlmsg_type=RTM_NEWROUTE, nlmsg_flags=NLM_F_REQUEST|..|NLM_F_CREATE
+		 * the userspace can't set this flags back. It's obvious inconsistency,
+		 * let's temporarily workaround it just by ignoring excess flags.
+		 */
+		rtnh->rtnh_flags &= ~(RTNH_F_DEAD | RTNH_F_LINKDOWN);
+#endif
 
 		fib_cfg.fc_flags = (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
 		fib_cfg.fc_oif = rtnh->rtnh_ifindex;
@@ -1361,11 +1374,15 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
 		goto err_inval;
 	}
 
+#if 0
 	if (cfg->fc_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN)) {
 		NL_SET_ERR_MSG(extack,
 			       "Invalid rtm_flags - can not contain DEAD or LINKDOWN");
 		goto err_inval;
 	}
+#else
+	cfg->fc_flags &= ~(RTNH_F_DEAD | RTNH_F_LINKDOWN);
+#endif
 
 	if (cfg->fc_nh_id) {
 		if (!cfg->fc_mx) {
-- 
2.36.1



More information about the Devel mailing list