From 4b919a56642ccd0a44920feace872aeb5b7a62cf Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Sat, 11 Mar 2017 05:55:21 -0800 Subject: Attached hosts allow this config to function: set int ip address loop0 169.254.1.1/32 (the default GW address for attached hosts) set int unnumbered af_packet0 use loop0 ('enable' IP on the host interface) ip route add 192.168.1.1/32 via af_packet0 (where to find the host) repeat for each host and host interface. Inter-host communication is throught the /32 routes. To allow this: 1 - attached host routes have the ATTACHED flag set, so the ARP code accepts then as legitimate sources 2 - unnumbered interfaces inherit the source address from the IP interface Change-Id: Ib66c5f0e848c528f79372813adc3a0c11b50717f Signed-off-by: Neale Ranns --- src/vnet/ethernet/arp.c | 72 +++++++++++++++++++++++++++++++++----------- src/vnet/fib/fib_entry_src.c | 4 +++ src/vnet/fib/fib_path.c | 7 +++++ src/vnet/fib/fib_path.h | 6 ++++ src/vnet/fib/fib_table.c | 1 + src/vnet/fib/fib_types.h | 4 +++ src/vnet/interface_api.c | 15 +++++++++ src/vnet/interface_cli.c | 12 ++++++++ 8 files changed, 103 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c index d8ae84433e7..75c7e20372a 100644 --- a/src/vnet/ethernet/arp.c +++ b/src/vnet/ethernet/arp.c @@ -1016,7 +1016,6 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vnet_hw_interface_t *hw_if0; ethernet_arp_header_t *arp0; ethernet_header_t *eth0; - ip_adjacency_t *adj0; ip4_address_t *if_addr0, proxy_src; u32 pi0, error0, next0, sw_if_index0, conn_sw_if_index0, fib_index0; u8 is_request0, dst_is_local0, is_unnum0; @@ -1073,6 +1072,11 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) 32); dst_flags = fib_entry_get_flags (dst_fei); + src_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0), + &arp0->ip4_over_ethernet[0].ip4, + 32); + src_flags = fib_entry_get_flags (src_fei); + conn_sw_if_index0 = fib_entry_get_resolving_interface (dst_fei); if (!(FIB_ENTRY_FLAG_CONNECTED & dst_flags)) @@ -1085,11 +1089,6 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) is_unnum0 = sw_if_index0 != conn_sw_if_index0; /* Source must also be local to subnet of matching interface address. */ - src_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0), - &arp0->ip4_over_ethernet[0].ip4, - 32); - src_flags = fib_entry_get_flags (src_fei); - if (!((FIB_ENTRY_FLAG_ATTACHED & src_flags) || (FIB_ENTRY_FLAG_CONNECTED & src_flags))) { @@ -1187,25 +1186,62 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) /* get the adj from the destination's covering connected */ if (NULL == pa) { - adj0 = - adj_get (fib_entry_get_adj_for_source - (ip4_fib_table_lookup - (ip4_fib_get (fib_index0), - &arp0->ip4_over_ethernet[1].ip4, 31), - FIB_SOURCE_INTERFACE)); - if (adj0->lookup_next_index != IP_LOOKUP_NEXT_GLEAN) - { - error0 = ETHERNET_ARP_ERROR_missing_interface_address; - goto drop2; - } if (is_unnum0) { if (!arp_unnumbered (p0, pi0, eth0, conn_sw_if_index0)) goto drop2; } else - vlib_buffer_advance (p0, -adj0->rewrite_header.data_bytes); + { + ip_adjacency_t *adj0 = NULL; + adj_index_t ai; + + if (FIB_ENTRY_FLAG_ATTACHED & src_flags) + { + /* + * If the source is attached use the adj from that source. + */ + ai = fib_entry_get_adj (src_fei); + if (ADJ_INDEX_INVALID != ai) + { + adj0 = adj_get (ai); + } + } + else + { + /* + * Get the glean adj from the cover. This is presumably interface + * sourced, and therefre needs to be a glean adj. + */ + ai = fib_entry_get_adj_for_source + (ip4_fib_table_lookup + (ip4_fib_get (fib_index0), + &arp0->ip4_over_ethernet[1].ip4, 31), + FIB_SOURCE_INTERFACE); + + if (ADJ_INDEX_INVALID != ai) + { + adj0 = adj_get (ai); + + if (adj0->lookup_next_index == IP_LOOKUP_NEXT_GLEAN) + { + adj0 = NULL; + } + } + } + if (NULL != adj0) + { + vlib_buffer_advance (p0, + -adj0->rewrite_header.data_bytes); + } + else + { + error0 = ETHERNET_ARP_ERROR_missing_interface_address; + goto drop2; + } + } } + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, pi0, next0); diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c index feb232df7f1..aa1d5a24a0f 100644 --- a/src/vnet/fib/fib_entry_src.c +++ b/src/vnet/fib/fib_entry_src.c @@ -946,6 +946,10 @@ fib_path_is_attached (const fib_route_path_t *rpath) { return (!0); } + else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED) + { + return (!0); + } return (0); } diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c index aa545b5ed45..3ed309f328b 100644 --- a/src/vnet/fib/fib_path.c +++ b/src/vnet/fib/fib_path.c @@ -109,6 +109,10 @@ typedef enum fib_path_oper_attribute_t_ { * The path is resolved */ FIB_PATH_OPER_ATTRIBUTE_RESOLVED, + /** + * The path is attached, despite what the next-hop may say. + */ + FIB_PATH_OPER_ATTRIBUTE_ATTACHED, /** * The path has become a permanent drop. */ @@ -143,6 +147,7 @@ typedef enum fib_path_oper_flags_t_ { FIB_PATH_OPER_FLAG_RECURSIVE_LOOP = (1 << FIB_PATH_OPER_ATTRIBUTE_RECURSIVE_LOOP), FIB_PATH_OPER_FLAG_DROP = (1 << FIB_PATH_OPER_ATTRIBUTE_DROP), FIB_PATH_OPER_FLAG_RESOLVED = (1 << FIB_PATH_OPER_ATTRIBUTE_RESOLVED), + FIB_PATH_OPER_FLAG_ATTACHED = (1 << FIB_PATH_OPER_ATTRIBUTE_ATTACHED), } __attribute__ ((packed)) fib_path_oper_flags_t; /** @@ -963,6 +968,8 @@ fib_path_route_flags_to_cfg_flags (const fib_route_path_t *rpath) cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED; if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) cfg_flags |= FIB_PATH_CFG_FLAG_LOCAL; + if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED) + cfg_flags |= FIB_PATH_CFG_FLAG_ATTACHED; return (cfg_flags); } diff --git a/src/vnet/fib/fib_path.h b/src/vnet/fib/fib_path.h index 91f49d09234..14efc1ab842 100644 --- a/src/vnet/fib/fib_path.h +++ b/src/vnet/fib/fib_path.h @@ -62,6 +62,10 @@ typedef enum fib_path_cfg_attribute_t_ { * Recursion constraint via attached */ FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED, + /** + * The path is attached + */ + FIB_PATH_CFG_ATTRIBUTE_ATTACHED, /** * The path is a for-us path */ @@ -83,6 +87,7 @@ typedef enum fib_path_cfg_attribute_t_ { [FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST] = "resolve-host", \ [FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED] = "resolve-attached", \ [FIB_PATH_CFG_ATTRIBUTE_LOCAL] = "local", \ + [FIB_PATH_CFG_ATTRIBUTE_ATTACHED] = "attached", \ } #define FOR_EACH_FIB_PATH_CFG_ATTRIBUTE(_item) \ @@ -100,6 +105,7 @@ typedef enum fib_path_cfg_flags_t_ { FIB_PATH_CFG_FLAG_RESOLVE_HOST = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_HOST), FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_RESOLVE_ATTACHED), FIB_PATH_CFG_FLAG_LOCAL = (1 << FIB_PATH_CFG_ATTRIBUTE_LOCAL), + FIB_PATH_CFG_FLAG_ATTACHED = (1 << FIB_PATH_CFG_ATTRIBUTE_ATTACHED), } __attribute__ ((packed)) fib_path_cfg_flags_t; diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c index a0ce0bbb4de..7818d02e05d 100644 --- a/src/vnet/fib/fib_table.c +++ b/src/vnet/fib/fib_table.c @@ -480,6 +480,7 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix, path->frp_sw_if_index != ~0) { path->frp_addr = prefix->fp_addr; + path->frp_flags |= FIB_ROUTE_PATH_ATTACHED; } } diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h index 05e0e0af4c9..1c5299a9214 100644 --- a/src/vnet/fib/fib_types.h +++ b/src/vnet/fib/fib_types.h @@ -282,6 +282,10 @@ typedef enum fib_route_path_flags_t_ * A for-us/local path */ FIB_ROUTE_PATH_LOCAL = (1 << 2), + /** + * Attached path + */ + FIB_ROUTE_PATH_ATTACHED = (1 << 3), } fib_route_path_flags_t; /** diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index 28b09b55598..44798c8b33b 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -459,11 +459,26 @@ static void vl_api_sw_interface_set_unnumbered_t_handler { si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; si->unnumbered_sw_if_index = sw_if_index; + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip4_main. + lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index]; + ip6_main. + lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip6_main. + lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index]; } else { si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); si->unnumbered_sw_if_index = (u32) ~ 0; + + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; } ip4_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add); ip6_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add); diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index bd715e4ea4b..ec8530da299 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -864,6 +864,10 @@ set_unnumbered (vlib_main_t * vm, si->unnumbered_sw_if_index = (u32) ~ 0; ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0); ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0); + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = ~0; } else if (is_set) { @@ -871,6 +875,14 @@ set_unnumbered (vlib_main_t * vm, si->unnumbered_sw_if_index = inherit_from_sw_if_index; ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1); ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1); + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip4_main.lookup_main.if_address_pool_index_by_sw_if_index + [inherit_from_sw_if_index]; + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [unnumbered_sw_if_index] = + ip6_main.lookup_main.if_address_pool_index_by_sw_if_index + [inherit_from_sw_if_index]; } return 0; -- cgit 1.2.3-korg