diff options
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed_api.c')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_api.c | 148 |
1 files changed, 134 insertions, 14 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c index d4de4823025..ad00d11052b 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_api.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c @@ -426,9 +426,50 @@ vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp) return; pool_foreach (i, sm->interfaces) - { - send_nat44_interface_details(i, reg, mp->context); - } + { + send_nat44_interface_details (i, reg, mp->context); + } +} + +static_always_inline int +add_del_dummy_output_interface (u32 sw_if_index, u8 is_inside, u8 is_add) +{ + snat_main_t *sm = &snat_main; + snat_interface_t *i; + int rv = 1; + + pool_foreach (i, sm->output_feature_dummy_interfaces) + { + if (i->sw_if_index == sw_if_index) + { + if (!is_add) + { + pool_put (sm->output_feature_dummy_interfaces, i); + rv = 0; + } + goto done; + } + } + + if (is_add) + { + pool_get (sm->output_feature_dummy_interfaces, i); + i->sw_if_index = sw_if_index; + + if (is_inside) + { + i->flags |= NAT_INTERFACE_FLAG_IS_INSIDE; + } + else + { + i->flags |= NAT_INTERFACE_FLAG_IS_OUTSIDE; + } + + rv = 0; + } + +done: + return rv; } static void @@ -444,13 +485,20 @@ static void sw_if_index = ntohl (mp->sw_if_index); - if (mp->is_add) - { - rv = nat44_ed_add_output_interface (sw_if_index); - } - else + // register all interfaces in the dummy structure + rv = add_del_dummy_output_interface ( + sw_if_index, mp->flags & NAT_API_IS_INSIDE, mp->is_add); + + if (!(mp->flags & NAT_API_IS_INSIDE)) { - rv = nat44_ed_del_output_interface (sw_if_index); + if (mp->is_add) + { + rv = nat44_ed_add_output_interface (sw_if_index); + } + else + { + rv = nat44_ed_del_output_interface (sw_if_index); + } } BAD_SW_IF_INDEX_LABEL; @@ -473,7 +521,9 @@ send_nat44_interface_output_feature_details (snat_interface_t * i, rmp->context = context; if (nat44_ed_is_interface_inside (i)) - rmp->flags |= NAT_API_IS_INSIDE; + { + rmp->flags |= NAT_API_IS_INSIDE; + } vl_api_send_msg (reg, (u8 *) rmp); } @@ -490,10 +540,80 @@ static void if (!reg) return; - pool_foreach (i, sm->output_feature_interfaces) - { - send_nat44_interface_output_feature_details (i, reg, mp->context); - } + pool_foreach (i, sm->output_feature_dummy_interfaces) + { + send_nat44_interface_output_feature_details (i, reg, mp->context); + } +} + +static void +vl_api_nat44_ed_add_del_output_interface_t_handler ( + vl_api_nat44_ed_add_del_output_interface_t *mp) +{ + vl_api_nat44_ed_add_del_output_interface_reply_t *rmp; + snat_main_t *sm = &snat_main; + u32 sw_if_index; + int rv = 0; + + VALIDATE_SW_IF_INDEX (mp); + + sw_if_index = ntohl (mp->sw_if_index); + + if (mp->is_add) + { + rv = nat44_ed_add_output_interface (sw_if_index); + } + else + { + rv = nat44_ed_del_output_interface (sw_if_index); + } + + BAD_SW_IF_INDEX_LABEL; + REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_OUTPUT_INTERFACE_REPLY); +} + +#define vl_endianfun +#include <nat/nat44-ed/nat44_ed.api.h> +#undef vl_endianfun +static void +send_nat44_ed_output_interface_details (u32 index, vl_api_registration_t *rp, + u32 context) +{ + snat_main_t *sm = &snat_main; + vl_api_nat44_ed_output_interface_details_t *rmp; + snat_interface_t *i = + pool_elt_at_index (sm->output_feature_interfaces, index); + + /* Make sure every field is initiated (or don't skip the clib_memset()) */ + REPLY_MACRO_DETAILS4 ( + VL_API_NAT44_ED_OUTPUT_INTERFACE_DETAILS, rp, context, ({ + rmp->sw_if_index = i->sw_if_index; + + /* Endian hack until apigen registers _details + * endian functions */ + vl_api_nat44_ed_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_ed_output_interface_get_t_handler ( + vl_api_nat44_ed_output_interface_get_t *mp) +{ + vl_api_nat44_ed_output_interface_get_reply_t *rmp; + snat_main_t *sm = &snat_main; + i32 rv = 0; + + if (pool_elts (sm->output_feature_interfaces) == 0) + { + REPLY_MACRO (VL_API_NAT44_ED_OUTPUT_INTERFACE_GET_REPLY); + return; + } + + REPLY_AND_DETAILS_MACRO ( + VL_API_NAT44_ED_OUTPUT_INTERFACE_GET_REPLY, sm->output_feature_interfaces, + ({ send_nat44_ed_output_interface_details (cursor, rp, mp->context); })); } static void |