diff options
Diffstat (limited to 'src/plugins/nat/nat44-ei/nat44_ei_api.c')
-rw-r--r-- | src/plugins/nat/nat44-ei/nat44_ei_api.c | 278 |
1 files changed, 218 insertions, 60 deletions
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_api.c b/src/plugins/nat/nat44-ei/nat44_ei_api.c index 427140ffb92..c6d17c94205 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_api.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_api.c @@ -469,9 +469,9 @@ vl_api_nat44_ei_add_del_address_range_t_handler ( for (i = 0; i < count; i++) { if (is_add) - rv = nat44_ei_add_address (nm, &this_addr, vrf_id); + rv = nat44_ei_add_address (&this_addr, vrf_id); else - rv = nat44_ei_del_address (nm, this_addr, 0); + rv = nat44_ei_del_address (this_addr, 0); if (rv) goto send_reply; @@ -540,7 +540,7 @@ vl_api_nat44_ei_interface_add_del_feature_t_handler ( VALIDATE_SW_IF_INDEX (mp); - rv = nat44_ei_interface_add_del (sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, + rv = nat44_ei_add_del_interface (sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, is_del); BAD_SW_IF_INDEX_LABEL; @@ -588,19 +588,68 @@ vl_api_nat44_ei_interface_dump_t_handler (vl_api_nat44_ei_interface_dump_t *mp) } } +static_always_inline int +add_del_dummy_output_interface (u32 sw_if_index, u8 is_inside, u8 is_add) +{ + nat44_ei_main_t *nm = &nat44_ei_main; + nat44_ei_interface_t *i; + int rv = 1; + + pool_foreach (i, nm->output_feature_dummy_interfaces) + { + if (i->sw_if_index == sw_if_index) + { + if (!is_add) + { + pool_put (nm->output_feature_dummy_interfaces, i); + rv = 0; + } + goto done; + } + } + + if (is_add) + { + pool_get (nm->output_feature_dummy_interfaces, i); + i->sw_if_index = sw_if_index; + + if (is_inside) + { + i->flags |= NAT44_EI_INTERFACE_FLAG_IS_INSIDE; + } + else + { + i->flags |= NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE; + } + + rv = 0; + } + +done: + return rv; +} + static void vl_api_nat44_ei_interface_add_del_output_feature_t_handler ( vl_api_nat44_ei_interface_add_del_output_feature_t *mp) { - nat44_ei_main_t *nm = &nat44_ei_main; vl_api_nat44_ei_interface_add_del_output_feature_reply_t *rmp; - u32 sw_if_index = ntohl (mp->sw_if_index); + nat44_ei_main_t *nm = &nat44_ei_main; + u32 sw_if_index; int rv = 0; VALIDATE_SW_IF_INDEX (mp); - rv = nat44_ei_interface_add_del_output_feature ( - sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, !mp->is_add); + sw_if_index = ntohl (mp->sw_if_index); + + // register all interfaces in the dummy structure + rv = add_del_dummy_output_interface ( + sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, mp->is_add); + + if (!(mp->flags & NAT44_EI_IF_INSIDE)) + { + rv = nat44_ei_add_del_output_interface (sw_if_index, !mp->is_add); + } BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_NAT44_EI_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY); @@ -622,7 +671,9 @@ send_nat44_ei_interface_output_feature_details (nat44_ei_interface_t *i, rmp->context = context; if (nat44_ei_interface_is_inside (i)) - rmp->flags |= NAT44_EI_IF_INSIDE; + { + rmp->flags |= NAT44_EI_IF_INSIDE; + } vl_api_send_msg (reg, (u8 *) rmp); } @@ -639,49 +690,131 @@ vl_api_nat44_ei_interface_output_feature_dump_t_handler ( if (!reg) return; - pool_foreach (i, nm->output_feature_interfaces) + pool_foreach (i, nm->output_feature_dummy_interfaces) { send_nat44_ei_interface_output_feature_details (i, reg, mp->context); } } static void +vl_api_nat44_ei_add_del_output_interface_t_handler ( + vl_api_nat44_ei_add_del_output_interface_t *mp) +{ + vl_api_nat44_ei_add_del_output_interface_reply_t *rmp; + nat44_ei_main_t *nm = &nat44_ei_main; + u32 sw_if_index; + int rv = 0; + + VALIDATE_SW_IF_INDEX (mp); + + sw_if_index = ntohl (mp->sw_if_index); + + rv = nat44_ei_add_del_output_interface (sw_if_index, !mp->is_add); + + BAD_SW_IF_INDEX_LABEL; + REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_OUTPUT_INTERFACE_REPLY); +} + +#define vl_endianfun +#include <nat/nat44-ei/nat44_ei.api.h> +#undef vl_endianfun +static void +send_nat44_ei_output_interface_details (u32 index, vl_api_registration_t *rp, + u32 context) +{ + nat44_ei_main_t *nm = &nat44_ei_main; + vl_api_nat44_ei_output_interface_details_t *rmp; + nat44_ei_interface_t *i = + pool_elt_at_index (nm->output_feature_interfaces, index); + + /* Make sure every field is initiated (or don't skip the clib_memset()) */ + REPLY_MACRO_DETAILS4 ( + VL_API_NAT44_EI_OUTPUT_INTERFACE_DETAILS, rp, context, ({ + rmp->sw_if_index = i->sw_if_index; + + /* Endian hack until apigen registers _details + * endian functions */ + vl_api_nat44_ei_output_interface_details_t_endian (rmp); + rmp->_vl_msg_id = htons (rmp->_vl_msg_id); + rmp->context = htonl (rmp->context); + })); +} + +static void +vl_api_nat44_ei_output_interface_get_t_handler ( + vl_api_nat44_ei_output_interface_get_t *mp) +{ + vl_api_nat44_ei_output_interface_get_reply_t *rmp; + nat44_ei_main_t *nm = &nat44_ei_main; + i32 rv = 0; + + if (pool_elts (nm->output_feature_interfaces) == 0) + { + REPLY_MACRO (VL_API_NAT44_EI_OUTPUT_INTERFACE_GET_REPLY); + return; + } + + REPLY_AND_DETAILS_MACRO ( + VL_API_NAT44_EI_OUTPUT_INTERFACE_GET_REPLY, nm->output_feature_interfaces, + ({ send_nat44_ei_output_interface_details (cursor, rp, mp->context); })); +} + +static void vl_api_nat44_ei_add_del_static_mapping_t_handler ( vl_api_nat44_ei_add_del_static_mapping_t *mp) { - nat44_ei_main_t *nm = &nat44_ei_main; vl_api_nat44_ei_add_del_static_mapping_reply_t *rmp; - ip4_address_t local_addr, external_addr; - u16 local_port = 0, external_port = 0; - u32 vrf_id, external_sw_if_index; + + nat44_ei_main_t *nm = &nat44_ei_main; int rv = 0; - nat_protocol_t proto; + + ip4_address_t l_addr, e_addr, pool_addr = { 0 }; + u32 sw_if_index, flags = 0, vrf_id; + u16 l_port = 0, e_port = 0; + nat_protocol_t proto = 0; u8 *tag = 0; - memcpy (&local_addr.as_u8, mp->local_ip_address, 4); - memcpy (&external_addr.as_u8, mp->external_ip_address, 4); + memcpy (&l_addr.as_u8, mp->local_ip_address, 4); - if (!(mp->flags & NAT44_EI_ADDR_ONLY_MAPPING)) + if (mp->flags & NAT44_EI_ADDR_ONLY_MAPPING) { - local_port = mp->local_port; - external_port = mp->external_port; + flags |= NAT44_EI_SM_FLAG_ADDR_ONLY; + } + else + { + l_port = mp->local_port; + e_port = mp->external_port; + proto = ip_proto_to_nat_proto (mp->protocol); } - vrf_id = clib_net_to_host_u32 (mp->vrf_id); - external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index); - proto = ip_proto_to_nat_proto (mp->protocol); - - mp->tag[sizeof (mp->tag) - 1] = 0; - tag = format (0, "%s", mp->tag); - vec_terminate_c_string (tag); - - rv = nat44_ei_add_del_static_mapping ( - local_addr, external_addr, local_port, external_port, proto, - external_sw_if_index, vrf_id, mp->flags & NAT44_EI_ADDR_ONLY_MAPPING, 0, - tag, mp->is_add); + sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index); + if (sw_if_index != ~0) + { + e_addr.as_u32 = 0; + } + else + { + memcpy (&e_addr.as_u8, mp->external_ip_address, 4); + } - vec_free (tag); + vrf_id = clib_net_to_host_u32 (mp->vrf_id); + if (mp->is_add) + { + mp->tag[sizeof (mp->tag) - 1] = 0; + tag = format (0, "%s", mp->tag); + vec_terminate_c_string (tag); + + rv = nat44_ei_add_static_mapping (l_addr, e_addr, l_port, e_port, proto, + vrf_id, sw_if_index, flags, pool_addr, + tag); + vec_free (tag); + } + else + { + rv = nat44_ei_del_static_mapping (l_addr, e_addr, l_port, e_port, proto, + vrf_id, sw_if_index, flags); + } REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_STATIC_MAPPING_REPLY); } @@ -704,7 +837,7 @@ send_nat44_ei_static_mapping_details (nat44_ei_static_mapping_t *m, rmp->vrf_id = htonl (m->vrf_id); rmp->context = context; - if (nat44_ei_is_addr_only_static_mapping (m)) + if (is_sm_addr_only (m->flags)) { rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING; } @@ -738,7 +871,7 @@ send_nat44_ei_static_map_resolve_details (nat44_ei_static_map_resolve_t *m, rmp->vrf_id = htonl (m->vrf_id); rmp->context = context; - if (m->addr_only) + if (is_sm_addr_only (m->flags)) { rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING; } @@ -770,14 +903,14 @@ vl_api_nat44_ei_static_mapping_dump_t_handler ( pool_foreach (m, nm->static_mappings) { - if (!nat44_ei_is_identity_static_mapping (m)) + if (!is_sm_identity_nat (m->flags)) send_nat44_ei_static_mapping_details (m, reg, mp->context); } for (j = 0; j < vec_len (nm->to_resolve); j++) { rp = nm->to_resolve + j; - if (!rp->identity_nat) + if (!is_sm_identity_nat (rp->flags)) send_nat44_ei_static_map_resolve_details (rp, reg, mp->context); } } @@ -786,35 +919,56 @@ static void vl_api_nat44_ei_add_del_identity_mapping_t_handler ( vl_api_nat44_ei_add_del_identity_mapping_t *mp) { - nat44_ei_main_t *nm = &nat44_ei_main; vl_api_nat44_ei_add_del_identity_mapping_reply_t *rmp; - ip4_address_t addr; - u16 port = 0; - u32 vrf_id, sw_if_index; + + nat44_ei_main_t *nm = &nat44_ei_main; int rv = 0; - nat_protocol_t proto = NAT_PROTOCOL_OTHER; + + ip4_address_t addr, pool_addr = { 0 }; + u32 sw_if_index, flags, vrf_id; + nat_protocol_t proto = 0; + u16 port = 0; u8 *tag = 0; - if (!(mp->flags & NAT44_EI_ADDR_ONLY_MAPPING)) + flags = NAT44_EI_SM_FLAG_IDENTITY_NAT; + + if (mp->flags & NAT44_EI_ADDR_ONLY_MAPPING) + { + flags |= NAT44_EI_SM_FLAG_ADDR_ONLY; + } + else { port = mp->port; proto = ip_proto_to_nat_proto (mp->protocol); } - vrf_id = clib_net_to_host_u32 (mp->vrf_id); + sw_if_index = clib_net_to_host_u32 (mp->sw_if_index); if (sw_if_index != ~0) - addr.as_u32 = 0; + { + addr.as_u32 = 0; + } else - memcpy (&addr.as_u8, mp->ip_address, 4); - mp->tag[sizeof (mp->tag) - 1] = 0; - tag = format (0, "%s", mp->tag); - vec_terminate_c_string (tag); + { + memcpy (&addr.as_u8, mp->ip_address, 4); + } - rv = nat44_ei_add_del_static_mapping ( - addr, addr, port, port, proto, sw_if_index, vrf_id, - mp->flags & NAT44_EI_ADDR_ONLY_MAPPING, 1, tag, mp->is_add); + vrf_id = clib_net_to_host_u32 (mp->vrf_id); - vec_free (tag); + if (mp->is_add) + { + mp->tag[sizeof (mp->tag) - 1] = 0; + tag = format (0, "%s", mp->tag); + vec_terminate_c_string (tag); + + rv = nat44_ei_add_static_mapping (addr, addr, port, port, proto, vrf_id, + sw_if_index, flags, pool_addr, tag); + vec_free (tag); + } + else + { + rv = nat44_ei_del_static_mapping (addr, addr, port, port, proto, vrf_id, + sw_if_index, flags); + } REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_IDENTITY_MAPPING_REPLY); } @@ -833,7 +987,7 @@ send_nat44_ei_identity_mapping_details (nat44_ei_static_mapping_t *m, rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base); - if (nat44_ei_is_addr_only_static_mapping (m)) + if (is_sm_addr_only (m->flags)) rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING; clib_memcpy (rmp->ip_address, &(m->local_addr), 4); @@ -860,7 +1014,7 @@ send_nat44_ei_identity_map_resolve_details (nat44_ei_static_map_resolve_t *m, rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base); - if (m->addr_only) + if (is_sm_addr_only (m->flags)) rmp->flags = (vl_api_nat44_ei_config_flags_t) NAT44_EI_ADDR_ONLY_MAPPING; rmp->port = m->l_port; @@ -890,7 +1044,7 @@ vl_api_nat44_ei_identity_mapping_dump_t_handler ( pool_foreach (m, nm->static_mappings) { - if (nat44_ei_is_identity_static_mapping (m)) + if (is_sm_identity_nat (m->flags)) { pool_foreach_index (j, m->locals) { @@ -902,7 +1056,7 @@ vl_api_nat44_ei_identity_mapping_dump_t_handler ( for (j = 0; j < vec_len (nm->to_resolve); j++) { rp = nm->to_resolve + j; - if (rp->identity_nat) + if (is_sm_identity_nat (rp->flags)) send_nat44_ei_identity_map_resolve_details (rp, reg, mp->context); } } @@ -915,13 +1069,17 @@ vl_api_nat44_ei_add_del_interface_addr_t_handler ( vl_api_nat44_ei_add_del_interface_addr_reply_t *rmp; u32 sw_if_index = ntohl (mp->sw_if_index); int rv = 0; - u8 is_del; - - is_del = !mp->is_add; VALIDATE_SW_IF_INDEX (mp); - rv = nat44_ei_add_interface_address (nm, sw_if_index, is_del); + if (mp->is_add) + { + rv = nat44_ei_add_interface_address (sw_if_index); + } + else + { + rv = nat44_ei_del_interface_address (sw_if_index); + } BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_INTERFACE_ADDR_REPLY); |