- tcp_api_reference ();
- tm->cc_algo_by_name = hash_create_string (0, sizeof (uword));
- tm->tx_pacing = 1;
- tm->cc_algo = TCP_CC_NEWRENO;
- tm->default_mtu = 1460;
- return 0;
-}
-
-VLIB_INIT_FUNCTION (tcp_init);
-
-uword
-unformat_tcp_cc_algo (unformat_input_t * input, va_list * va)
-{
- uword *result = va_arg (*va, uword *);
- tcp_main_t *tm = &tcp_main;
- char *cc_algo_name;
- u8 found = 0;
- uword *p;
-
- if (unformat (input, "%s", &cc_algo_name)
- && ((p = hash_get_mem (tm->cc_algo_by_name, cc_algo_name))))
- {
- *result = *p;
- found = 1;
- }
-
- vec_free (cc_algo_name);
- return found;
-}
-
-uword
-unformat_tcp_cc_algo_cfg (unformat_input_t * input, va_list * va)
-{
- tcp_main_t *tm = vnet_get_tcp_main ();
- tcp_cc_algorithm_t *cc_alg;
- unformat_input_t sub_input;
- int found = 0;
-
- vec_foreach (cc_alg, tm->cc_algos)
- {
- if (!unformat (input, cc_alg->name))
- continue;
-
- if (cc_alg->unformat_cfg
- && unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
- {
- if (cc_alg->unformat_cfg (&sub_input))
- found = 1;
- }
- }
- return found;
-}
-
-static clib_error_t *
-tcp_config_fn (vlib_main_t * vm, unformat_input_t * input)
-{
- tcp_main_t *tm = vnet_get_tcp_main ();
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "preallocated-connections %d",
- &tm->preallocated_connections))
- ;
- else if (unformat (input, "preallocated-half-open-connections %d",
- &tm->preallocated_half_open_connections))
- ;
- else if (unformat (input, "buffer-fail-fraction %f",
- &tm->buffer_fail_fraction))
- ;
- else if (unformat (input, "max-rx-fifo %U", unformat_memory_size,
- &tm->max_rx_fifo))
- ;
- else if (unformat (input, "mtu %d", &tm->default_mtu))
- ;
- else if (unformat (input, "no-tx-pacing"))
- tm->tx_pacing = 0;
- else if (unformat (input, "cc-algo %U", unformat_tcp_cc_algo,
- &tm->cc_algo))
- ;
- else if (unformat (input, "%U", unformat_tcp_cc_algo_cfg))
- ;
- else
- return clib_error_return (0, "unknown input `%U'",
- format_unformat_error, input);
- }
- return 0;
-}
-
-VLIB_CONFIG_FUNCTION (tcp_config_fn, "tcp");
-
-
-/**
- * \brief Configure an ipv4 source address range
- * @param vm vlib_main_t pointer
- * @param start first ipv4 address in the source address range
- * @param end last ipv4 address in the source address range
- * @param table_id VRF / table ID, 0 for the default FIB
- * @return 0 if all OK, else an error indication from api_errno.h
- */
-
-int
-tcp_configure_v4_source_address_range (vlib_main_t * vm,
- ip4_address_t * start,
- ip4_address_t * end, u32 table_id)
-{
- tcp_main_t *tm = vnet_get_tcp_main ();
- vnet_main_t *vnm = vnet_get_main ();
- u32 start_host_byte_order, end_host_byte_order;
- fib_prefix_t prefix;
- vnet_sw_interface_t *si;
- fib_node_index_t fei;
- u32 fib_index = 0;
- u32 sw_if_index;
- int rv;
- int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
- ip4_address_t * hi_addr, u32 fib_index,
- int is_del);
-
- clib_memset (&prefix, 0, sizeof (prefix));
-
- fib_index = fib_table_find (FIB_PROTOCOL_IP4, table_id);
-
- if (fib_index == ~0)
- return VNET_API_ERROR_NO_SUCH_FIB;
-
- start_host_byte_order = clib_net_to_host_u32 (start->as_u32);
- end_host_byte_order = clib_net_to_host_u32 (end->as_u32);
-
- /* sanity check for reversed args or some such */
- if ((end_host_byte_order - start_host_byte_order) > (10 << 10))
- return VNET_API_ERROR_INVALID_ARGUMENT;
-
- /* Lookup the last address, to identify the interface involved */
- prefix.fp_len = 32;
- prefix.fp_proto = FIB_PROTOCOL_IP4;
- memcpy (&prefix.fp_addr.ip4, end, sizeof (ip4_address_t));
-
- fei = fib_table_lookup (fib_index, &prefix);
-
- /* Couldn't find route to destination. Bail out. */
- if (fei == FIB_NODE_INDEX_INVALID)
- return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
-
- sw_if_index = fib_entry_get_resolving_interface (fei);
-
- /* Enable proxy arp on the interface */
- si = vnet_get_sw_interface (vnm, sw_if_index);
- si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
-
- /* Configure proxy arp across the range */
- rv = vnet_proxy_arp_add_del (start, end, fib_index, 0 /* is_del */ );
-
- if (rv)
- return rv;
-
- do
- {
- dpo_id_t dpo = DPO_INVALID;
-
- vec_add1 (tm->ip4_src_addresses, start[0]);
-
- /* Add local adjacencies for the range */
-
- receive_dpo_add_or_lock (DPO_PROTO_IP4, ~0 /* sw_if_index */ ,
- NULL, &dpo);
- prefix.fp_len = 32;
- prefix.fp_proto = FIB_PROTOCOL_IP4;
- prefix.fp_addr.ip4.as_u32 = start->as_u32;
-
- fib_table_entry_special_dpo_update (fib_index,
- &prefix,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
- dpo_reset (&dpo);
-
- start_host_byte_order++;
- start->as_u32 = clib_host_to_net_u32 (start_host_byte_order);
- }
- while (start_host_byte_order <= end_host_byte_order);
-
- return 0;
-}
-
-/**
- * \brief Configure an ipv6 source address range
- * @param vm vlib_main_t pointer
- * @param start first ipv6 address in the source address range
- * @param end last ipv6 address in the source address range
- * @param table_id VRF / table ID, 0 for the default FIB
- * @return 0 if all OK, else an error indication from api_errno.h
- */
-
-int
-tcp_configure_v6_source_address_range (vlib_main_t * vm,
- ip6_address_t * start,
- ip6_address_t * end, u32 table_id)
-{
- tcp_main_t *tm = vnet_get_tcp_main ();
- fib_prefix_t prefix;
- u32 fib_index = 0;
- fib_node_index_t fei;
- u32 sw_if_index;
-
- clib_memset (&prefix, 0, sizeof (prefix));
-
- fib_index = fib_table_find (FIB_PROTOCOL_IP6, table_id);
-
- if (fib_index == ~0)
- return VNET_API_ERROR_NO_SUCH_FIB;
-
- while (1)
- {
- int i;
- ip6_address_t tmp;
- dpo_id_t dpo = DPO_INVALID;
-
- /* Remember this address */
- vec_add1 (tm->ip6_src_addresses, start[0]);
-
- /* Lookup the prefix, to identify the interface involved */
- prefix.fp_len = 128;
- prefix.fp_proto = FIB_PROTOCOL_IP6;
- memcpy (&prefix.fp_addr.ip6, start, sizeof (ip6_address_t));
-
- fei = fib_table_lookup (fib_index, &prefix);
-
- /* Couldn't find route to destination. Bail out. */
- if (fei == FIB_NODE_INDEX_INVALID)
- return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
-
- sw_if_index = fib_entry_get_resolving_interface (fei);
-
- if (sw_if_index == (u32) ~ 0)
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
-
- /* Add a proxy neighbor discovery entry for this address */
- ip6_neighbor_proxy_add_del (sw_if_index, start, 0 /* is_del */ );
-
- /* Add a receive adjacency for this address */
- receive_dpo_add_or_lock (DPO_PROTO_IP6, ~0 /* sw_if_index */ ,
- NULL, &dpo);
-
- fib_table_entry_special_dpo_update (fib_index,
- &prefix,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
- dpo_reset (&dpo);
-
- /* Done with the entire range? */
- if (!memcmp (start, end, sizeof (start[0])))
- break;
-
- /* Increment the address. DGMS. */
- tmp = start[0];
- for (i = 15; i >= 0; i--)
- {
- tmp.as_u8[i] += 1;
- if (tmp.as_u8[i] != 0)
- break;
- }
- start[0] = tmp;
- }
- return 0;
-}
-
-static clib_error_t *
-tcp_src_address (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd_arg)
-{
- ip4_address_t v4start, v4end;
- ip6_address_t v6start, v6end;
- u32 table_id = 0;
- int v4set = 0;
- int v6set = 0;
- int rv;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "%U - %U", unformat_ip4_address, &v4start,
- unformat_ip4_address, &v4end))
- v4set = 1;
- else if (unformat (input, "%U", unformat_ip4_address, &v4start))
- {
- memcpy (&v4end, &v4start, sizeof (v4start));
- v4set = 1;
- }
- else if (unformat (input, "%U - %U", unformat_ip6_address, &v6start,
- unformat_ip6_address, &v6end))
- v6set = 1;
- else if (unformat (input, "%U", unformat_ip6_address, &v6start))
- {
- memcpy (&v6end, &v6start, sizeof (v6start));
- v6set = 1;
- }
- else if (unformat (input, "fib-table %d", &table_id))
- ;
- else
- break;
- }