+static void
+gre_nhrp_mk_key (const gre_tunnel_t * t,
+ const nhrp_entry_t * ne, gre_tunnel_key_t * key)
+{
+ const fib_prefix_t *nh;
+
+ nh = nhrp_entry_get_nh (ne);
+
+ /* construct the key using mode P2P so it can be found in the DP */
+ if (FIB_PROTOCOL_IP4 == nh->fp_proto)
+ gre_mk_key4 (t->tunnel_src.ip4,
+ nh->fp_addr.ip4,
+ nhrp_entry_get_fib_index (ne),
+ t->type, GRE_TUNNEL_MODE_P2P, 0, &key->gtk_v4);
+ else
+ gre_mk_key6 (&t->tunnel_src.ip6,
+ &nh->fp_addr.ip6,
+ nhrp_entry_get_fib_index (ne),
+ t->type, GRE_TUNNEL_MODE_P2P, 0, &key->gtk_v6);
+}
+
+static void
+gre_nhrp_entry_added (const nhrp_entry_t * ne)
+{
+ gre_main_t *gm = &gre_main;
+ gre_tunnel_key_t key;
+ gre_tunnel_t *t;
+ u32 sw_if_index;
+ u32 t_idx;
+
+ sw_if_index = nhrp_entry_get_sw_if_index (ne);
+ if (vec_len (gm->tunnel_index_by_sw_if_index) < sw_if_index)
+ return;
+
+ t_idx = gm->tunnel_index_by_sw_if_index[sw_if_index];
+
+ if (INDEX_INVALID == t_idx)
+ return;
+
+ t = pool_elt_at_index (gm->tunnels, t_idx);
+
+ gre_nhrp_mk_key (t, ne, &key);
+ gre_tunnel_db_add (t, &key);
+}
+
+static void
+gre_nhrp_entry_deleted (const nhrp_entry_t * ne)
+{
+ gre_main_t *gm = &gre_main;
+ gre_tunnel_key_t key;
+ gre_tunnel_t *t;
+ u32 sw_if_index;
+ u32 t_idx;
+
+ sw_if_index = nhrp_entry_get_sw_if_index (ne);
+ if (vec_len (gm->tunnel_index_by_sw_if_index) < sw_if_index)
+ return;
+
+ t_idx = gm->tunnel_index_by_sw_if_index[sw_if_index];
+
+ if (INDEX_INVALID == t_idx)
+ return;
+
+ t = pool_elt_at_index (gm->tunnels, t_idx);
+
+ gre_nhrp_mk_key (t, ne, &key);
+ gre_tunnel_db_remove (t, &key);
+}
+
+static walk_rc_t
+gre_tunnel_delete_nhrp_walk (index_t nei, void *ctx)
+{
+ gre_tunnel_t *t = ctx;
+ gre_tunnel_key_t key;
+
+ gre_nhrp_mk_key (t, nhrp_entry_get (nei), &key);
+ gre_tunnel_db_remove (t, &key);
+
+ return (WALK_CONTINUE);
+}
+
+static walk_rc_t
+gre_tunnel_add_nhrp_walk (index_t nei, void *ctx)
+{
+ gre_tunnel_t *t = ctx;
+ gre_tunnel_key_t key;
+
+ gre_nhrp_mk_key (t, nhrp_entry_get (nei), &key);
+ gre_tunnel_db_add (t, &key);
+
+ return (WALK_CONTINUE);
+}
+