diff --git a/lib/zclient.c b/lib/zclient.c index 5ca5849948..a1e7194890 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -4487,11 +4487,9 @@ static int zclient_neigh_ip_read_entry(struct stream *s, struct ipaddr *add) return -1; } -int zclient_neigh_ip_encode(struct stream *s, - uint16_t cmd, - union sockunion *in, - union sockunion *out, - struct interface *ifp) +int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in, + union sockunion *out, struct interface *ifp, + int ndm_state) { int ret = 0; @@ -4506,7 +4504,7 @@ int zclient_neigh_ip_encode(struct stream *s, stream_putc(s, AF_UNSPEC); stream_putl(s, ifp->ifindex); if (out) - stream_putl(s, ZEBRA_NEIGH_STATE_REACHABLE); + stream_putl(s, ndm_state); else stream_putl(s, ZEBRA_NEIGH_STATE_FAILED); return ret; diff --git a/lib/zclient.h b/lib/zclient.h index a25c5800b7..71187ccae7 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -856,9 +856,18 @@ extern struct zclient_options zclient_options_default; * ip_in is the underlay IP, ip_out is the tunnel dest * index stands for the index of the interface * ndm state stands for the NDM value in netlink + * (see linux/neighbour.h) */ +#define ZEBRA_NEIGH_STATE_INCOMPLETE (0x01) #define ZEBRA_NEIGH_STATE_REACHABLE (0x02) -#define ZEBRA_NEIGH_STATE_FAILED (0x20) +#define ZEBRA_NEIGH_STATE_STALE (0x04) +#define ZEBRA_NEIGH_STATE_DELAY (0x08) +#define ZEBRA_NEIGH_STATE_PROBE (0x10) +#define ZEBRA_NEIGH_STATE_FAILED (0x20) +#define ZEBRA_NEIGH_STATE_NOARP (0x40) +#define ZEBRA_NEIGH_STATE_PERMANENT (0x80) +#define ZEBRA_NEIGH_STATE_NONE (0x00) + struct zapi_neigh_ip { int cmd; struct ipaddr ip_in; @@ -867,11 +876,9 @@ struct zapi_neigh_ip { uint32_t ndm_state; }; int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api); -int zclient_neigh_ip_encode(struct stream *s, - uint16_t cmd, - union sockunion *in, - union sockunion *out, - struct interface *ifp); +int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in, + union sockunion *out, struct interface *ifp, + int ndm_state); /* * We reserve the top 4 bits for l2-NHG, everything else diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index ee8db277d9..12a2fc2fa0 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -452,7 +452,8 @@ void nhrp_send_zebra_nbr(union sockunion *in, stream_reset(s); zclient_neigh_ip_encode(s, out ? ZEBRA_NEIGH_IP_ADD : ZEBRA_NEIGH_IP_DEL, in, out, - ifp); + ifp, out ? ZEBRA_NEIGH_STATE_REACHABLE + : ZEBRA_NEIGH_STATE_FAILED); stream_putw_at(s, 0, stream_get_endp(s)); zclient_send_message(zclient); } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 48ccf91ec7..a8b4b54d29 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3658,6 +3658,15 @@ static void netlink_handle_5549(struct ndmsg *ndm, struct zebra_if *zif, #define NUD_LOCAL_ACTIVE \ (NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE) +static int netlink_nbr_entry_state_to_zclient(int nbr_state) +{ + /* an exact match is done between + * - netlink neighbor state values: NDM_XXX (see in linux/neighbour.h) + * - zclient neighbor state values: ZEBRA_NEIGH_STATE_XXX + * (see in lib/zclient.h) + */ + return nbr_state; +} static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) { struct ndmsg *ndm; @@ -3747,8 +3756,10 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) &mac, l2_len); } else sockunion_family(&link_layer_ipv4) = AF_UNSPEC; - zsend_nhrp_neighbor_notify(cmd, ifp, &ip, ndm->ndm_state, - &link_layer_ipv4); + zsend_nhrp_neighbor_notify( + cmd, ifp, &ip, + netlink_nbr_entry_state_to_zclient(ndm->ndm_state), + &link_layer_ipv4); } if (h->nlmsg_type == RTM_GETNEIGH) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index ddd6a74c0b..6666b3525e 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -997,7 +997,8 @@ void zsend_nhrp_neighbor_notify(int cmd, struct interface *ifp, continue; s = stream_new(ZEBRA_MAX_PACKET_SIZ); - zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp); + zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp, + ndm_state); stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); }