summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vat/api_format.c62
-rw-r--r--src/vnet/ip/ip.api11
-rw-r--r--src/vnet/ip/ip_api.c26
-rw-r--r--src/vnet/ip/lookup.c139
-rw-r--r--src/vnet/ip/lookup.h10
-rw-r--r--src/vpp/api/custom_dump.c17
6 files changed, 243 insertions, 22 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index c972c192db3..0651be97c62 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -5305,7 +5305,8 @@ _(tcp_configure_src_addresses_reply) \
_(app_namespace_add_del_reply) \
_(dns_enable_disable_reply) \
_(dns_name_server_add_del_reply) \
-_(session_rule_add_del_reply)
+_(session_rule_add_del_reply) \
+_(ip_container_proxy_add_del_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -5627,7 +5628,8 @@ _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply) \
_(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply) \
_(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply) \
_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
-_(SESSION_RULES_DETAILS, session_rules_details)
+_(SESSION_RULES_DETAILS, session_rules_details) \
+_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
#define foreach_standalone_reply_msg \
_(SW_INTERFACE_EVENT, sw_interface_event) \
@@ -21748,6 +21750,61 @@ api_session_rules_dump (vat_main_t * vam)
}
static int
+api_ip_container_proxy_add_del (vat_main_t * vam)
+{
+ vl_api_ip_container_proxy_add_del_t *mp;
+ unformat_input_t *i = vam->input;
+ u32 plen = ~0, sw_if_index = ~0;
+ ip4_address_t ip4;
+ ip6_address_t ip6;
+ u8 is_ip4 = 1;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "add"))
+ ;
+ if (unformat (i, "%U", unformat_ip4_address, &ip4))
+ {
+ is_ip4 = 1;
+ plen = 32;
+ }
+ else if (unformat (i, "%U", unformat_ip6_address, &ip6))
+ {
+ is_ip4 = 0;
+ plen = 128;
+ }
+ else if (unformat (i, "sw_if_index %u", &sw_if_index))
+ ;
+ else
+ break;
+ }
+ if (sw_if_index == ~0 || plen == ~0)
+ {
+ errmsg ("address and sw_if_index must be set");
+ return -99;
+ }
+
+ M (IP_CONTAINER_PROXY_ADD_DEL, mp);
+
+ mp->is_ip4 = is_ip4;
+ mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
+ mp->plen = plen;
+ mp->is_add = is_add;
+ if (is_ip4)
+ clib_memcpy (mp->ip, &ip4, sizeof (ip4));
+ else
+ clib_memcpy (mp->ip, &ip6, sizeof (ip6));
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
q_or_quit (vat_main_t * vam)
{
#if VPP_API_TEST_BUILTIN == 0
@@ -22558,6 +22615,7 @@ _(dns_resolve_name, "<hostname>") \
_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
"<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
_(session_rules_dump, "") \
+_(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
/* List of command functions, CLI names map directly to functions */
#define foreach_cli_function \
diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api
index 67258ee4fe9..df3ae9646c4 100644
--- a/src/vnet/ip/ip.api
+++ b/src/vnet/ip/ip.api
@@ -584,6 +584,17 @@ autoreply define ip_punt_redirect
u8 nh[16];
};
+autoreply define ip_container_proxy_add_del
+{
+ u32 client_index;
+ u32 context;
+ u8 ip[16];
+ u8 is_ip4;
+ u8 plen;
+ u32 sw_if_index;
+ u8 is_add;
+};
+
/*
* Local Variables:
* eval: (c-set-style "gnu")
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 4b7af3bc62d..fad518f18a5 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -79,7 +79,8 @@ _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
_(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
_(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
- sw_interface_ip6_set_link_local_address)
+ sw_interface_ip6_set_link_local_address) \
+_(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del )
extern void stats_dslock_with_hint (int hint, int tag);
extern void stats_dsunlock (void);
@@ -1849,6 +1850,29 @@ vl_api_mfib_signal_dump_t_handler (vl_api_mfib_signal_dump_t * mp)
;
}
+static void
+ vl_api_ip_container_proxy_add_del_t_handler
+ (vl_api_ip_container_proxy_add_del_t * mp)
+{
+ vl_api_ip_container_proxy_add_del_reply_t *rmp;
+ vnet_ip_container_proxy_args_t args;
+ int rv = 0;
+ clib_error_t *error;
+
+ memset (&args, 0, sizeof (args));
+ ip_set (&args.prefix.fp_addr, mp->ip, mp->is_ip4);
+ args.prefix.fp_len = mp->plen ? mp->plen : (mp->is_ip4 ? 32 : 128);
+ args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
+ args.is_add = mp->is_add;
+ if ((error = vnet_ip_container_proxy_add_del (&args)))
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
+
+ REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
+}
+
#define vl_msg_name_crc_list
#include <vnet/ip/ip.api.h>
#undef vl_msg_name_crc_list
diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c
index 61350b4f0d8..3d5dc36c9a0 100644
--- a/src/vnet/ip/lookup.c
+++ b/src/vnet/ip/lookup.c
@@ -1435,6 +1435,64 @@ VLIB_CLI_COMMAND (ip_probe_neighbor_command, static) = {
/* *INDENT-ON* */
clib_error_t *
+vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t * args)
+{
+ u32 fib_index;
+
+ if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index))
+ return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0,
+ "invalid sw_if_index");
+
+ fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto,
+ args->sw_if_index);
+ if (args->is_add)
+ {
+ dpo_id_t proxy_dpo = DPO_INVALID;
+ l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto),
+ args->sw_if_index, &proxy_dpo);
+ fib_table_entry_special_dpo_add (fib_index,
+ &args->prefix,
+ FIB_SOURCE_PROXY,
+ FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo);
+ dpo_reset (&proxy_dpo);
+ }
+ else
+ {
+ fib_table_entry_special_remove (fib_index, &args->prefix,
+ FIB_SOURCE_PROXY);
+ }
+ return 0;
+}
+
+u8
+ip_container_proxy_is_set (fib_prefix_t * pfx, u32 sw_if_index)
+{
+ u32 fib_index;
+ fib_node_index_t fei;
+ const dpo_id_t *dpo;
+ l3_proxy_dpo_t *l3p;
+ load_balance_t *lb0;
+
+ fib_index = fib_table_get_table_id_for_sw_if_index (pfx->fp_proto,
+ sw_if_index);
+ if (fib_index == ~0)
+ return 0;
+
+ fei = fib_table_lookup_exact_match (fib_index, pfx);
+ if (fei == FIB_NODE_INDEX_INVALID)
+ return 0;
+
+ dpo = fib_entry_contribute_ip_forwarding (fei);
+ lb0 = load_balance_get (dpo->dpoi_index);
+ dpo = load_balance_get_bucket_i (lb0, 0);
+ if (dpo->dpoi_type != DPO_L3_PROXY)
+ return 0;
+
+ l3p = l3_proxy_dpo_get (dpo->dpoi_index);
+ return (l3p->l3p_sw_if_index == sw_if_index);
+}
+
+clib_error_t *
ip_container_cmd (vlib_main_t * vm,
unformat_input_t * main_input, vlib_cli_command_t * cmd)
{
@@ -1443,7 +1501,6 @@ ip_container_cmd (vlib_main_t * vm,
u32 is_del;
vnet_main_t *vnm;
- u32 fib_index;
u32 sw_if_index;
vnm = vnet_get_main ();
@@ -1482,24 +1539,13 @@ ip_container_cmd (vlib_main_t * vm,
return (clib_error_return (0, "no interface"));
}
- fib_index = fib_table_get_table_id_for_sw_if_index (pfx.fp_proto,
- sw_if_index);
-
- if (is_del)
- fib_table_entry_special_remove (fib_index, &pfx, FIB_SOURCE_PROXY);
- else
- {
- dpo_id_t proxy_dpo = DPO_INVALID;
-
- l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (pfx.fp_proto),
- sw_if_index, &proxy_dpo);
-
- fib_table_entry_special_dpo_add (fib_index,
- &pfx,
- FIB_SOURCE_PROXY,
- FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo);
- }
-
+ vnet_ip_container_proxy_args_t args = {
+ .prefix = pfx,
+ .sw_if_index = sw_if_index,
+ .is_add = !is_del,
+ };
+ vnet_ip_container_proxy_add_del (&args);
+ unformat_free (line_input);
return (NULL);
}
@@ -1512,6 +1558,61 @@ VLIB_CLI_COMMAND (ip_container_command_node, static) = {
};
/* *INDENT-ON* */
+clib_error_t *
+show_ip_container_cmd_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ vnet_main_t *vnm = vnet_get_main ();
+ fib_prefix_t pfx;
+ u32 sw_if_index = ~0;
+ u8 has_proxy;
+
+ if (!unformat_user (main_input, unformat_line_input, line_input))
+ return 0;
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ pfx.fp_len = 32;
+ }
+ else if (unformat (line_input, "%U",
+ unformat_ip6_address, &pfx.fp_addr.ip6))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ pfx.fp_len = 128;
+ }
+ else if (unformat (line_input, "%U",
+ unformat_vnet_sw_interface, vnm, &sw_if_index))
+ ;
+ else
+ return (clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input));
+ }
+
+ if (~0 == sw_if_index)
+ {
+ vlib_cli_output (vm, "no interface");
+ return (clib_error_return (0, "no interface"));
+ }
+
+ has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index);
+ vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off");
+
+ unformat_free (line_input);
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (show_ip_container_command, static) = {
+ .path = "show ip container",
+ .function = show_ip_container_cmd_fn,
+ .short_help = "show ip container <address> <interface>",
+ .is_mp_safe = 1,
+};
+/* *INDENT-ON* */
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vnet/ip/lookup.h b/src/vnet/ip/lookup.h
index 28a4bd8f755..a89546f5d92 100644
--- a/src/vnet/ip/lookup.h
+++ b/src/vnet/ip/lookup.h
@@ -211,6 +211,16 @@ do { \
} while (0)
/* *INDENT-ON* */
+typedef struct _vnet_ip_container_proxy_args
+{
+ fib_prefix_t prefix;
+ u32 sw_if_index;
+ u8 is_add;
+} vnet_ip_container_proxy_args_t;
+
+clib_error_t *vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t
+ * args);
+
void ip_lookup_init (ip_lookup_main_t * lm, u32 ip_lookup_node_index);
#endif /* included_ip_lookup_h */
diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c
index 4ec19e50408..928ca76dc6e 100644
--- a/src/vpp/api/custom_dump.c
+++ b/src/vpp/api/custom_dump.c
@@ -3231,6 +3231,23 @@ static void *vl_api_session_rule_add_del_t_print
FINISH;
}
+static void *vl_api_ip_container_proxy_add_del_t_print
+ (vl_api_ip_container_proxy_add_del_t * mp, void *handle)
+{
+ u8 *s;
+ s = format (0, "SCRIPT: ip_container_proxy_add_del ");
+ if (mp->is_ip4)
+ s = format (s, "is_add %d address %U/%d sw_if_index %d",
+ mp->is_add, format_ip4_address,
+ (ip4_address_t *) mp->ip, mp->plen, mp->sw_if_index);
+ else
+ s = format (s, "is_add %d address %U/%d sw_if_index %d",
+ mp->is_add, format_ip6_address,
+ (ip6_address_t *) mp->ip, mp->plen, mp->sw_if_index);
+ FINISH;
+}
+
+
#define foreach_custom_print_no_arg_function \
_(lisp_eid_table_vni_dump) \
_(lisp_map_resolver_dump) \