diff --git a/lib/zclient.c b/lib/zclient.c index b1aea55afa..e2f99aebf3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3931,6 +3931,11 @@ static int zclient_read(struct thread *thread) (*zclient->neighbor_get)(command, zclient, length, vrf_id); break; + case ZEBRA_GRE_UPDATE: + if (zclient->gre_update) + (*zclient->gre_update)(command, zclient, + length, vrf_id); + break; default: break; } @@ -4252,3 +4257,28 @@ int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api) stream_failure: return -1; } + +int zclient_send_zebra_gre_request(struct zclient *client, + struct interface *ifp) +{ + struct stream *s; + ifindex_t idx_local; + int ret; + + if (!client || client->sock < 0) { + zlog_err("%s : zclient not ready", __func__); + return -1; + } + s = client->obuf; + stream_reset(s); + zclient_create_header(s, + ZEBRA_GRE_GET, + ifp->vrf_id); + stream_putl(s, ifp->ifindex); + stream_putw_at(s, 0, stream_get_endp(s)); + zclient_send_message(client); + return 0; +stream_failure: + zlog_err("%s(): error reading response ..", __func__); + return 0; +} diff --git a/lib/zclient.h b/lib/zclient.h index f9e1bdc370..8c27916542 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -396,6 +396,7 @@ struct zclient { void (*neighbor_added)(ZAPI_CALLBACK_ARGS); void (*neighbor_removed)(ZAPI_CALLBACK_ARGS); void (*neighbor_get)(ZAPI_CALLBACK_ARGS); + void (*gre_update)(ZAPI_CALLBACK_ARGS); }; /* Zebra API message flag. */ @@ -1231,6 +1232,8 @@ struct zapi_client_close_info { extern int zapi_client_close_notify_decode(struct stream *s, struct zapi_client_close_info *info); +extern int zclient_send_zebra_gre_request(struct zclient *client, + struct interface *ifp); #ifdef __cplusplus } #endif diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 645cb2bd0c..d36c6becd7 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3240,6 +3240,61 @@ stream_failure: return; } +static inline void zebra_gre_get(ZAPI_HANDLER_ARGS) +{ + struct stream *s; + ifindex_t idx; + struct interface *ifp; + struct zebra_if *zebra_if = NULL; + struct zebra_l2info_gre *gre_info; + struct interface *ifp_link = NULL; + vrf_id_t vrf_id_link = VRF_UNKNOWN; + vrf_id_t vrf_id = zvrf->vrf->vrf_id; + + s = msg; + STREAM_GETL(s, idx); + ifp = if_lookup_by_index(idx, vrf_id); + + if (ifp) + zebra_if = ifp->info; + + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, ZEBRA_GRE_UPDATE, vrf_id); + + if (ifp && IS_ZEBRA_IF_GRE(ifp) && zebra_if) { + gre_info = &zebra_if->l2info.gre; + + stream_putl(s, idx); + stream_putl(s, gre_info->ikey); + stream_putl(s, gre_info->ikey); + stream_putl(s, gre_info->ifindex_link); + + ifp_link = if_lookup_by_index_per_ns( + zebra_ns_lookup(gre_info->link_nsid), + gre_info->ifindex_link); + if (ifp_link) + vrf_id_link = ifp_link->vrf_id; + stream_putl(s, vrf_id_link); + stream_putl(s, gre_info->vtep_ip.s_addr); + stream_putl(s, gre_info->vtep_ip_remote.s_addr); + } else { + stream_putl(s, idx); + stream_putl(s, 0); + stream_putl(s, 0); + stream_putl(s, IFINDEX_INTERNAL); + stream_putl(s, VRF_UNKNOWN); + stream_putl(s, 0); + } + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); + zserv_send_message(client, s); + + return; + stream_failure: + return; +} + static inline void zebra_configure_arp(ZAPI_HANDLER_ARGS) { struct stream *s; @@ -3516,6 +3571,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_NHRP_NEIGH_REGISTER] = zebra_neigh_register, [ZEBRA_NHRP_NEIGH_UNREGISTER] = zebra_neigh_unregister, [ZEBRA_CONFIGURE_ARP] = zebra_configure_arp, + [ZEBRA_GRE_GET] = zebra_gre_get, [ZEBRA_GRE_SOURCE_SET] = zebra_gre_source_set, };