- user_index = value.value;
- u = pool_elt_at_index (tnm->users, user_index);
- if (u->nsessions)
- {
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tnm->list_pool, head_index);
- elt_index = head->next;
- elt = pool_elt_at_index (tnm->list_pool, elt_index);
- ses_index = elt->value;
- while (ses_index != ~0)
- {
- s = pool_elt_at_index (tnm->sessions, ses_index);
- elt = pool_elt_at_index (tnm->list_pool, elt->next);
- ses_index = elt->value;
+ nat44_ei_del_resolve_record (l_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags);
+ }
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+ }
+
+ pool_get (nm->static_mappings, m);
+ clib_memset (m, 0, sizeof (*m));
+
+ m->flags = flags;
+ m->local_addr = l_addr;
+ m->external_addr = e_addr;
+
+ m->tag = vec_dup (tag);
+
+ if (!is_sm_addr_only (flags))
+ {
+ m->local_port = l_port;
+ m->external_port = e_port;
+ m->proto = proto;
+ }
+
+ if (is_sm_identity_nat (flags))
+ {
+ pool_get (m->locals, local);
+
+ local->vrf_id = vrf_id;
+ local->fib_index = fib_index;
+ }
+ else
+ {
+ m->vrf_id = vrf_id;
+ m->fib_index = fib_index;
+ }
+
+ init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, 0,
+ m - nm->static_mappings);
+ clib_bihash_add_del_8_8 (&nm->static_mapping_by_local, &kv, 1);
+
+ init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0,
+ m - nm->static_mappings);
+ clib_bihash_add_del_8_8 (&nm->static_mapping_by_external, &kv, 1);
+
+ if (nm->num_workers > 1)
+ {
+ // store worker index for this record
+ ip4_header_t ip = {
+ .src_address = m->local_addr,
+ };
+ worker_index = nat44_ei_get_in2out_worker_index (&ip, m->fib_index, 0);
+ vec_add1 (m->workers, worker_index);
+ }
+ else
+ {
+ worker_index = nm->num_workers;
+ }
+ delete_matching_dynamic_sessions (m, worker_index);
+
+ if (is_sm_addr_only (flags))
+ {
+ nat44_ei_add_del_addr_to_fib_foreach_out_if (&e_addr, 1);
+ }
+
+ return 0;
+}
+
+int
+nat44_ei_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
+ u16 l_port, u16 e_port, nat_protocol_t proto,
+ u32 vrf_id, u32 sw_if_index, u32 flags)
+{
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ clib_bihash_kv_8_8_t kv, value;
+ nat44_ei_lb_addr_port_t *local;
+ nat44_ei_static_mapping_t *m;
+ u32 fib_index = ~0;
+ nat44_ei_user_key_t u_key;
+
+ fail_if_disabled ();
+
+ if (is_sm_addr_only (flags))
+ {
+ e_port = l_port = proto = 0;
+ }
+
+ if (sw_if_index != ~0)
+ {
+ // this mapping is interface bound
+ ip4_address_t *first_int_addr;
+
+ // delete record registered for resolve
+ if (nat44_ei_del_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags))
+ {
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }