zebra: Only create vrf route-node if in the kernel

Changed vrf_get to only create a route-node if the kernel has enabled the vrf,
supplying a table-id.  If the quagga configuration contains vrfs that have not
yet been enabled by the kernel, the vrf is created with a vrf_id of VRF_UNKNOWN.
These vrfs are added to the vrf_list so they contain a zvrf and configuration,
but the route-node is not created until the kernel has signalled that the vrf
has been defined and enabled.

Ticket: CM-10481
Signed-off-by: Don Slice
Reviewed-by: Donald Sharp
This commit is contained in:
Don Slice 2016-04-21 16:15:07 +00:00
parent c26cb63815
commit c88a8b757d

107
lib/vrf.c
View File

@ -87,77 +87,86 @@ struct vrf *
vrf_get (vrf_id_t vrf_id, const char *name)
{
struct prefix p;
struct route_node *rn;
struct route_node *rn = NULL;
struct vrf *vrf = NULL;
size_t namelen = 0;
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (rn->info)
/* Only create a route node if the vrf was learned from the kernel */
if (vrf_id != VRF_UNKNOWN)
{
vrf = (struct vrf *)rn->info;
route_unlock_node (rn); /* get */
vrf_build_key (vrf_id, &p);
rn = route_node_get (vrf_table, &p);
if (name)
if (rn->info)
{
strncpy (vrf->name, name, strlen(name));
vrf->name[strlen(name)] = '\0';
if (vrf_list_lookup_by_name (vrf->name) == NULL)
listnode_add_sort (vrf_list, vrf);
vrf = (struct vrf *)rn->info;
route_unlock_node (rn); /* get */
if (name)
{
strncpy (vrf->name, name, strlen(name));
vrf->name[strlen(name)] = '\0';
if (vrf_list_lookup_by_name (vrf->name) == NULL)
listnode_add_sort (vrf_list, vrf);
}
if (debug_vrf)
zlog_debug ("VRF(%u) %s Found %p", vrf_id, (name) ? name : "(NULL)",
vrf);
}
}
if (name && !vrf)
vrf = vrf_list_lookup_by_name(name);
if (vrf)
{
if (debug_vrf)
zlog_debug ("VRF(%u) %s Found %p", vrf_id, (name) ? name : "(NULL)",
vrf);
zlog_debug ("VRF(%u) %s lookup by name is successful",
vrf_id, (name) ? name : "(NULL)");
}
else
{
if (name)
vrf = vrf_list_lookup_by_name(name);
if (vrf)
{
if (debug_vrf)
zlog_debug ("VRF(%u) %s lookup by name is successful",
vrf_id, (name) ? name : "(NULL)");
}
else
{
if (name)
{
namelen = strlen (name);
if (namelen > VRF_NAMSIZ)
{
namelen = strlen (name);
if (namelen > VRF_NAMSIZ)
{
zlog_err("Attempt to get/create VRF %u name %s - name too long",
vrf_id, name);
return NULL;
}
zlog_err("Attempt to get/create VRF %u name %s - name too long",
vrf_id, name);
return NULL;
}
}
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
if (debug_vrf)
zlog_debug ("VRF(%u) %s is created.",
vrf_id, (name) ? name : "(NULL)");
if (name)
{
strncpy (vrf->name, name, namelen);
vrf->name[namelen] = '\0';
listnode_add_sort (vrf_list, vrf);
}
}
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
if (debug_vrf)
zlog_debug ("VRF(%u) %s is created.",
vrf_id, (name) ? name : "(NULL)");
if (name)
{
strncpy (vrf->name, name, namelen);
vrf->name[namelen] = '\0';
listnode_add_sort (vrf_list, vrf);
}
if ((vrf_id != VRF_UNKNOWN) && (rn != NULL))
{
rn->info = vrf;
vrf->node = rn;
}
vrf->vrf_id = vrf_id;
rn->info = vrf;
vrf->node = rn;
/* Initialize interfaces. */
if_init (&vrf->iflist);
}
if (vrf_master.vrf_new_hook && name) {
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (vrf_master.vrf_new_hook && name)
{
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
if (vrf->info)
zlog_info ("zvrf is created.");
}
if (vrf->info)
zlog_info ("zvrf is created.");
}
return vrf;
}