summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2018-01-18 13:35:11 +0100
committerNeale Ranns <nranns@cisco.com>2018-01-18 15:59:06 +0000
commit7866c4595b65f54f491ffc4e92b1f8cf94d6f142 (patch)
tree404c981a49256a66e4a95718f426d2040619fe71
parent929fb9d75071ef4141b1cac3997f86d9ded0a9ab (diff)
tapv2: add option to set host-side default gw
Change-Id: I76fd655ecd9445299b94b3b5af10e7b1588584e4 Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r--src/vat/api_format.c15
-rw-r--r--src/vnet/devices/netlink.c42
-rw-r--r--src/vnet/devices/netlink.h2
-rw-r--r--src/vnet/devices/tap/cli.c9
-rw-r--r--src/vnet/devices/tap/tap.c20
-rw-r--r--src/vnet/devices/tap/tap.h4
-rw-r--r--src/vnet/devices/tap/tapv2.api10
-rw-r--r--src/vnet/devices/tap/tapv2_api.c12
-rw-r--r--src/vpp/api/custom_dump.c4
9 files changed, 115 insertions, 3 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 3654cd663bd..4f20ea82361 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -7772,8 +7772,12 @@ api_tap_create_v2 (vat_main_t * vam)
u8 host_mac_addr_set = 0;
u8 *host_bridge = 0;
ip4_address_t host_ip4_addr;
+ ip4_address_t host_ip4_gw;
+ u8 host_ip4_gw_set = 0;
u32 host_ip4_prefix_len = 0;
ip6_address_t host_ip6_addr;
+ ip6_address_t host_ip6_gw;
+ u8 host_ip6_gw_set = 0;
u32 host_ip6_prefix_len = 0;
int ret;
int rx_ring_sz = 0, tx_ring_sz = 0;
@@ -7804,6 +7808,12 @@ api_tap_create_v2 (vat_main_t * vam)
else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
&host_ip6_addr, &host_ip6_prefix_len))
;
+ else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
+ &host_ip4_gw))
+ host_ip4_gw_set = 1;
+ else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
+ &host_ip6_gw))
+ host_ip6_gw_set = 1;
else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
;
else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
@@ -7885,7 +7895,10 @@ api_tap_create_v2 (vat_main_t * vam)
clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
if (host_ip4_prefix_len)
clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
-
+ if (host_ip4_gw_set)
+ clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
+ if (host_ip6_gw_set)
+ clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
vec_free (host_ns);
vec_free (host_if_name);
diff --git a/src/vnet/devices/netlink.c b/src/vnet/devices/netlink.c
index 5994366007c..8346b1c77ea 100644
--- a/src/vnet/devices/netlink.c
+++ b/src/vnet/devices/netlink.c
@@ -245,6 +245,48 @@ vnet_netlink_add_ip6_addr (int ifindex, void *addr, int pfx_len)
return vnet_netlink_msg_send (&m);
}
+clib_error_t *
+vnet_netlink_add_ip4_route (void *dst, u8 dst_len, void *gw)
+{
+ vnet_netlink_msg_t m;
+ struct rtmsg rtm = { 0 };
+ u8 dflt[4] = { 0 };
+
+ rtm.rtm_family = AF_INET;
+ rtm.rtm_table = RT_TABLE_MAIN;
+ rtm.rtm_type = RTN_UNICAST;
+ rtm.rtm_dst_len = dst_len;
+
+ vnet_netlink_msg_init (&m, RTM_NEWROUTE,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
+ &rtm, sizeof (struct rtmsg));
+
+ vnet_netlink_msg_add_rtattr (&m, RTA_GATEWAY, gw, 4);
+ vnet_netlink_msg_add_rtattr (&m, RTA_DST, dst ? dst : dflt, 4);
+ return vnet_netlink_msg_send (&m);
+}
+
+clib_error_t *
+vnet_netlink_add_ip6_route (void *dst, u8 dst_len, void *gw)
+{
+ vnet_netlink_msg_t m;
+ struct rtmsg rtm = { 0 };
+ u8 dflt[16] = { 0 };
+
+ rtm.rtm_family = AF_INET6;
+ rtm.rtm_table = RT_TABLE_MAIN;
+ rtm.rtm_type = RTN_UNICAST;
+ rtm.rtm_dst_len = dst_len;
+
+ vnet_netlink_msg_init (&m, RTM_NEWROUTE,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
+ &rtm, sizeof (struct rtmsg));
+
+ vnet_netlink_msg_add_rtattr (&m, RTA_GATEWAY, gw, 16);
+ vnet_netlink_msg_add_rtattr (&m, RTA_DST, dst ? dst : dflt, 16);
+ return vnet_netlink_msg_send (&m);
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vnet/devices/netlink.h b/src/vnet/devices/netlink.h
index e8501961a04..0d3e0d23ac6 100644
--- a/src/vnet/devices/netlink.h
+++ b/src/vnet/devices/netlink.h
@@ -26,6 +26,8 @@ clib_error_t *vnet_netlink_add_ip4_addr (int ifindex, void *addr,
int pfx_len);
clib_error_t *vnet_netlink_add_ip6_addr (int ifindex, void *addr,
int pfx_len);
+clib_error_t *vnet_netlink_add_ip4_route (void *dst, u8 dst_len, void *gw);
+clib_error_t *vnet_netlink_add_ip6_route (void *dst, u8 dst_len, void *gw);
#endif /* included_vnet_device_netlink_h */
diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c
index 7dd525b169d..c17599afdad 100644
--- a/src/vnet/devices/tap/cli.c
+++ b/src/vnet/devices/tap/cli.c
@@ -61,10 +61,16 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
unformat_ip4_address, &args.host_ip4_addr,
&args.host_ip4_prefix_len))
ip_addr_set = 1;
+ else if (unformat (line_input, "host-ip4-gw %U",
+ unformat_ip4_address, &args.host_ip4_gw))
+ args.host_ip4_gw_set = 1;
else if (unformat (line_input, "host-ip6-addr %U/%d",
unformat_ip6_address, &args.host_ip6_addr,
&args.host_ip6_prefix_len))
ip_addr_set = 1;
+ else if (unformat (line_input, "host-ip6-gw %U",
+ unformat_ip6_address, &args.host_ip6_gw))
+ args.host_ip6_gw_set = 1;
else if (unformat (line_input, "rx-ring-size %d", &args.rx_ring_sz))
;
else if (unformat (line_input, "tx-ring-size %d", &args.tx_ring_sz))
@@ -102,7 +108,8 @@ VLIB_CLI_COMMAND (tap_create_command, static) = {
.short_help = "create tap {id <if-id>} [hw-addr <mac-address>] "
"[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-if-name <name>]",
+ "[host-ip6-addr <ip6-addr>] [host-ip4-gw <ip4-addr>] "
+ "[host-ip6-gw <ip6-addr>] [host-if-name <name>]",
.function = tap_create_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index a7d10fe5473..e6a7ba518a6 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -292,6 +292,26 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
goto error;
}
+ if (args->host_ip4_gw_set)
+ {
+ args->error = vnet_netlink_add_ip4_route (0, 0, &args->host_ip4_gw);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ }
+
+ if (args->host_ip6_gw_set)
+ {
+ args->error = vnet_netlink_add_ip6_route (0, 0, &args->host_ip6_gw);
+ if (args->error)
+ {
+ args->rv = VNET_API_ERROR_NETLINK_ERROR;
+ goto error;
+ }
+ }
+
/* switch back to old net namespace */
if (args->host_namespace)
{
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 35f7a018237..98af0d8f3ab 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -35,8 +35,12 @@ typedef struct
u8 *host_bridge;
ip4_address_t host_ip4_addr;
u8 host_ip4_prefix_len;
+ ip4_address_t host_ip4_gw;
+ u8 host_ip4_gw_set;
ip6_address_t host_ip6_addr;
u8 host_ip6_prefix_len;
+ ip6_address_t host_ip6_gw;
+ u8 host_ip6_gw_set;
/* return */
u32 sw_if_index;
int rv;
diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api
index 1f0051ec86f..0d86edff735 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
*/
-vl_api_version 1.0.0
+vl_api_version 1.1.0
/** \brief Initialize a new tap interface with the given paramters
@param client_index - opaque cookie to identify the sender
@@ -43,6 +43,10 @@ vl_api_version 1.0.0
@param host_ip6_addr_set - host IPv6 ip address should be set
@param host_ip6_addr - host IPv6 ip address
@param host_ip6_prefix_len - host IPv6 ip address prefix length
+ @param host_ip4_gw_set - host IPv4 default gateway should be set
+ @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
*/
define tap_create_v2
{
@@ -67,6 +71,10 @@ define tap_create_v2
u8 host_ip6_addr_set;
u8 host_ip6_addr[16];
u8 host_ip6_prefix_len;
+ u8 host_ip4_gw_set;
+ u8 host_ip4_gw[4];
+ u8 host_ip6_gw_set;
+ u8 host_ip6_gw[16];
};
/** \brief Reply for tap create reply
diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c
index 9f46884ca8c..34472c0ab28 100644
--- a/src/vnet/devices/tap/tapv2_api.c
+++ b/src/vnet/devices/tap/tapv2_api.c
@@ -96,6 +96,18 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
ap->host_ip6_prefix_len = mp->host_ip6_prefix_len;
}
+ if (mp->host_ip4_gw_set)
+ {
+ clib_memcpy (&ap->host_ip4_gw, mp->host_ip4_gw, 4);
+ ap->host_ip4_gw_set = 1;
+ }
+
+ if (mp->host_ip6_gw_set)
+ {
+ clib_memcpy (&ap->host_ip6_gw, mp->host_ip6_gw, 16);
+ ap->host_ip6_gw_set = 1;
+ }
+
tap_create_if (vm, ap);
reg = vl_api_client_index_to_registration (mp->client_index);
diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c
index 2af3b47d388..62f3c5f4af5 100644
--- a/src/vpp/api/custom_dump.c
+++ b/src/vpp/api/custom_dump.c
@@ -576,6 +576,10 @@ static void *vl_api_tap_create_v2_t_print
if (mp->host_ip6_addr_set)
s = format (s, "host-ip6-addr %U/%d ", format_ip6_address,
mp->host_ip6_addr, mp->host_ip6_prefix_len);
+ if (mp->host_ip4_gw_set)
+ s = format (s, "host-ip4-gw %U ", format_ip4_address, mp->host_ip4_addr);
+ if (mp->host_ip6_gw_set)
+ s = format (s, "host-ip6-gw %U ", format_ip6_address, mp->host_ip6_addr);
if (mp->tx_ring_sz)
s = format (s, "tx-ring-size %d ", mp->tx_ring_sz);
if (mp->rx_ring_sz)