From 72261ecd22495d23ce80a699bb799694981fffe8 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 7 Feb 2019 14:55:06 +0100 Subject: [PATCH 1/2] lib: interface handling where zebra not yet ready other daemons need to sync with zebra to get to know which vrf backend is available. in that time, there may be interface configuration available. in that specific case, the vrf backend returned is not known. A specific return value is sent back. This will be useful to know which specific algorithm to apply. Signed-off-by: Philippe Guibert --- lib/if.c | 1 + lib/vrf.c | 4 ++++ lib/vrf.h | 5 +++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/if.c b/lib/if.c index 0fd65da03a..6ae75939e7 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1281,6 +1281,7 @@ static int lib_interface_create(enum nb_event event, vrf->name); return NB_ERR_VALIDATION; } + if (vrf_get_backend() == VRF_BACKEND_VRF_LITE) { ifp = if_lookup_by_name_all_vrf(ifname); if (ifp && ifp->vrf_id != vrf->vrf_id) { diff --git a/lib/vrf.c b/lib/vrf.c index f9f14822cb..c0dd7f5cf7 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -56,6 +56,7 @@ struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id); struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name); static int vrf_backend; +static int vrf_backend_configured; static struct zebra_privs_t *vrf_daemon_privs; static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL; @@ -613,12 +614,15 @@ int vrf_is_backend_netns(void) int vrf_get_backend(void) { + if (!vrf_backend_configured) + return VRF_BACKEND_UNKNOWN; return vrf_backend; } void vrf_configure_backend(int vrf_backend_netns) { vrf_backend = vrf_backend_netns; + vrf_backend_configured = 1; } int vrf_handler_create(struct vty *vty, const char *vrfname, diff --git a/lib/vrf.h b/lib/vrf.h index e80796f480..1a850f218f 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -97,8 +97,9 @@ RB_PROTOTYPE(vrf_name_head, vrf, name_entry, vrf_name_compare) DECLARE_QOBJ_TYPE(vrf) /* Allow VRF with netns as backend */ -#define VRF_BACKEND_VRF_LITE 0 -#define VRF_BACKEND_NETNS 1 +#define VRF_BACKEND_VRF_LITE 0 +#define VRF_BACKEND_NETNS 1 +#define VRF_BACKEND_UNKNOWN 2 extern struct vrf_id_head vrfs_by_id; extern struct vrf_name_head vrfs_by_name; From b0b97a7f6103202884311ae52c7bac202c83d24e Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 11 Feb 2019 13:48:12 +0100 Subject: [PATCH 2/2] lib: handling vrf backend unknown case on interface search algorithm, at initialisation, when reading config file, the vrf backend may not be yet known ( because zebra did not sync yet with daemon). For that, avoid searching interface name in a separate vrf. This change of behaviour is induced because the assumption is done that at config startup, the user is not wrong with the interface configuration to use. Every usage of vrf_get_backend() should then be wisely adapted in order to handle that init state. Signed-off-by: Philippe Guibert --- lib/if.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/if.c b/lib/if.c index 6ae75939e7..910a38d4cb 100644 --- a/lib/if.c +++ b/lib/if.c @@ -397,6 +397,7 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id) struct interface *ifp; switch (vrf_get_backend()) { + case VRF_BACKEND_UNKNOWN: case VRF_BACKEND_NETNS: ifp = if_lookup_by_name(name, vrf_id); if (ifp) @@ -1282,6 +1283,10 @@ static int lib_interface_create(enum nb_event event, return NB_ERR_VALIDATION; } + /* if VRF is netns or not yet known - init for instance + * then assumption is that passed config is exact + * then the user intent was not to use an other iface + */ if (vrf_get_backend() == VRF_BACKEND_VRF_LITE) { ifp = if_lookup_by_name_all_vrf(ifname); if (ifp && ifp->vrf_id != vrf->vrf_id) {