diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2019-02-11 16:05:39 +0100 |
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2019-06-12 08:37:58 +0200 |
| commit | ac6c2a11a659a00360700f352c0fbd47c133dfea (patch) | |
| tree | 8f5d801d5bf920158c3330a2d3a533aeb058fcb7 /lib/if.c | |
| parent | f11e98eca3c4b4e3c91c826329018e848bcb9fc6 (diff) | |
lib: create interface upon accessing interface NB API.
Upon accessing interface NB API, the interface is created, if the vrf
is available. the commit does not change the behaviour, since at this
commit, this is not yet possible to have vrf contexts, while zebra did
not connect to daemons. However, that commit adds some work, so that it
will be possible to work on a vrf context, without having the vrf_id
completely resolved. for instance, if we suppose a vrf is created by
command 'vrf TOTO' in the starting configuration of a daemon, then 'interface
TITI vrf TOTO' will permit to create interface TITI within vrf TOTO.
the macro VRF_GET_INSTANCE will return the vrf context, if available or
not.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'lib/if.c')
| -rw-r--r-- | lib/if.c | 34 |
1 files changed, 20 insertions, 14 deletions
@@ -1125,8 +1125,7 @@ DEFPY_NOSH (interface, VRF_CMD_HELP_STR) { char xpath_list[XPATH_MAXLEN]; - vrf_id_t vrf_id; - struct interface *ifp; + struct interface *ifp = NULL; int ret; struct vrf *vrf; @@ -1140,14 +1139,24 @@ DEFPY_NOSH (interface, * interface is found, then a new one should be created on the default * VRF. */ - VRF_GET_ID(vrf_id, vrfname, false); - ifp = if_lookup_by_name_all_vrf(ifname); - if (ifp && ifp->vrf_id != vrf_id) { + VRF_GET_INSTANCE(vrf, vrfname, false); + /* + * within vrf context, vrf_id may be unknown + * this happens on daemons relying on zebra + * on this specific case, interface creation may + * be forced + */ + if (vrf && (vrf->vrf_id == VRF_UNKNOWN || + vrf_get_backend() == VRF_BACKEND_UNKNOWN)) + ifp = if_lookup_by_name(ifname, vrf); + else + ifp = if_lookup_by_name_all_vrf(ifname); + if (ifp && ifp->vrf_id != vrf->vrf_id) { /* * Special case 1: a VRF name was specified, but the found * interface is associated to different VRF. Reject the command. */ - if (vrf_id != VRF_DEFAULT) { + if (vrf->vrf_id != VRF_DEFAULT) { vty_out(vty, "%% interface %s not in %s vrf\n", ifname, vrfname); return CMD_WARNING_CONFIG_FAILED; @@ -1161,8 +1170,7 @@ DEFPY_NOSH (interface, vrf = vrf_lookup_by_id(ifp->vrf_id); assert(vrf); vrfname = vrf->name; - } else - vrf = vrf_lookup_by_id(vrf_id); + } snprintf(xpath_list, sizeof(xpath_list), "/frr-interface:lib/interface[name='%s'][vrf='%s']", ifname, @@ -1301,7 +1309,7 @@ static int lib_interface_create(enum nb_event event, const char *ifname; const char *vrfname; struct vrf *vrf; - struct interface *ifp; + struct interface *ifp = NULL; ifname = yang_dnode_get_string(dnode, "./name"); vrfname = yang_dnode_get_string(dnode, "./vrf"); @@ -1314,11 +1322,9 @@ static int lib_interface_create(enum nb_event event, vrfname); return NB_ERR_VALIDATION; } - if (vrf->vrf_id == VRF_UNKNOWN) { - zlog_warn("%s: VRF %s is not active", __func__, - vrf->name); - return NB_ERR_VALIDATION; - } + if (vrf->vrf_id == VRF_UNKNOWN) + zlog_warn("%s: VRF %s is not active. Using interface however.", + __func__, vrf->name); /* if VRF is netns or not yet known - init for instance * then assumption is that passed config is exact |
