From af6b1458f852dc164206dc2fc45467ade6a7f7ae Mon Sep 17 00:00:00 2001 From: Gris Ge Date: Wed, 9 Feb 2022 23:33:40 +0800 Subject: [PATCH] python route: Add support of multipath route Supporting the rout created by below command: sudo ip -6 route add 2001:db8:e::/64 proto static \ nexthop via 2001:db8:f::254 dev eth1 weight 1 onlink \ nexthop via 2001:db8:f::253 dev eth1 weight 256 onlink Integration test case included. Signed-off-by: Gris Ge --- libnmstate/nispor/route.py | 53 ++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/libnmstate/nispor/route.py b/libnmstate/nispor/route.py index 9852ba51..87543de2 100644 --- a/libnmstate/nispor/route.py +++ b/libnmstate/nispor/route.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2020 Red Hat, Inc. +# Copyright (c) 2020-2022 Red Hat, Inc. # # This file is part of nmstate # @@ -17,6 +17,8 @@ # along with this program. If not, see . # +from copy import deepcopy + from libnmstate.schema import Route @@ -30,24 +32,24 @@ LOCAL_ROUTE_TABLE = 255 def nispor_route_state_to_nmstate(np_routes): - return [ - _nispor_route_to_nmstate(rt) - for rt in np_routes - if rt.scope in ["universe", "link"] - and rt.oif != "lo" - and rt.table != LOCAL_ROUTE_TABLE - ] + ret = [] + for np_route in np_routes: + if np_route.oif != "lo" and np_route.table != LOCAL_ROUTE_TABLE: + ret.extend(_nispor_route_to_nmstate(np_route)) + return ret def nispor_route_state_to_nmstate_static(np_routes): - return [ - _nispor_route_to_nmstate(rt) - for rt in np_routes - if rt.scope in ["universe", "link"] - and rt.protocol not in ["kernel", "ra", "dhcp"] - and rt.oif != "lo" - and rt.table != LOCAL_ROUTE_TABLE - ] + ret = [] + for np_route in np_routes: + if ( + np_route.oif != "lo" + and np_route.table != LOCAL_ROUTE_TABLE + and np_route.scope in ["universe", "link"] + and np_route.protocol in ["static", "boot"] + ): + ret.extend(_nispor_route_to_nmstate(np_route)) + return ret def _nispor_route_to_nmstate(np_rt): @@ -71,10 +73,27 @@ def _nispor_route_to_nmstate(np_rt): else IPV4_EMPTY_NEXT_HOP_ADDRESS ) - return { + nm_route = { Route.TABLE_ID: np_rt.table, Route.DESTINATION: destination, Route.NEXT_HOP_INTERFACE: np_rt.oif if np_rt.oif else "", Route.NEXT_HOP_ADDRESS: next_hop, Route.METRIC: np_rt.metric if np_rt.metric else 0, } + np_mp_rts = get_multipath_routes(np_rt) + if np_mp_rts: + ret = [] + for np_mp_rt in np_mp_rts: + nm_route_clone = deepcopy(nm_route) + nm_route_clone[Route.NEXT_HOP_INTERFACE] = np_mp_rt["iface"] + nm_route_clone[Route.NEXT_HOP_ADDRESS] = np_mp_rt["via"] + ret.append(nm_route_clone) + return ret + else: + return [nm_route] + + +# Instead of bumping nispor dependency version, we just use nispor private +# property temporarily +def get_multipath_routes(np_route): + return np_route._info.get("multipath") -- 2.27.0