Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: fix issue with interface node access at startup #4193

Closed
11 changes: 5 additions & 6 deletions bfdd/bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,12 @@ int bfd_session_enable(struct bfd_session *bs)
"session-enable: specified VRF doesn't exists.");
return 0;
}
}

} else
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (!vrf)
return 0;
if (bs->key.ifname[0]) {
if (vrf)
ifp = if_lookup_by_name(bs->key.ifname, vrf->vrf_id);
else
ifp = if_lookup_by_name_all_vrf(bs->key.ifname);
ifp = if_lookup_by_name(bs->key.ifname, vrf->vrf_id);
if (ifp == NULL) {
log_error(
"session-enable: specified interface doesn't exists.");
Expand Down
3 changes: 2 additions & 1 deletion bfdd/bfdctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ struct sockaddr_any {
};

#ifndef MAXNAMELEN
#define MAXNAMELEN 32
/* aligned with VRF_NAMSIZ + 1 defined in vrf.h */
#define MAXNAMELEN 37
#endif

#define BPC_DEF_DETECTMULTIPLIER 3
Expand Down
19 changes: 18 additions & 1 deletion bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1466,14 +1466,31 @@ route_match_interface(void *rule, const struct prefix *prefix,
{
struct interface *ifp;
struct bgp_path_info *path;
struct bgp_node *rn;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this commit work with route leaking routes? Have you tested this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the interface should be in the bgp_orig pointer. good point.
I did not test it.
I will try to make a test to check if it is correct ( I focus on vrf-lite backend).

struct bgp_table *table;
struct bgp *bgp;

if (type == RMAP_BGP) {
path = object;

if (!path || !path->attr)
return RMAP_NOMATCH;

ifp = if_lookup_by_name_all_vrf((char *)rule);
/* get vrf_id of current bgp instance
* in cast imported vrf leak entry, get bgp_orig
*/
if (path->extra && path->extra->bgp_orig)
bgp = path->extra->bgp_orig;
else {
rn = path->net;
if (!rn || !bgp_node_table(rn))
return RMAP_NOMATCH;
table = bgp_node_table(rn);
if (!table->bgp)
return RMAP_NOMATCH;
bgp = table->bgp;
}
ifp = if_lookup_by_name((char *)rule, bgp->vrf_id);

if (ifp == NULL || ifp->ifindex != path->attr->nh_ifindex)
return RMAP_NOMATCH;
Expand Down
2 changes: 1 addition & 1 deletion bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -2985,7 +2985,7 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
/* create default route with interface <VRF>
* with nexthop-vrf <VRF>
*/
ifp = if_lookup_by_name_all_vrf(vrf->name);
ifp = if_lookup_by_name(vrf->name, nh->vrf_id);
if (!ifp)
return;
api_nh->vrf_id = nh->vrf_id;
Expand Down
43 changes: 32 additions & 11 deletions lib/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ void if_down_via_zapi(struct interface *ifp)
(*ifp_master.down_hook)(ifp);
}

static struct interface *if_lookup_by_name_all_vrf(const char *name)
{
struct vrf *vrf;
struct interface *ifp;

if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
return NULL;

RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
ifp = if_lookup_by_name(name, vrf->vrf_id);
if (ifp)
return ifp;
}

return NULL;
}

struct interface *if_create_name(const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
Expand Down Expand Up @@ -359,20 +376,24 @@ struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id)
return RB_FIND(if_name_head, &vrf->ifaces_by_name, &if_tmp);
}

struct interface *if_lookup_by_name_all_vrf(const char *name)
/* Interface existance check by interface name.
* if vrf backend is vrf-lite, look in other vrfs
*/
static struct interface *if_lookup_by_name_relax(const char *name, vrf_id_t vrf_id)
{
struct vrf *vrf;
struct interface *ifp;
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface if_tmp, *ifp;

if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
if (!vrf || !name
|| strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
return NULL;

RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
ifp = if_lookup_by_name(name, vrf->vrf_id);
if (ifp)
return ifp;
}

strlcpy(if_tmp.name, name, sizeof(if_tmp.name));
ifp = RB_FIND(if_name_head, &vrf->ifaces_by_name, &if_tmp);
if (ifp)
return ifp;
if (vrf_get_backend() == VRF_BACKEND_VRF_LITE)
return if_lookup_by_name_all_vrf(name);
return NULL;
}

Expand Down Expand Up @@ -1279,7 +1300,7 @@ DEFPY_NOSH (interface,
* VRF.
*/
VRF_GET_ID(vrf_id, vrf_name, false);
ifp = if_lookup_by_name_all_vrf(ifname);
ifp = if_lookup_by_name_relax(ifname, vrf_id);
if (ifp && ifp->vrf_id != vrf_id) {
struct vrf *vrf;

Expand Down
3 changes: 2 additions & 1 deletion lib/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ extern struct interface *if_lookup_prefix(struct prefix *prefix,
size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,
struct interface ***result, vrf_id_t vrf_id);

extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
/* These 3 functions are to be used when the ifname argument is terminated
by a '\0' character: */
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);
Expand Down
1 change: 1 addition & 0 deletions ospfd/ospf_asbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
new = ospf_external_info_new(type, instance);
new->p = p;
new->ifindex = ifindex;
new->vrf_id = ospf->vrf_id;
new->nexthop = nexthop;
new->tag = tag;

Expand Down
2 changes: 2 additions & 0 deletions ospfd/ospf_asbr.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct external_info {
struct route_map_set_values route_map_set;
#define ROUTEMAP_METRIC(E) (E)->route_map_set.metric
#define ROUTEMAP_METRIC_TYPE(E) (E)->route_map_set.metric_type

vrf_id_t vrf_id;
};

#define OSPF_ASBR_CHECK_DELAY 30
Expand Down
2 changes: 1 addition & 1 deletion ospfd/ospf_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ route_match_interface(void *rule, const struct prefix *prefix,

if (type == RMAP_OSPF) {
ei = object;
ifp = if_lookup_by_name_all_vrf((char *)rule);
ifp = if_lookup_by_name((char *)rule, ei->vrf_id);

if (ifp == NULL || ifp->ifindex != ei->ifindex)
return RMAP_NOMATCH;
Expand Down
17 changes: 15 additions & 2 deletions zebra/zebra_ptm.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ static int zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt,
char bfdst_str[32];
char dest_str[64];
char src_str[64];
char vrf_str[64];
char vrf_str[VRF_NAMSIZ + 1];
struct prefix dest_prefix;
struct prefix src_prefix;
vrf_id_t vrf_id;
Expand Down Expand Up @@ -589,6 +589,8 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)
char port_str[128];
char cbl_str[32];
char cmd_status_str[32];
char vrf_str[VRF_NAMSIZ + 1];
struct vrf *vrf = NULL;

ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_CMD_STATUS_STR,
cmd_status_str);
Expand All @@ -598,6 +600,17 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)
return 0;
}

ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDVRF_STR, vrf_str);

if (vrf_str[0] == '\0')
vrf = vrf_lookup_by_id(VRF_DEFAULT);
else
vrf = vrf_lookup_by_name(vrf_str);
if (!vrf) {
zlog_debug("%s: Could not obtain appropriate VRF",
__func__);
return -1;
}
ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_PORT_STR, port_str);

if (port_str[0] == '\0') {
Expand All @@ -607,7 +620,7 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)
}

if (strcmp(ZEBRA_PTM_INVALID_PORT_NAME, port_str)) {
ifp = if_lookup_by_name_all_vrf(port_str);
ifp = if_lookup_by_name(port_str, vrf->vrf_id);

if (!ifp) {
flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
Expand Down