diff options
Diffstat (limited to 'vpp/app')
-rw-r--r-- | vpp/app/vpe_cli.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/vpp/app/vpe_cli.c b/vpp/app/vpe_cli.c index b9f79688..3b24c26f 100644 --- a/vpp/app/vpe_cli.c +++ b/vpp/app/vpe_cli.c @@ -14,6 +14,8 @@ */ #include <vnet/ip/ip.h> #include <vnet/ethernet/ethernet.h> +#include <vnet/adj/adj.h> +#include <vnet/fib/fib_table.h> typedef struct { @@ -27,20 +29,25 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm, { unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t *vnm = vnet_get_main (); - ip4_main_t *im = &ip4_main; - ip_lookup_main_t *lm = &im->lookup_main; - ip4_address_t ip_addr, next_hop; + ip46_address_t next_hop, *next_hops; + fib_route_path_t *rpaths; + fib_prefix_t prefix; u8 mac_addr[6]; mac_addr_t *mac_addrs = 0; u32 sw_if_index; - u32 i, f; + u32 i; + + next_hops = NULL; + rpaths = NULL; + prefix.fp_len = 32; + prefix.fp_proto = FIB_PROTOCOL_IP4; /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; if (!unformat (line_input, "%U %U", - unformat_ip4_address, &ip_addr, + unformat_ip4_address, &prefix.fp_addr.ip4, unformat_vnet_sw_interface, vnm, &sw_if_index)) goto barf; @@ -53,6 +60,11 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm, vec_add2 (mac_addrs, ma, 1); clib_memcpy (ma, mac_addr, sizeof (mac_addr)); } + else if (unformat (line_input, "next-hop %U", + unformat_ip4_address, &next_hop.ip4)) + { + vec_add1 (next_hops, next_hop); + } else { barf: @@ -60,37 +72,37 @@ virtual_ip_cmd_fn_command_fn (vlib_main_t * vm, format_unformat_error, input); } } - if (vec_len (mac_addrs) == 0) + if (vec_len (mac_addrs) == 0 || + vec_len (next_hops) == 0 || vec_len (mac_addrs) != vec_len (next_hops)) goto barf; /* Create / delete special interface route /32's */ - next_hop.as_u32 = 0; for (i = 0; i < vec_len (mac_addrs); i++) { - ip_adjacency_t adj; - u32 adj_index; - - memset (&adj, 0, sizeof (adj)); - adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE; - - vnet_rewrite_for_sw_interface (vnm, VNET_L3_PACKET_TYPE_IP4, sw_if_index, ip4_rewrite_node.index, &mac_addrs[i], /* destination address */ - &adj.rewrite_header, - sizeof (adj.rewrite_data)); - - ip_add_adjacency (lm, &adj, 1 /* one adj */ , - &adj_index); - - f = - (i + 1 < vec_len (mac_addrs)) ? IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP : 0; - ip4_add_del_route_next_hop (im, IP4_ROUTE_FLAG_ADD | f, &ip_addr, - 32 /* insert /32's */ , - &next_hop, sw_if_index, 1 /* weight */ , - adj_index, - (u32) ~ 0 /* explicit fib index */ ); + fib_route_path_t *rpath; + + adj_nbr_add_or_lock_w_rewrite (FIB_PROTOCOL_IP4, + FIB_LINK_IP4, + &next_hops[i], + sw_if_index, mac_addrs[i].mac_addr); + + vec_add2 (rpaths, rpath, 1); + + rpath->frp_proto = FIB_PROTOCOL_IP4; + rpath->frp_addr = next_hops[i]; + rpath->frp_sw_if_index = sw_if_index; + rpath->frp_fib_index = ~0; + rpath->frp_weight = 1; + rpath->frp_label = MPLS_LABEL_INVALID; } + fib_table_entry_path_add2 (0, // default FIB table + &prefix, + FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, rpaths); + vec_free (mac_addrs); + vec_free (next_hops); return 0; } |