aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/tap
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2019-06-10 11:20:15 +0200
committerDamjan Marion <dmarion@me.com>2019-06-20 03:39:31 +0000
commit97d54ed43eb69f6ea731c02305ebe0ca0b1a5cc4 (patch)
tree1247bbd99b64313aa7dc9aa9fd51d822a42e31d8 /src/vnet/devices/tap
parent3a9f11e6d93c9839c7bb0aaa62662299165123d8 (diff)
tap: add support to configure tap interface host MTU size
This patch adds support to configure host mtu size using api, cli or startup.conf. Type: feature Change-Id: I8ab087d82dbe7dedc498825c1a3ea3fcb2cce030 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/vnet/devices/tap')
-rw-r--r--src/vnet/devices/tap/cli.c7
-rw-r--r--src/vnet/devices/tap/tap.c47
-rw-r--r--src/vnet/devices/tap/tap.h6
-rw-r--r--src/vnet/devices/tap/tapv2.api8
-rw-r--r--src/vnet/devices/tap/tapv2_api.c7
5 files changed, 73 insertions, 2 deletions
diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c
index 084fb908dc9..c74d24a12a9 100644
--- a/src/vnet/devices/tap/cli.c
+++ b/src/vnet/devices/tap/cli.c
@@ -76,6 +76,10 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
;
else if (unformat (line_input, "tx-ring-size %d", &args.tx_ring_sz))
;
+ else
+ if (unformat
+ (line_input, "host-mtu-size %d", &args.host_mtu_size))
+ args.host_mtu_set = 1;
else if (unformat (line_input, "no-gso"))
args.tap_flags &= ~TAP_FLAG_GSO;
else if (unformat (line_input, "gso"))
@@ -114,7 +118,8 @@ VLIB_CLI_COMMAND (tap_create_command, static) = {
"[rx-ring-size <size>] [tx-ring-size <size>] [host-ns <netns>] "
"[host-bridge <bridge-name>] [host-ip4-addr <ip4addr/mask>] "
"[host-ip6-addr <ip6-addr>] [host-ip4-gw <ip4-addr>] "
- "[host-ip6-gw <ip6-addr>] [host-if-name <name>] [no-gso|gso]",
+ "[host-ip6-gw <ip6-addr>] [host-mac-addr <host-mac-address>] "
+ "[host-if-name <name>] [host-mtu-size <size>] [no-gso|gso]",
.function = tap_create_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index 35f1f2a3451..8dc798a3cb3 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -361,6 +361,29 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
}
}
+ if (args->host_mtu_set)
+ {
+ args->error =
+ vnet_netlink_set_link_mtu (vif->ifindex, args->host_mtu_size);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ }
+ else if (tm->host_mtu_size != 0)
+ {
+ args->error =
+ vnet_netlink_set_link_mtu (vif->ifindex, tm->host_mtu_size);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ args->host_mtu_set = 1;
+ args->host_mtu_size = tm->host_mtu_size;
+ }
+
/* Set vhost memory table */
i = sizeof (struct vhost_memory) + sizeof (struct vhost_memory_region);
vhost_mem = clib_mem_alloc (i);
@@ -396,6 +419,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
args->host_namespace = 0;
vif->host_bridge = args->host_bridge;
args->host_bridge = 0;
+ vif->host_mtu_size = args->host_mtu_size;
clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
vif->host_ip4_prefix_len = args->host_ip4_prefix_len;
vif->host_ip6_prefix_len = args->host_ip6_prefix_len;
@@ -627,6 +651,7 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
if (vif->host_ip6_prefix_len)
clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len;
+ tapid->host_mtu_size = vif->host_mtu_size;
);
/* *INDENT-ON* */
@@ -636,6 +661,26 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
}
static clib_error_t *
+tap_mtu_config (vlib_main_t * vm, unformat_input_t * input)
+{
+ tap_main_t *tm = &tap_main;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "host-mtu %d", &tm->host_mtu_size))
+ ;
+ else
+ return clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ }
+
+ return 0;
+}
+
+/* tap { host-mtu <size> } configuration. */
+VLIB_CONFIG_FUNCTION (tap_mtu_config, "tap");
+
+static clib_error_t *
tap_init (vlib_main_t * vm)
{
tap_main_t *tm = &tap_main;
@@ -644,6 +689,8 @@ tap_init (vlib_main_t * vm)
tm->log_default = vlib_log_register_class ("tap", 0);
vlib_log_debug (tm->log_default, "initialized");
+ tm->host_mtu_size = 0;
+
return error;
}
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 745f9fca304..45ff1d9910e 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -43,6 +43,8 @@ typedef struct
u8 host_ip6_prefix_len;
ip6_address_t host_ip6_gw;
u8 host_ip6_gw_set;
+ u8 host_mtu_set;
+ u32 host_mtu_size;
/* return */
u32 sw_if_index;
int rv;
@@ -66,6 +68,7 @@ typedef struct
u8 host_ip4_prefix_len;
u8 host_ip6_addr[16];
u8 host_ip6_prefix_len;
+ u32 host_mtu_size;
} tap_interface_details_t;
typedef struct
@@ -75,6 +78,9 @@ typedef struct
/* bit-map of in-use IDs */
uword *tap_ids;
+
+ /* host mtu size, configurable through startup.conf */
+ int host_mtu_size;
} tap_main_t;
void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args);
diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api
index fb90483efbe..2d4d5c3497d 100644
--- a/src/vnet/devices/tap/tapv2.api
+++ b/src/vnet/devices/tap/tapv2.api
@@ -19,7 +19,7 @@
the Linux kernel TAP device driver
*/
-option version = "2.0.0";
+option version = "2.1.0";
/** \brief Initialize a new tap interface with the given paramters
@param client_index - opaque cookie to identify the sender
@@ -47,6 +47,8 @@ option version = "2.0.0";
@param host_ip4_gw - host IPv4 default gateway
@param host_ip6_gw_set - host IPv6 default gateway should be set
@param host_ip6_gw - host IPv6 default gateway
+ @param host_mtu_set - host MTU should be set
+ @param host_mtu_size - host MTU size
@param tap_flags - flags for the TAP interface creation
*/
define tap_create_v2
@@ -76,6 +78,8 @@ define tap_create_v2
u8 host_ip4_gw[4];
u8 host_ip6_gw_set;
u8 host_ip6_gw[16];
+ u8 host_mtu_set;
+ u32 host_mtu_size;
u8 tag[64];
u32 tap_flags;
};
@@ -125,6 +129,7 @@ define sw_interface_tap_v2_dump
@param host_ip4_prefix_len - host IPv4 ip address prefix length; 0 if unset
@param host_ip6_addr - host IPv6 ip address
@param host_ip6_prefix_len - host IPv6 ip address prefix length; 0 if unset
+ @param host_mtu_size - host mtu size
*/
define sw_interface_tap_v2_details
{
@@ -142,6 +147,7 @@ define sw_interface_tap_v2_details
u8 host_ip4_prefix_len;
u8 host_ip6_addr[16];
u8 host_ip6_prefix_len;
+ u32 host_mtu_size;
u32 tap_flags;
};
diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c
index 40ff22eaeaa..2471d0084e1 100644
--- a/src/vnet/devices/tap/tapv2_api.c
+++ b/src/vnet/devices/tap/tapv2_api.c
@@ -109,6 +109,12 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
ap->host_ip6_gw_set = 1;
}
+ if (mp->host_mtu_set)
+ {
+ ap->host_mtu_size = ntohl (mp->host_mtu_size);
+ ap->host_mtu_set = 1;
+ }
+
ap->tap_flags = ntohl (mp->tap_flags);
tap_create_if (vm, ap);
@@ -190,6 +196,7 @@ tap_send_sw_interface_details (vpe_api_main_t * am,
clib_memcpy (mp->host_bridge, tap_if->host_bridge,
MIN (ARRAY_LEN (mp->host_bridge) - 1,
strlen ((const char *) tap_if->host_bridge)));
+ mp->host_mtu_size = htonl (tap_if->host_mtu_size);
if (tap_if->host_ip4_prefix_len)
clib_memcpy (&mp->host_ip4_addr, &tap_if->host_ip4_addr, 4);
mp->host_ip4_prefix_len = tap_if->host_ip4_prefix_len;
="cp">#include <vppinfra/socket.h> #include <vnet/vnet.h> #include <vlib/vlib.h> #include <vlib/unix/unix.h> #include <vlibapi/api.h> #include <vlibmemory/api.h> #include "vat/json_format.h" #include <vlib/vlib.h> typedef struct { u8 *interface_name; u32 sw_if_index; /* * Subinterface ID. A number 0-N to uniquely identify this * subinterface under the super interface */ u32 sub_id; /* 0 = dot1q, 1=dot1ad */ u8 sub_dot1ad; /* Number of tags 0-2 */ u8 sub_number_of_tags; u16 sub_outer_vlan_id; u16 sub_inner_vlan_id; u8 sub_exact_match; u8 sub_default; u8 sub_outer_vlan_id_any; u8 sub_inner_vlan_id_any; /* vlan tag rewrite */ u32 vtr_op; u32 vtr_push_dot1q; u32 vtr_tag1; u32 vtr_tag2; } sw_interface_subif_t; typedef struct { u8 ip[16]; u8 prefix_length; } ip_address_details_t; typedef struct { u8 present; ip_address_details_t *addr; } ip_details_t; typedef struct { u64 packets; u64 bytes; } interface_counter_t; typedef struct { struct in_addr address; u8 address_length; u64 packets; u64 bytes; } ip4_fib_counter_t; typedef struct { struct in6_addr address; u8 address_length; u64 packets; u64 bytes; } ip6_fib_counter_t; typedef struct { struct in_addr address; vnet_link_t linkt; u64 packets; u64 bytes; } ip4_nbr_counter_t; typedef struct { struct in6_addr address; vnet_link_t linkt; u64 packets; u64 bytes; } ip6_nbr_counter_t; typedef struct { /* vpe input queue */ svm_queue_t *vl_input_queue; /* interface name table */ uword *sw_if_index_by_interface_name; /* subinterface table */ sw_interface_subif_t *sw_if_subif_table; /* Graph node table */ uword *graph_node_index_by_name; vlib_node_t ***graph_nodes; /* ip tables */ ip_details_t *ip_details_by_sw_if_index[2]; /* sw_if_index of currently processed interface */ u32 current_sw_if_index; /* remember that we are dumping ipv6 */ u8 is_ipv6; /* function table */ uword *function_by_name; /* help strings */ uword *help_by_name; /* macro table */ macro_main_t macro_main; /* Errors by number */ uword *error_string_by_error_number; /* Main thread can spin (w/ timeout) here if needed */ u32 async_mode; u32 async_errors; volatile u32 result_ready; volatile i32 retval; volatile u32 sw_if_index; volatile u8 *shmem_result; u8 *cmd_reply; /* our client index */ u32 my_client_index; int client_index_invalid; /* Time is of the essence... */ clib_time_t clib_time; /* Unwind (so we can quit) */ jmp_buf jump_buf; int jump_buf_set; volatile int do_exit; /* temporary parse buffer */ unformat_input_t *input; /* input buffer */ u8 *inbuf; /* stdio input / output FILEs */ FILE *ifp, *ofp; u8 *current_file; u32 input_line_number; /* exec mode toggle */ int exec_mode; /* Regenerate the interface table */ volatile int regenerate_interface_table; /* flag for JSON output format */ u8 json_output; /* flag for interface event display */ u8 interface_event_display; /* JSON tree used in composing dump api call results */ vat_json_node_t json_tree; /* counters */ u64 **simple_interface_counters; interface_counter_t **combined_interface_counters; ip4_fib_counter_t **ip4_fib_counters; u32 *ip4_fib_counters_vrf_id_by_index; ip6_fib_counter_t **ip6_fib_counters; u32 *ip6_fib_counters_vrf_id_by_index; ip4_nbr_counter_t **ip4_nbr_counters; ip6_nbr_counter_t **ip6_nbr_counters; ssvm_private_t stat_segment; clib_spinlock_t *stat_segment_lockp; socket_client_main_t *socket_client_main; u8 *socket_name; /* Convenience */ vlib_main_t *vlib_main; } vat_main_t; extern vat_main_t vat_main; void vat_suspend (vlib_main_t * vm, f64 interval); f64 vat_time_now (vat_main_t * vam); void errmsg (char *fmt, ...); void vat_api_hookup (vat_main_t * vam); int api_sw_interface_dump (vat_main_t * vam); void do_one_file (vat_main_t * vam); int exec (vat_main_t * vam); /* Plugin API library functions */ char *vat_plugin_path; char *vat_plugin_name_filter; void vat_plugin_api_reference (void); uword unformat_sw_if_index (unformat_input_t * input, va_list * args); uword unformat_ip4_address (unformat_input_t * input, va_list * args); uword unformat_ethernet_address (unformat_input_t * input, va_list * args); uword unformat_ethernet_type_host_byte_order (unformat_input_t * input, va_list * args); uword unformat_ip6_address (unformat_input_t * input, va_list * args); u8 *format_ip4_address (u8 * s, va_list * args); u8 *format_ip6_address (u8 * s, va_list * args); u8 *format_ip46_address (u8 * s, va_list * args); u8 *format_ethernet_address (u8 * s, va_list * args); int vat_socket_connect (vat_main_t * vam); #if VPP_API_TEST_BUILTIN #define print api_cli_output void api_cli_output (void *, const char *fmt, ...); #else #define print fformat_append_cr void fformat_append_cr (FILE *, const char *fmt, ...); #endif #endif /* __included_vat_h__ */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */