lib: allow to create interfaces in non-existing VRFs

It allows FRR to read the interface config even when the necessary VRFs
are not yet created and interfaces are in "wrong" VRFs. Currently, such
config is rejected.

For VRF-lite backend, we don't care at all about the VRF of the inactive
interface. When the interface is created in the OS and becomes active,
we always use its actual VRF instead of the configured one. So there's
no need to reject the config.

For netns backend, we may have multiple interfaces with the same name in
different VRFs. So we care about the VRF of inactive interfaces. And we
must allow to preconfigure the interface in a VRF even before it is
moved to the corresponding netns. From now on, we allow to create
multiple configs for the same interface name in different VRFs and
the necessary config is applied once the OS interface is moved to the
corresponding netns.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2021-10-13 15:06:38 +03:00
parent e9f7b2b597
commit f60a11883c
12 changed files with 155 additions and 233 deletions

284
lib/if.c
View File

@ -45,6 +45,7 @@ DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected");
DEFINE_MTYPE(LIB, CONNECTED_LABEL, "Connected interface label");
DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters");
static void if_set_name(struct interface *ifp, const char *name);
static struct interface *if_lookup_by_ifindex(ifindex_t ifindex,
vrf_id_t vrf_id);
static int if_cmp_func(const struct interface *, const struct interface *);
@ -153,16 +154,19 @@ static void ifp_connected_free(void *arg)
}
/* Create new interface structure. */
static struct interface *if_new(vrf_id_t vrf_id)
static struct interface *if_new(struct vrf *vrf)
{
struct interface *ifp;
assert(vrf);
ifp = XCALLOC(MTYPE_IF, sizeof(struct interface));
ifp->ifindex = IFINDEX_INTERNAL;
ifp->name[0] = '\0';
ifp->vrf_id = vrf_id;
ifp->vrf = vrf;
ifp->vrf_id = vrf->vrf_id;
ifp->connected = list_new();
ifp->connected->del = ifp_connected_free;
@ -207,11 +211,11 @@ void if_down_via_zapi(struct interface *ifp)
(*ifp_master.down_hook)(ifp);
}
struct interface *if_create_name(const char *name, vrf_id_t vrf_id)
static struct interface *if_create_name(const char *name, struct vrf *vrf)
{
struct interface *ifp;
ifp = if_new(vrf_id);
ifp = if_new(vrf);
if_set_name(ifp, name);
@ -219,35 +223,23 @@ struct interface *if_create_name(const char *name, vrf_id_t vrf_id)
return ifp;
}
struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
{
struct interface *ifp;
ifp = if_new(vrf_id);
if_set_index(ifp, ifindex);
hook_call(if_add, ifp);
return ifp;
}
/* Create new interface structure. */
void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
{
struct vrf *old_vrf, *vrf;
/* remove interface from old master vrf list */
old_vrf = vrf_lookup_by_id(ifp->vrf_id);
if (old_vrf) {
if (ifp->name[0] != '\0')
IFNAME_RB_REMOVE(old_vrf, ifp);
old_vrf = ifp->vrf;
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(old_vrf, ifp);
}
if (ifp->name[0] != '\0')
IFNAME_RB_REMOVE(old_vrf, ifp);
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(old_vrf, ifp);
ifp->vrf_id = vrf_id;
vrf = vrf_get(ifp->vrf_id, NULL);
ifp->vrf = vrf;
if (ifp->name[0] != '\0')
IFNAME_RB_INSERT(vrf, ifp);
@ -261,7 +253,7 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
* the interface and readding it in the new VRF, which would have
* several implications.
*/
if (yang_module_find("frr-interface")) {
if (!vrf_is_backend_netns() && yang_module_find("frr-interface")) {
struct lyd_node *if_dnode;
char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN];
@ -304,15 +296,15 @@ void if_delete_retain(struct interface *ifp)
void if_delete(struct interface **ifp)
{
struct interface *ptr = *ifp;
struct vrf *vrf;
vrf = vrf_lookup_by_id(ptr->vrf_id);
assert(vrf);
struct vrf *vrf = ptr->vrf;
IFNAME_RB_REMOVE(vrf, ptr);
if (ptr->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(vrf, ptr);
if (!vrf_is_enabled(vrf))
vrf_delete(vrf);
if_delete_retain(ptr);
list_delete(&ptr->connected);
@ -439,7 +431,7 @@ struct interface *if_lookup_by_name_all_vrf(const char *name)
if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
return NULL;
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ifp = if_lookup_by_name_vrf(name, vrf);
if (ifp)
return ifp;
@ -582,72 +574,58 @@ size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,
/* Get interface by name if given name interface doesn't exist create
one. */
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id)
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id,
const char *vrf_name)
{
struct interface *ifp;
struct interface *ifp = NULL;
struct vrf *vrf;
switch (vrf_get_backend()) {
case VRF_BACKEND_UNKNOWN:
case VRF_BACKEND_NETNS:
ifp = if_lookup_by_name(name, vrf_id);
if (ifp)
vrf = vrf_get(vrf_id, vrf_name);
assert(vrf);
ifp = if_lookup_by_name_vrf(name, vrf);
if (ifp) {
/* If it came from the kernel or by way of zclient,
* believe it and update the ifp accordingly.
*/
if (ifp->vrf_id != vrf_id && vrf_id != VRF_UNKNOWN)
if_update_to_new_vrf(ifp, vrf_id);
return ifp;
return if_create_name(name, vrf_id);
}
break;
case VRF_BACKEND_VRF_LITE:
ifp = if_lookup_by_name_all_vrf(name);
if (ifp) {
if (ifp->vrf_id == vrf_id)
return ifp;
/* If it came from the kernel or by way of zclient,
* believe it and update the ifp accordingly.
*/
if_update_to_new_vrf(ifp, vrf_id);
if (ifp->vrf_id != vrf_id && vrf_id != VRF_UNKNOWN)
if_update_to_new_vrf(ifp, vrf_id);
return ifp;
}
return if_create_name(name, vrf_id);
vrf = vrf_get(vrf_id, vrf_name);
assert(vrf);
break;
default:
return NULL;
}
return NULL;
}
struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
{
struct interface *ifp;
switch (vrf_get_backend()) {
case VRF_BACKEND_UNKNOWN:
case VRF_BACKEND_NETNS:
ifp = if_lookup_by_ifindex(ifindex, vrf_id);
if (ifp)
return ifp;
return if_create_ifindex(ifindex, vrf_id);
case VRF_BACKEND_VRF_LITE:
ifp = if_lookup_by_index_all_vrf(ifindex);
if (ifp) {
if (ifp->vrf_id == vrf_id)
return ifp;
/* If it came from the kernel or by way of zclient,
* believe it and update the ifp accordingly.
*/
if_update_to_new_vrf(ifp, vrf_id);
return ifp;
}
return if_create_ifindex(ifindex, vrf_id);
}
return NULL;
return if_create_name(name, vrf);
}
int if_set_index(struct interface *ifp, ifindex_t ifindex)
{
struct vrf *vrf;
if (ifp->ifindex == ifindex)
return 0;
vrf = vrf_get(ifp->vrf_id, NULL);
assert(vrf);
/*
* If there is already an interface with this ifindex, we will collide
* on insertion, so don't even try.
@ -656,7 +634,7 @@ int if_set_index(struct interface *ifp, ifindex_t ifindex)
return -1;
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(vrf, ifp);
IFINDEX_RB_REMOVE(ifp->vrf, ifp);
ifp->ifindex = ifindex;
@ -666,30 +644,25 @@ int if_set_index(struct interface *ifp, ifindex_t ifindex)
* already an interface with the desired ifindex at the top of
* the function. Nevertheless.
*/
if (IFINDEX_RB_INSERT(vrf, ifp))
if (IFINDEX_RB_INSERT(ifp->vrf, ifp))
return -1;
}
return 0;
}
void if_set_name(struct interface *ifp, const char *name)
static void if_set_name(struct interface *ifp, const char *name)
{
struct vrf *vrf;
vrf = vrf_get(ifp->vrf_id, NULL);
assert(vrf);
if (if_cmp_name_func(ifp->name, name) == 0)
return;
if (ifp->name[0] != '\0')
IFNAME_RB_REMOVE(vrf, ifp);
IFNAME_RB_REMOVE(ifp->vrf, ifp);
strlcpy(ifp->name, name, sizeof(ifp->name));
if (ifp->name[0] != '\0')
IFNAME_RB_INSERT(vrf, ifp);
IFNAME_RB_INSERT(ifp->vrf, ifp);
}
/* Does interface up ? */
@ -817,15 +790,12 @@ static void if_dump(const struct interface *ifp)
struct listnode *node;
struct connected *c __attribute__((unused));
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c)) {
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c))
zlog_info(
"Interface %s vrf %s(%u) index %d metric %d mtu %d mtu6 %d %s",
ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex,
ifp->name, ifp->vrf->name, ifp->vrf_id, ifp->ifindex,
ifp->metric, ifp->mtu, ifp->mtu6,
if_flag_dump(ifp->flags));
}
}
/* Interface printing for all interface. */
@ -894,16 +864,14 @@ connected_log(struct connected *connected, char *str)
{
struct prefix *p;
struct interface *ifp;
struct vrf *vrf;
char logbuf[BUFSIZ];
char buf[BUFSIZ];
ifp = connected->ifp;
p = connected->address;
vrf = vrf_lookup_by_id(ifp->vrf_id);
snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %pFX ",
str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id,
str, ifp->name, ifp->vrf->name, ifp->vrf_id,
prefix_family_str(p), p);
p = connected->destination;
@ -1059,30 +1027,15 @@ struct connected *connected_get_linklocal(struct interface *ifp)
void if_terminate(struct vrf *vrf)
{
struct interface *ifp;
bool delete;
/*
* If the default VRF is being terminated or has
* already been terminated it means that
* the program is shutting down and we need to
* delete all the interfaces. Otherwise, we only
* need to move VRF's interfaces to the default VRF.
*/
delete = vrf_is_backend_netns() || vrf->vrf_id == VRF_DEFAULT
|| !vrf_lookup_by_id(VRF_DEFAULT);
while (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
ifp = RB_ROOT(if_name_head, &vrf->ifaces_by_name);
if (delete) {
if (ifp->node) {
ifp->node->info = NULL;
route_unlock_node(ifp->node);
}
if_delete(&ifp);
} else {
if_update_to_new_vrf(ifp, VRF_DEFAULT);
if (ifp->node) {
ifp->node->info = NULL;
route_unlock_node(ifp->node);
}
if_delete(&ifp);
}
}
@ -1186,6 +1139,25 @@ void if_link_params_free(struct interface *ifp)
/* ----------- CLI commands ----------- */
/* Guess the VRF of an interface. */
static int vrfname_by_ifname(const char *ifname, const char **vrfname)
{
struct vrf *vrf;
struct interface *ifp;
int count = 0;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
FOR_ALL_INTERFACES (vrf, ifp) {
if (strmatch(ifp->name, ifname)) {
*vrfname = vrf->name;
count++;
}
}
}
return count;
}
/*
* XPath: /frr-interface:lib/interface
*/
@ -1197,12 +1169,9 @@ DEFPY_YANG_NOSH (interface,
VRF_CMD_HELP_STR)
{
char xpath_list[XPATH_MAXLEN];
vrf_id_t vrf_id;
struct interface *ifp;
int ret;
if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME;
struct vrf *vrf;
int ret, count;
/*
* This command requires special handling to maintain backward
@ -1211,30 +1180,30 @@ DEFPY_YANG_NOSH (interface,
* interface is found, then a new one should be created on the default
* VRF.
*/
VRF_GET_ID(vrf_id, vrf_name, false);
ifp = if_lookup_by_name_all_vrf(ifname);
if (ifp && ifp->vrf_id != vrf_id) {
struct vrf *vrf;
if (vrf_is_backend_netns()) {
/*
* Special case 1: a VRF name was specified, but the found
* interface is associated to different VRF. Reject the command.
* For backward compatibility, if the VRF name is not specified
* and there is exactly one interface with this name in the
* system, use its VRF. Otherwise fallback to the default VRF.
*/
if (vrf_id != VRF_DEFAULT) {
vty_out(vty, "%% interface %s not in %s vrf\n", ifname,
vrf_name);
return CMD_WARNING_CONFIG_FAILED;
if (!vrf_name) {
count = vrfname_by_ifname(ifname, &vrf_name);
if (count != 1)
vrf_name = VRF_DEFAULT_NAME;
}
} else {
/*
* Special case 2: a VRF name was *not* specified, and the found
* interface is associated to a VRF other than the default one.
* Update vrf_id and vrf_name to account for that.
* If the interface already exists, use its VRF regardless of
* what user specified. We can't have same interface name in
* different VRFs with VRF-lite backend.
*/
vrf = vrf_lookup_by_id(ifp->vrf_id);
assert(vrf);
vrf_id = ifp->vrf_id;
vrf_name = vrf->name;
ifp = if_lookup_by_name_all_vrf(ifname);
if (ifp) {
vrf_name = ifp->vrf->name;
} else {
if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME;
}
}
snprintf(xpath_list, sizeof(xpath_list),
@ -1252,7 +1221,15 @@ DEFPY_YANG_NOSH (interface,
* all interface-level commands are converted to the new
* northbound model.
*/
ifp = if_lookup_by_name(ifname, vrf_id);
if (vrf_is_backend_netns()) {
vrf = vrf_lookup_by_name(vrf_name);
if (vrf)
ifp = if_lookup_by_name_vrf(ifname, vrf);
else
ifp = NULL;
} else {
ifp = if_lookup_by_name_all_vrf(ifname);
}
if (ifp)
VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp);
}
@ -1397,7 +1374,6 @@ static int lib_interface_create(struct nb_cb_create_args *args)
{
const char *ifname;
const char *vrfname;
struct vrf *vrf;
struct interface *ifp;
ifname = yang_dnode_get_string(args->dnode, "./name");
@ -1405,39 +1381,11 @@ static int lib_interface_create(struct nb_cb_create_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
vrf = vrf_lookup_by_name(vrfname);
if (!vrf) {
zlog_warn("%s: VRF %s doesn't exist", __func__,
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 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) {
zlog_warn(
"%s: interface %s already exists in another VRF",
__func__, ifp->name);
return NB_ERR_VALIDATION;
}
}
break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
ifp = if_get_by_name(ifname, vrf->vrf_id);
ifp = if_get_by_name(ifname, VRF_UNKNOWN, vrfname);
ifp->configured = true;
nb_running_set_entry(args->dnode, ifp);
@ -1488,7 +1436,7 @@ static const void *lib_interface_get_next(struct nb_cb_get_next_args *args)
assert(vrf);
pif = RB_MIN(if_name_head, &vrf->ifaces_by_name);
} else {
vrf = vrf_lookup_by_id(pif->vrf_id);
vrf = pif->vrf;
pif = RB_NEXT(if_name_head, pif);
/* if no more interfaces, switch to next vrf */
while (pif == NULL) {
@ -1506,13 +1454,9 @@ static int lib_interface_get_keys(struct nb_cb_get_keys_args *args)
{
const struct interface *ifp = args->list_entry;
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
assert(vrf);
args->keys->num = 2;
strlcpy(args->keys->key[0], ifp->name, sizeof(args->keys->key[0]));
strlcpy(args->keys->key[1], vrf->name, sizeof(args->keys->key[1]));
strlcpy(args->keys->key[1], ifp->vrf->name, sizeof(args->keys->key[1]));
return NB_OK;
}

View File

@ -293,6 +293,8 @@ struct interface {
#endif /* HAVE_NET_RT_IFLIST */
struct route_node *node;
struct vrf *vrf;
vrf_id_t vrf_id;
/*
@ -510,11 +512,6 @@ extern int if_cmp_name_func(const char *p1, const char *p2);
*/
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
/* Create new interface, adds to name list only */
extern struct interface *if_create_name(const char *name, vrf_id_t vrf_id);
/* Create new interface, adds to index list only */
extern struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
vrf_id_t vrf_id);
@ -532,13 +529,11 @@ struct vrf;
extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
extern struct interface *if_lookup_by_name_vrf(const char *name, struct vrf *vrf);
extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id);
extern struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id,
const char *vrf_name);
/* Sets the index and adds to index list */
extern int if_set_index(struct interface *ifp, ifindex_t ifindex);
/* Sets the name and adds to name list */
extern void if_set_name(struct interface *ifp, const char *name);
/* Delete the interface, but do not free the structure, and leave it in the
interface list. It is often advisable to leave the pseudo interface

View File

@ -272,32 +272,29 @@ void vrf_delete(struct vrf *vrf)
if (vrf_is_enabled(vrf))
vrf_disable(vrf);
if (vrf->vrf_id != VRF_UNKNOWN) {
RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
vrf->vrf_id = VRF_UNKNOWN;
}
/* If the VRF is user configured, it'll stick around, just remove
* the ID mapping. Interfaces assigned to this VRF should've been
* removed already as part of the VRF going down.
*/
if (vrf_is_user_cfged(vrf)) {
if (vrf->vrf_id != VRF_UNKNOWN) {
/* Delete any VRF interfaces - should be only
* the VRF itself, other interfaces should've
* been moved out of the VRF.
*/
if_terminate(vrf);
RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
vrf->vrf_id = VRF_UNKNOWN;
}
vrf->ns_ctxt = NULL;
return;
}
/* Do not delete the VRF if it has interfaces configured in it. */
if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name))
return;
if (vrf_master.vrf_delete_hook)
(*vrf_master.vrf_delete_hook)(vrf);
QOBJ_UNREG(vrf);
if_terminate(vrf);
if (vrf->vrf_id != VRF_UNKNOWN)
RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
if (vrf->name[0] != '\0')
RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
@ -571,6 +568,7 @@ static void vrf_terminate_single(struct vrf *vrf)
{
/* Clear configured flag and invoke delete. */
UNSET_FLAG(vrf->status, VRF_CONFIGURED);
if_terminate(vrf);
vrf_delete(vrf);
}

View File

@ -2164,19 +2164,21 @@ static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
struct stream *s = zclient->ibuf;
struct vrf *vrf;
/* Read interface name. */
STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup/create interface by name. */
if (!vrf_get(vrf_id, NULL)) {
vrf = vrf_lookup_by_id(vrf_id);
if (!vrf) {
zlog_debug(
"Rx'd interface add from Zebra, but VRF %u does not exist",
vrf_id);
return -1;
}
ifp = if_get_by_name(ifname_tmp, vrf_id);
ifp = if_get_by_name(ifname_tmp, vrf_id, vrf->name);
zebra_interface_if_set_value(s, ifp);

View File

@ -1032,7 +1032,6 @@ DEFUN_HIDDEN (ospf6_interface_area,
struct ospf6_area *oa;
struct ospf6_interface *oi;
struct interface *ifp;
vrf_id_t vrf_id = VRF_DEFAULT;
uint32_t area_id;
int format;
@ -1041,11 +1040,8 @@ DEFUN_HIDDEN (ospf6_interface_area,
vty_out(vty,
"Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
if (ospf6->vrf_id != VRF_UNKNOWN)
vrf_id = ospf6->vrf_id;
/* find/create ospf6 interface */
ifp = if_get_by_name(argv[idx_ifname]->arg, vrf_id);
ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
oi = (struct ospf6_interface *)ifp->info;
if (oi == NULL)
oi = ospf6_interface_create(ifp);
@ -1107,18 +1103,14 @@ DEFUN_HIDDEN (no_ospf6_interface_area,
struct ospf6_area *oa;
struct interface *ifp;
uint32_t area_id;
vrf_id_t vrf_id = VRF_DEFAULT;
vty_out(vty,
"This command is deprecated, because it is not VRF-aware.\n");
vty_out(vty,
"Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
if (ospf6->vrf_id != VRF_UNKNOWN)
vrf_id = ospf6->vrf_id;
/* find/create ospf6 interface */
ifp = if_get_by_name(argv[idx_ifname]->arg, vrf_id);
ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
if (ifp == NULL) {
vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);

View File

@ -915,9 +915,9 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%u", vlink_count);
vi = if_create_name(ifname, ospf->vrf_id);
vi = if_get_by_name(ifname, ospf->vrf_id, ospf->name);
/*
* if_create_name sets ZEBRA_INTERFACE_LINKDETECTION
* if_get_by_name sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this.
*/
UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);

View File

@ -445,7 +445,7 @@ DEFUN_HIDDEN (ospf_passive_interface_addr,
"Please, use \"ip ospf passive\" on an interface instead.\n");
if (ospf->vrf_id != VRF_UNKNOWN)
ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id);
ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, ospf->name);
if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n", (char *)argv[1]->arg);
@ -506,7 +506,7 @@ DEFUN_HIDDEN (no_ospf_passive_interface,
"Please, use \"no ip ospf passive\" on an interface instead.\n");
if (ospf->vrf_id != VRF_UNKNOWN)
ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id, ospf->name);
if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n", (char *)argv[2]->arg);

View File

@ -1482,7 +1482,8 @@ void pim_if_create_pimreg(struct pim_instance *pim)
snprintf(pimreg_name, sizeof(pimreg_name), "pimreg%u",
pim->vrf->data.l.table_id);
pim->regiface = if_create_name(pimreg_name, pim->vrf->vrf_id);
pim->regiface = if_get_by_name(pimreg_name, pim->vrf->vrf_id,
pim->vrf->name);
pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
pim_if_new(pim->regiface, false, false, true,

View File

@ -109,7 +109,8 @@ static int interface_list_ioctl(void)
unsigned int size;
ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n);
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT);
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT,
VRF_DEFAULT_NAME);
if_add_update(ifp);
size = ifreq->ifr_addr.sa_len;
if (size < sizeof(ifreq->ifr_addr))
@ -119,7 +120,8 @@ static int interface_list_ioctl(void)
}
#else
for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) {
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT);
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT,
VRF_DEFAULT_NAME);
if_add_update(ifp);
ifreq++;
}

