diff options
author | Florin Coras <fcoras@cisco.com> | 2017-10-02 00:18:51 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2017-10-10 20:42:50 +0000 |
commit | cea194d8f973a2f2b5ef72d212533057174cc70a (patch) | |
tree | 6fdd2e8a929c62625d1ad35bfbec342129989aef /src/vnet/tcp/tcp.c | |
parent | 1f36a93d3d68f5ba6dcda08809394ce757cefd72 (diff) |
session: add support for application namespacing
Applications are now provided the option to select the namespace they
are to be attached to and the scope of their attachement. Application
namespaces are meant to:
1) constrain the scope of communication through the network by
association with source interfaces and/or fib tables that provide the
source ips to be used and limit the scope of routing
2) provide a namespace local scope to session layer communication, as
opposed to the global scope provided by 1). That is, sessions can be
established without assistance from transport and network layers.
Albeit, zero/local-host ip addresses must still be provided in session
establishment messages due to existing application idiosyncrasies. This
mode of communication uses shared-memory fifos (cut-through sessions)
exclusively.
If applications request no namespace, they are assigned to the default
one, which at its turn uses the default fib. Applications can request
access to both local and global scopes for a namespace. If no scope is
specified, session layer defaults to the global one.
When a sw_if_index is provided for a namespace, zero-ip (INADDR_ANY)
binds are converted to binds to the requested interface.
Change-Id: Ia0f660bbf7eec7f89673f75b4821fc7c3d58e3d1
Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/tcp/tcp.c')
-rw-r--r-- | src/vnet/tcp/tcp.c | 109 |
1 files changed, 53 insertions, 56 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index 2a705d01b4c..52e945a262b 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -28,11 +28,45 @@ tcp_main_t tcp_main; +void * +ip_interface_get_first_ip (u32 sw_if_index, u8 is_ip4) +{ + ip_lookup_main_t *lm4 = &ip4_main.lookup_main; + ip_lookup_main_t *lm6 = &ip6_main.lookup_main; + ip_interface_address_t *ia = 0; + + if (is_ip4) + { + /* *INDENT-OFF* */ + foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ , + ({ + return ip_interface_address_get_address (lm4, ia); + })); + /* *INDENT-ON* */ + } + else + { + /* *INDENT-OFF* */ + foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ , + ({ + ip6_address_t *rv; + rv = ip_interface_address_get_address (lm6, ia); + /* Trying to use a link-local ip6 src address is a fool's errand */ + if (!ip6_address_is_link_local_unicast (rv)) + return rv; + })); + /* *INDENT-ON* */ + } + + return 0; +} + static u32 tcp_connection_bind (u32 session_index, transport_endpoint_t * lcl) { tcp_main_t *tm = &tcp_main; tcp_connection_t *listener; + void *iface_ip; pool_get (tm->listener_pool, listener); memset (listener, 0, sizeof (*listener)); @@ -40,19 +74,18 @@ tcp_connection_bind (u32 session_index, transport_endpoint_t * lcl) listener->c_c_index = listener - tm->listener_pool; listener->c_lcl_port = lcl->port; - if (lcl->is_ip4) + /* If we are provided a sw_if_index, bind using one of its ips */ + if (ip_is_zero (&lcl->ip, 1) && lcl->sw_if_index != ENDPOINT_INVALID_INDEX) { - listener->c_lcl_ip4.as_u32 = lcl->ip.ip4.as_u32; - listener->c_is_ip4 = 1; - } - else - { - clib_memcpy (&listener->c_lcl_ip6, &lcl->ip.ip6, - sizeof (ip6_address_t)); - + if ((iface_ip = ip_interface_get_first_ip (lcl->sw_if_index, + lcl->is_ip4))) + ip_set (&lcl->ip, iface_ip, lcl->is_ip4); } + ip_copy (&listener->c_lcl_ip, &lcl->ip, lcl->is_ip4); + listener->c_is_ip4 = lcl->is_ip4; listener->c_transport_proto = TRANSPORT_PROTO_TCP; listener->c_s_index = session_index; + listener->c_fib_index = lcl->fib_index; listener->state = TCP_STATE_LISTEN; tcp_connection_timers_init (listener); @@ -355,39 +388,6 @@ tcp_session_cleanup (u32 conn_index, u32 thread_index) tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME); } -void * -ip_interface_get_first_ip (u32 sw_if_index, u8 is_ip4) -{ - ip_lookup_main_t *lm4 = &ip4_main.lookup_main; - ip_lookup_main_t *lm6 = &ip6_main.lookup_main; - ip_interface_address_t *ia = 0; - - if (is_ip4) - { - /* *INDENT-OFF* */ - foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ , - ({ - return ip_interface_address_get_address (lm4, ia); - })); - /* *INDENT-ON* */ - } - else - { - /* *INDENT-OFF* */ - foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ , - ({ - ip6_address_t *rv; - rv = ip_interface_address_get_address (lm6, ia); - /* Trying to use a link-local ip6 src address is a fool's errand */ - if (!ip6_address_is_link_local_unicast (rv)) - return rv; - })); - /* *INDENT-ON* */ - } - - return 0; -} - #define PORT_MASK ((1 << 16)- 1) /** * Allocate local port and add if successful add entry to local endpoint @@ -528,7 +528,7 @@ tcp_lookup_rmt_in_fib (tcp_connection_t * tc) clib_memcpy (&prefix.fp_addr, &tc->c_rmt_ip, sizeof (prefix.fp_addr)); prefix.fp_proto = tc->c_is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; prefix.fp_len = tc->c_is_ip4 ? 32 : 128; - fib_index = fib_table_find (prefix.fp_proto, tc->c_vrf); + fib_index = fib_table_find (prefix.fp_proto, tc->c_fib_index); return fib_table_lookup (fib_index, &prefix); } @@ -575,6 +575,7 @@ tcp_init_snd_vars (tcp_connection_t * tc) u32 time_now; /* Set random initial sequence */ + tcp_set_time_now (0); time_now = tcp_time_now (); tc->iss = random_u32 (&time_now); tc->snd_una = tc->iss; @@ -606,7 +607,7 @@ tcp_connection_open (transport_endpoint_t * rmt) tcp_connection_t *tc; fib_prefix_t prefix; fib_node_index_t fei; - u32 sw_if_index, fib_index; + u32 sw_if_index; ip46_address_t lcl_addr; int lcl_port; @@ -620,14 +621,8 @@ tcp_connection_open (transport_endpoint_t * rmt) prefix.fp_proto = rmt->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; prefix.fp_len = rmt->is_ip4 ? 32 : 128; - fib_index = fib_table_find (prefix.fp_proto, rmt->vrf); - if (fib_index == (u32) ~ 0) - { - clib_warning ("no fib table"); - return -1; - } - - fei = fib_table_lookup (fib_index, &prefix); + ASSERT (rmt->fib_index != ENDPOINT_INVALID_INDEX); + fei = fib_table_lookup (rmt->fib_index, &prefix); /* Couldn't find route to destination. Bail out. */ if (fei == FIB_NODE_INDEX_INVALID) @@ -636,12 +631,14 @@ tcp_connection_open (transport_endpoint_t * rmt) return -1; } - sw_if_index = fib_entry_get_resolving_interface (fei); + sw_if_index = rmt->sw_if_index; + if (sw_if_index == ENDPOINT_INVALID_INDEX) + sw_if_index = fib_entry_get_resolving_interface (fei); - if (sw_if_index == (u32) ~ 0) + if (sw_if_index == ENDPOINT_INVALID_INDEX) { clib_warning ("no resolving interface for %U", format_ip46_address, - &rmt->ip, IP46_TYPE_IP4); + &rmt->ip, (rmt->is_ip4 == 0) + 1); return -1; } @@ -709,7 +706,7 @@ tcp_connection_open (transport_endpoint_t * rmt) tc->c_lcl_port = clib_host_to_net_u16 (lcl_port); tc->c_is_ip4 = rmt->is_ip4; tc->c_transport_proto = TRANSPORT_PROTO_TCP; - tc->c_vrf = rmt->vrf; + tc->c_fib_index = rmt->fib_index; /* The other connection vars will be initialized after SYN ACK */ tcp_connection_timers_init (tc); |