+u32
+session_rule_tag_key_index (u32 ri, u8 is_ip4)
+{
+ return ((ri << 1) | is_ip4);
+}
+
+void
+session_rule_tag_key_index_parse (u32 rti_key, u32 * ri, u8 * is_ip4)
+{
+ *is_ip4 = rti_key & 1;
+ *ri = rti_key >> 1;
+}
+
+u8 *
+session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri, u8 is_ip4)
+{
+ uword *tip;
+ session_rule_tag_t *rt;
+
+ tip =
+ hash_get (srt->tags_by_rules, session_rule_tag_key_index (ri, is_ip4));
+ if (tip)
+ {
+ rt = pool_elt_at_index (srt->rule_tags, *tip);
+ return rt->tag;
+ }
+ return 0;
+}
+
+void
+session_rules_table_add_del_tag (session_rules_table_t * srt, u8 * tag,
+ u32 rule_index, u8 is_ip4, u8 is_add)
+{
+ uword *rip, *rtip;
+ session_rule_tag_t *rt;
+ u32 rti_key;
+
+ if (tag == 0)
+ return;
+ if (is_add)
+ {
+ pool_get (srt->rule_tags, rt);
+ rt->tag = vec_dup (tag);
+ hash_set_mem (srt->rules_by_tag, rt->tag, rule_index);
+ rti_key = session_rule_tag_key_index (rule_index, is_ip4);
+ hash_set (srt->tags_by_rules, rti_key, rt - srt->rule_tags);
+ }
+ else
+ {
+ rip = hash_get_mem (srt->rules_by_tag, tag);
+ if (!rip)
+ {
+ clib_warning ("tag has no rule associated");
+ return;
+ }
+ rti_key = session_rule_tag_key_index (*rip, is_ip4);
+ rtip = hash_get (srt->tags_by_rules, rti_key);
+ if (!rtip)
+ {
+ clib_warning ("rule has no tag associated");
+ return;
+ }
+ rt = pool_elt_at_index (srt->rule_tags, *rtip);
+ ASSERT (rt);
+ hash_unset_mem (srt->rules_by_tag, tag);
+ hash_unset (srt->tags_by_rules, rti_key);
+ pool_put (srt->rule_tags, rt);
+ }
+}
+
+u32
+session_rules_table_rule_for_tag (session_rules_table_t * srt, u8 * tag)
+{
+ uword *rp;
+ if (tag == 0)
+ return SESSION_RULES_TABLE_INVALID_INDEX;
+ rp = hash_get_mem (srt->rules_by_tag, tag);
+ return (rp == 0 ? SESSION_RULES_TABLE_INVALID_INDEX : *rp);
+}
+