mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 11:30:30 +00:00
zebra: Ensure master's ifname is known, even if slave comes up first
In if_netlink.c, when an interface structure, ifp, is first created, its possible for the master to come up after the slave interface does. This means, the slave interface has no way to display the master's ifname in show outputs. To fix this, we need to allow creation by ifindex instead of by ifname so that this issue is handled. Signed-off-by: Dinesh G Dutt<5016467+ddutt@users.noreply.github.com>
This commit is contained in:
parent
eb4a93fb09
commit
ea7ec26162
75
lib/if.c
75
lib/if.c
@ -132,18 +132,26 @@ static int if_cmp_index_func(const struct interface *ifp1,
|
||||
}
|
||||
|
||||
/* Create new interface structure. */
|
||||
struct interface *if_create(const char *name, vrf_id_t vrf_id)
|
||||
static struct interface *if_create_backend(const char *name, ifindex_t ifindex,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf *vrf = vrf_get(vrf_id, NULL);
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = XCALLOC(MTYPE_IF, sizeof(struct interface));
|
||||
ifp->ifindex = IFINDEX_INTERNAL;
|
||||
|
||||
assert(name);
|
||||
strlcpy(ifp->name, name, sizeof(ifp->name));
|
||||
ifp->vrf_id = vrf_id;
|
||||
IFNAME_RB_INSERT(vrf, ifp);
|
||||
|
||||
if (name) {
|
||||
strlcpy(ifp->name, name, sizeof(ifp->name));
|
||||
IFNAME_RB_INSERT(vrf, ifp);
|
||||
} else
|
||||
ifp->name[0] = '\0';
|
||||
|
||||
if (ifindex != IFINDEX_INTERNAL)
|
||||
if_set_index(ifp, ifindex);
|
||||
else
|
||||
ifp->ifindex = ifindex; /* doesn't add it to the list */
|
||||
|
||||
ifp->connected = list_new();
|
||||
ifp->connected->del = (void (*)(void *))connected_free;
|
||||
|
||||
@ -158,6 +166,16 @@ struct interface *if_create(const char *name, vrf_id_t vrf_id)
|
||||
return ifp;
|
||||
}
|
||||
|
||||
struct interface *if_create(const char *name, vrf_id_t vrf_id)
|
||||
{
|
||||
return if_create_backend(name, IFINDEX_INTERNAL, vrf_id);
|
||||
}
|
||||
|
||||
struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
|
||||
{
|
||||
return if_create_backend(NULL, ifindex, vrf_id);
|
||||
}
|
||||
|
||||
/* Create new interface structure. */
|
||||
void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
|
||||
{
|
||||
@ -302,6 +320,23 @@ struct interface *if_lookup_by_name_all_vrf(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct interface *ifp;
|
||||
|
||||
if (ifindex == IFINDEX_INTERNAL)
|
||||
return NULL;
|
||||
|
||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
|
||||
ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
|
||||
if (ifp)
|
||||
return ifp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Lookup interface by IPv4 address. */
|
||||
struct interface *if_lookup_exact_address(void *src, int family,
|
||||
vrf_id_t vrf_id)
|
||||
@ -447,6 +482,34 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id)
|
||||
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_index(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;
|
||||
}
|
||||
|
||||
void if_set_index(struct interface *ifp, ifindex_t ifindex)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
|
3
lib/if.h
3
lib/if.h
@ -478,7 +478,9 @@ 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);
|
||||
extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
|
||||
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_lookup_by_index_all_vrf(ifindex_t);
|
||||
extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
|
||||
vrf_id_t vrf_id);
|
||||
extern struct connected *if_lookup_address(void *matchaddr, int family,
|
||||
@ -493,6 +495,7 @@ size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,
|
||||
extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
|
||||
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 void if_set_index(struct interface *ifp, ifindex_t ifindex);
|
||||
|
||||
/* Delete the interface, but do not free the structure, and leave it in the
|
||||
|
@ -590,7 +590,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
||||
char *kind = NULL;
|
||||
char *desc = NULL;
|
||||
char *slave_kind = NULL;
|
||||
struct zebra_ns *zns;
|
||||
struct zebra_ns *zns = NULL;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
|
||||
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
|
||||
@ -598,6 +598,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
||||
ifindex_t link_ifindex = IFINDEX_INTERNAL;
|
||||
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
|
||||
struct zebra_if *zif;
|
||||
struct vrf *vrf = NULL;
|
||||
|
||||
zns = zebra_ns_lookup(ns_id);
|
||||
ifi = NLMSG_DATA(h);
|
||||
@ -681,9 +682,17 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
|
||||
if (tb[IFLA_LINK])
|
||||
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
|
||||
|
||||
/* Add interface. */
|
||||
ifp = if_get_by_name(name, vrf_id);
|
||||
set_ifindex(ifp, ifi->ifi_index, zns);
|
||||
vrf = vrf_get(vrf_id, NULL);
|
||||
/* 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);
|
||||
set_ifindex(ifp, ifi->ifi_index, zns); /* add it to ns struct */
|
||||
strlcpy(ifp->name, name, sizeof(ifp->name));
|
||||
IFNAME_RB_INSERT(vrf, ifp);
|
||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||
ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
|
||||
ifp->metric = 0;
|
||||
|
@ -99,15 +99,18 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
|
||||
br_slave->br_if = NULL;
|
||||
}
|
||||
|
||||
void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave)
|
||||
void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
struct interface *bond_if;
|
||||
|
||||
/* TODO: Handle change of master */
|
||||
bond_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
|
||||
bond_slave->bond_ifindex);
|
||||
bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex);
|
||||
if (bond_if)
|
||||
bond_slave->bond_if = bond_if;
|
||||
else
|
||||
bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex,
|
||||
vrf_id);
|
||||
}
|
||||
|
||||
void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
|
||||
@ -282,7 +285,7 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
|
||||
|
||||
/* Set up or remove link with master */
|
||||
if (bond_ifindex != IFINDEX_INTERNAL)
|
||||
zebra_l2_map_slave_to_bond(&zif->bondslave_info);
|
||||
zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id);
|
||||
else if (old_bond_ifindex != IFINDEX_INTERNAL)
|
||||
zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave);
|
||||
extern void
|
||||
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
|
||||
extern void
|
||||
zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave);
|
||||
zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, vrf_id_t);
|
||||
extern void
|
||||
zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave);
|
||||
extern void zebra_l2_bridge_add_update(struct interface *ifp,
|
||||
|
Loading…
Reference in New Issue
Block a user