From 7866c4595b65f54f491ffc4e92b1f8cf94d6f142 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Thu, 18 Jan 2018 13:35:11 +0100 Subject: tapv2: add option to set host-side default gw Change-Id: I76fd655ecd9445299b94b3b5af10e7b1588584e4 Signed-off-by: Damjan Marion --- src/vnet/devices/netlink.c | 42 ++++++++++++++++++++++++++++++++++++++++ src/vnet/devices/netlink.h | 2 ++ src/vnet/devices/tap/cli.c | 9 ++++++++- src/vnet/devices/tap/tap.c | 20 +++++++++++++++++++ src/vnet/devices/tap/tap.h | 4 ++++ src/vnet/devices/tap/tapv2.api | 10 +++++++++- src/vnet/devices/tap/tapv2_api.c | 12 ++++++++++++ 7 files changed, 97 insertions(+), 2 deletions(-) (limited to 'src/vnet/devices') 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 } [hw-addr ] " "[rx-ring-size ] [tx-ring-size ] [host-ns ] " "[host-bridge ] [host-ip4-addr ] " - "[host-ip6-addr ]", + "[host-ip6-addr ] [host-ip4-gw ] " + "[host-ip6-gw ] [host-if-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); -- cgit 1.2.3-korg