summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-02-11 16:05:39 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2019-06-12 08:37:58 +0200
commitac6c2a11a659a00360700f352c0fbd47c133dfea (patch)
tree8f5d801d5bf920158c3330a2d3a533aeb058fcb7 /lib/if.c
parentf11e98eca3c4b4e3c91c826329018e848bcb9fc6 (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.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/lib/if.c b/lib/if.c
index 1a51e3ee8d..c10aebd8a5 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -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