+static u32
+add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref,
+ ip_prefix_t * src_pref, u32 val, u8 is_add)
+{
+ u32 sfi, old_val = ~0;
+ gid_ip6_table_t *sfib;
+
+ sfi = ip6_lookup (&db->dst_ip6_table, vni, dst_pref);
+
+ if (is_add)
+ {
+ if (GID_LOOKUP_MISS == sfi)
+ {
+ pool_get (db->src_ip6_table_pool, sfib);
+ ip6_lookup_init (sfib);
+ add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref,
+ sfib - db->src_ip6_table_pool, is_add);
+ if (src_pref)
+ add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+ else
+ {
+ ip_prefix_t sp;
+ memset (&sp, 0, sizeof (sp));
+ add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
+ }
+ }
+ else
+ {
+ ASSERT (!pool_is_free_index (db->src_ip6_table_pool, sfi));
+ sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
+ if (src_pref)
+ {
+ old_val = ip6_lookup (sfib, 0, src_pref);
+ add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add);
+ }
+ else
+ {
+ ip_prefix_t sp;
+ memset (&sp, 0, sizeof (sp));
+ old_val =
+ add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add);
+ }
+ }
+ }
+ else
+ {
+ if (GID_LOOKUP_MISS != sfi)
+ {
+ add_del_ip6_key (&db->dst_ip6_table, vni, dst_pref, 0, is_add);
+ sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi);
+ if (src_pref)
+ old_val = add_del_ip6_key (sfib, 0, src_pref, 0, is_add);
+ else
+ {
+ ip_prefix_t sp;
+ memset (&sp, 0, sizeof (sp));
+ old_val = add_del_ip6_key (sfib, 0, &sp, 0, is_add);
+ }
+ }
+ else
+ clib_warning ("cannot delete dst mapping %U!", format_ip_prefix,
+ dst_pref);
+ }
+ return old_val;
+}
+
+static u32
+add_del_ip (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_key,
+ ip_prefix_t * src_key, u32 value, u8 is_add)
+{
+ switch (ip_prefix_version (dst_key))
+ {
+ case IP4:
+ return add_del_sd_ip4_key (db, vni, dst_key, src_key, value, is_add);
+ break;
+ case IP6:
+ return add_del_sd_ip6_key (db, vni, dst_key, src_key, value, is_add);
+ break;
+ default:
+ clib_warning ("address type %d not supported!",
+ ip_prefix_version (dst_key));
+ break;
+ }
+ return ~0;
+}
+
+static u32
+add_del_sd (gid_dictionary_t * db, u32 vni, source_dest_t * key, u32 value,
+ u8 is_add)
+{
+ switch (sd_dst_type (key))
+ {
+ case FID_ADDR_IP_PREF:
+ add_del_ip (db, vni, &sd_dst_ippref (key), &sd_src_ippref (key),
+ value, is_add);
+
+ case FID_ADDR_MAC:
+ return add_del_mac (&db->sd_mac_table, vni, sd_dst_mac (key),
+ sd_src_mac (key), value, is_add);
+
+ default:
+ clib_warning ("SD address type %d not supprted!", sd_dst_type (key));
+ break;
+ }
+
+ return ~0;
+}
+
+u32
+gid_dictionary_add_del (gid_dictionary_t * db, gid_address_t * key, u32 value,
+ u8 is_add)
+{
+ switch (gid_address_type (key))
+ {
+ case GID_ADDR_IP_PREFIX:
+ return add_del_ip (db, gid_address_vni (key), &gid_address_ippref (key),
+ 0, value, is_add);
+ case GID_ADDR_MAC:
+ return add_del_mac (&db->sd_mac_table, gid_address_vni (key),
+ gid_address_mac (key), 0, value, is_add);
+ case GID_ADDR_SRC_DST:
+ return add_del_sd (db, gid_address_vni (key), &gid_address_sd (key),
+ value, is_add);
+ default:
+ clib_warning ("address type %d not supported!", gid_address_type (key));
+ break;
+ }
+ return ~0;
+}
+