diff options
Diffstat (limited to 'nhrpd/nhrp_route.c')
-rw-r--r-- | nhrpd/nhrp_route.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 23fa0771e..1f513b7c0 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -380,6 +380,7 @@ void nhrp_zebra_init(void) zclient->neighbor_added = nhrp_neighbor_operation; zclient->neighbor_removed = nhrp_neighbor_operation; zclient->neighbor_get = nhrp_neighbor_operation; + zclient->gre_update = nhrp_gre_update; zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs); } @@ -412,6 +413,32 @@ void nhrp_send_zebra_configure_arp(struct interface *ifp, int family) zclient_send_message(zclient); } +void nhrp_send_zebra_gre_source_set(struct interface *ifp, + unsigned int link_idx, + vrf_id_t link_vrf_id) +{ + struct stream *s; + + if (!zclient || zclient->sock < 0) { + zlog_err("%s : zclient not ready", __func__); + return; + } + if (link_idx == IFINDEX_INTERNAL || link_vrf_id == VRF_UNKNOWN) { + /* silently ignore */ + return; + } + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, + ZEBRA_GRE_SOURCE_SET, + ifp->vrf_id); + stream_putl(s, ifp->ifindex); + stream_putl(s, link_idx); + stream_putl(s, link_vrf_id); + stream_putw_at(s, 0, stream_get_endp(s)); + zclient_send_message(zclient); +} + void nhrp_send_zebra_nbr(union sockunion *in, union sockunion *out, struct interface *ifp) @@ -429,6 +456,11 @@ void nhrp_send_zebra_nbr(union sockunion *in, zclient_send_message(zclient); } +int nhrp_send_zebra_gre_request(struct interface *ifp) +{ + return zclient_send_zebra_gre_request(zclient, ifp); +} + void nhrp_zebra_terminate(void) { nhrp_zebra_register_neigh(VRF_DEFAULT, AFI_IP, false); @@ -441,3 +473,48 @@ void nhrp_zebra_terminate(void) route_table_finish(zebra_rib[AFI_IP]); route_table_finish(zebra_rib[AFI_IP6]); } + +void nhrp_gre_update(ZAPI_CALLBACK_ARGS) +{ + struct stream *s; + struct nhrp_gre_info gre_info, *val; + struct interface *ifp; + + /* result */ + s = zclient->ibuf; + if (vrf_id != VRF_DEFAULT) + return; + + /* read GRE information */ + STREAM_GETL(s, gre_info.ifindex); + STREAM_GETL(s, gre_info.ikey); + STREAM_GETL(s, gre_info.okey); + STREAM_GETL(s, gre_info.ifindex_link); + STREAM_GETL(s, gre_info.vrfid_link); + STREAM_GETL(s, gre_info.vtep_ip.s_addr); + STREAM_GETL(s, gre_info.vtep_ip_remote.s_addr); + if (gre_info.ifindex == IFINDEX_INTERNAL) + val = NULL; + else + val = hash_lookup(nhrp_gre_list, &gre_info); + if (val) { + if (gre_info.vtep_ip.s_addr != val->vtep_ip.s_addr || + gre_info.vrfid_link != val->vrfid_link || + gre_info.ifindex_link != val->ifindex_link || + gre_info.ikey != val->ikey || + gre_info.okey != val->okey) { + /* update */ + memcpy(val, &gre_info, sizeof(struct nhrp_gre_info)); + } + } else { + val = nhrp_gre_info_alloc(&gre_info); + } + ifp = if_lookup_by_index(gre_info.ifindex, vrf_id); + debugf(NHRP_DEBUG_EVENT, "%s: gre interface %d vr %d obtained from system", + ifp ? ifp->name : "<none>", gre_info.ifindex, vrf_id); + if (ifp) + nhrp_interface_update_nbma(ifp, val); + return; +stream_failure: + zlog_err("%s(): error reading response ..", __func__); +} |