aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat44-ed/nat44_ed_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed_api.c')
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_api.c148
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