View File

@ -972,17 +972,9 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
link_nsid = ns_id_get_absolute(ns_id, link_nsid);
}
/* Add interface.
* We add by index first because in some cases such as the master
* interface, we have the index before we have the name. Fixing
* back references on the slave interfaces is painful if not done
* this way, i.e. by creating by ifindex.
*/
ifp = if_get_by_ifindex(ifi->ifi_index, vrf_id);
ifp = if_get_by_name(name, vrf_id, NULL);
set_ifindex(ifp, ifi->ifi_index, zns); /* add it to ns struct */
if_set_name(ifp, name);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
@ -1814,7 +1806,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (ifp == NULL) {
/* unknown interface */
ifp = if_get_by_name(name, vrf_id);
ifp = if_get_by_name(name, vrf_id, NULL);
} else {
/* pre-configured interface, learnt now */
if (ifp->vrf_id != vrf_id)

View File

@ -1616,7 +1616,6 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
struct listnode *node;
struct route_node *rn;
struct zebra_if *zebra_if;
struct vrf *vrf;
char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
zebra_if = ifp->info;
@ -1644,8 +1643,7 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
zebra_ptm_show_status(vty, NULL, ifp);
vrf = vrf_lookup_by_id(ifp->vrf_id);
vty_out(vty, " vrf: %s\n", vrf->name);
vty_out(vty, " vrf: %s\n", ifp->vrf->name);
if (ifp->desc)
vty_out(vty, " Description: %s\n", ifp->desc);
@ -1941,7 +1939,6 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
struct listnode *node;
struct route_node *rn;
struct zebra_if *zebra_if;
struct vrf *vrf;
char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
char buf[BUFSIZ];
json_object *json_if;
@ -1979,8 +1976,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
zebra_ptm_show_status(vty, json, ifp);
vrf = vrf_lookup_by_id(ifp->vrf_id);
json_object_string_add(json_if, "vrfName", vrf->name);
json_object_string_add(json_if, "vrfName", ifp->vrf->name);
if (ifp->desc)
json_object_string_add(json_if, "description", ifp->desc);
@ -4206,21 +4202,19 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp)
static int if_config_write(struct vty *vty)
{
struct vrf *vrf0;
struct vrf *vrf;
struct interface *ifp;
zebra_ptm_write(vty);
RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
FOR_ALL_INTERFACES (vrf0, ifp) {
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
FOR_ALL_INTERFACES (vrf, ifp) {
struct zebra_if *if_data;
struct listnode *addrnode;
struct connected *ifc;
struct prefix *p;
struct vrf *vrf;
if_data = ifp->info;
vrf = vrf_lookup_by_id(ifp->vrf_id);
if (ifp->vrf_id == VRF_DEFAULT)
vty_frame(vty, "interface %s\n", ifp->name);

View File

@ -443,7 +443,8 @@ static int ifan_read(struct if_announcemsghdr *ifan)
__func__, ifan->ifan_index, ifan->ifan_name);
/* Create Interface */
ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT);
ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT,
VRF_DEFAULT_NAME);
if_set_index(ifp, ifan->ifan_index);
if_get_metric(ifp);
@ -624,7 +625,8 @@ int ifm_read(struct if_msghdr *ifm)
if (ifp == NULL) {
/* Interface that zebra was not previously aware of, so
* create. */
ifp = if_create_name(ifname, VRF_DEFAULT);
ifp = if_get_by_name(ifname, VRF_DEFAULT,
VRF_DEFAULT_NAME);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s: creating ifp for ifindex %d",
__func__, ifm->ifm_index);