zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message

Unlike the other interface zapi messages, ZEBRA_INTERFACE_VRF_UPDATE
identifies interfaces using ifindexes and not interface names. This
is a problem because zebra always sends ZEBRA_INTERFACE_DOWN
and ZEBRA_INTERFACE_DELETE messages before sending
ZEBRA_INTERFACE_VRF_UPDATE, and the ZEBRA_INTERFACE_DELETE callback
from all daemons set the interface index to IFINDEX_INTERNAL. Hence,
when decoding a ZEBRA_INTERFACE_VRF_UPDATE message, the interface
lookup would always fail since the corresponding interface lost
its ifindex. Example (ospfd):

OSPF: Zebra: Interface[rt1-eth2] state change to down.
OSPF: Zebra: interface delete rt1-eth2 vrf default[0] index 8 flags 11143 metric 0 mtu 1500
OSPF: [EC 100663301] INTERFACE_VRF_UPDATE: Cannot find IF 8 in VRF 0

To fix this problem, use interface names instead of ifindexes to
indentify interfaces like the other interface zapi messages do.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2019-01-02 13:05:53 -02:00
parent d52fa66f0e
commit 91d227b7e3
2 changed files with 8 additions and 8 deletions

View File

@ -1770,19 +1770,19 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s,
vrf_id_t vrf_id, vrf_id_t vrf_id,
vrf_id_t *new_vrf_id) vrf_id_t *new_vrf_id)
{ {
unsigned int ifindex; char ifname[INTERFACE_NAMSIZ];
struct interface *ifp; struct interface *ifp;
vrf_id_t new_id; vrf_id_t new_id;
/* Get interface index. */ /* Read interface name. */
ifindex = stream_getl(s); stream_get(ifname, s, INTERFACE_NAMSIZ);
/* Lookup interface. */ /* Lookup interface. */
ifp = if_lookup_by_index(ifindex, vrf_id); ifp = if_lookup_by_name(ifname, vrf_id);
if (ifp == NULL) { if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE, flog_err(EC_LIB_ZAPI_ENCODE,
"INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d", "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
ifindex, vrf_id); ifname, vrf_id);
return NULL; return NULL;
} }

View File

@ -432,8 +432,8 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
/* Fill in the ifIndex of the interface and its new VRF (id) */ /* Fill in the name of the interface and its new VRF (id) */
stream_putl(s, ifp->ifindex); stream_put(s, ifp->name, INTERFACE_NAMSIZ);
stream_putl(s, vrf_id); stream_putl(s, vrf_id);
/* Write packet size. */ /* Write packet size. */