diff options
Diffstat (limited to 'src/vnet/vxlan/vxlan.c')
-rw-r--r-- | src/vnet/vxlan/vxlan.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/src/vnet/vxlan/vxlan.c b/src/vnet/vxlan/vxlan.c index 97098b83774..dcf480578a7 100644 --- a/src/vnet/vxlan/vxlan.c +++ b/src/vnet/vxlan/vxlan.c @@ -442,29 +442,34 @@ int vnet_vxlan_add_del_tunnel return VNET_API_ERROR_INSTANCE_IN_USE; } - f64 now = vlib_time_now (vm); - u32 rnd; - rnd = (u32) (now * 1e6); - rnd = random_u32 (&rnd); - - memcpy (hw_addr + 2, &rnd, sizeof (rnd)); - hw_addr[0] = 2; - hw_addr[1] = 0xfe; - hash_set (vxm->instance_used, user_instance, 1); t->dev_instance = dev_instance; /* actual */ t->user_instance = user_instance; /* name */ t->flow_index = ~0; - if (ethernet_register_interface (vnm, vxlan_device_class.index, - dev_instance, hw_addr, &t->hw_if_index, - vxlan_eth_flag_change)) + if (a->is_l3) + t->hw_if_index = + vnet_register_interface (vnm, vxlan_device_class.index, dev_instance, + vxlan_hw_class.index, dev_instance); + else { - hash_unset (vxm->instance_used, t->user_instance); + f64 now = vlib_time_now (vm); + u32 rnd; + rnd = (u32) (now * 1e6); + rnd = random_u32 (&rnd); + memcpy (hw_addr + 2, &rnd, sizeof (rnd)); + hw_addr[0] = 2; + hw_addr[1] = 0xfe; + if (ethernet_register_interface ( + vnm, vxlan_device_class.index, dev_instance, hw_addr, + &t->hw_if_index, vxlan_eth_flag_change)) + { + hash_unset (vxm->instance_used, t->user_instance); - pool_put (vxm->tunnels, t); - return VNET_API_ERROR_SYSCALL_ERROR_2; + pool_put (vxm->tunnels, t); + return VNET_API_ERROR_SYSCALL_ERROR_2; + } } vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index); @@ -498,7 +503,10 @@ int vnet_vxlan_add_del_tunnel if (add_failed) { - ethernet_delete_interface (vnm, t->hw_if_index); + if (a->is_l3) + vnet_delete_hw_interface (vnm, t->hw_if_index); + else + ethernet_delete_interface (vnm, t->hw_if_index); hash_unset (vxm->instance_used, t->user_instance); pool_put (vxm->tunnels, t); return VNET_API_ERROR_INVALID_REGISTRATION; @@ -647,7 +655,11 @@ int vnet_vxlan_add_del_tunnel mcast_shared_remove (&t->dst); } - ethernet_delete_interface (vnm, t->hw_if_index); + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, t->hw_if_index); + if (hw->dev_class_index == vxlan_device_class.index) + vnet_delete_hw_interface (vnm, t->hw_if_index); + else + ethernet_delete_interface (vnm, t->hw_if_index); hash_unset (vxm->instance_used, t->user_instance); fib_node_deinit (&t->node); @@ -717,6 +729,7 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, u8 grp_set = 0; u8 ipv4_set = 0; u8 ipv6_set = 0; + u8 is_l3 = 0; u32 instance = ~0; u32 encap_fib_index = 0; u32 mcast_sw_if_index = ~0; @@ -764,6 +777,8 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, encap_fib_index = fib_table_find (fib_ip_proto (ipv6_set), table_id); } + else if (unformat (line_input, "l3")) + is_l3 = 1; else if (unformat (line_input, "decap-next %U", unformat_decap_next, &decap_next_index, ipv4_set)) ; @@ -786,6 +801,13 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, if (parse_error) return parse_error; + if (is_l3 && decap_next_index == VXLAN_INPUT_NEXT_L2_INPUT) + { + vlib_node_t *node = vlib_get_node_by_name ( + vm, (u8 *) (ipv4_set ? "ip4-input" : "ip6-input")); + decap_next_index = get_decap_next_for_node (node->index, ipv4_set); + } + if (encap_fib_index == ~0) return clib_error_return (0, "nonexistent encap-vrf-id %d", table_id); @@ -819,12 +841,12 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, if (vni >> 24) return clib_error_return (0, "vni %d out of range", vni); - vnet_vxlan_add_del_tunnel_args_t a = { - .is_add = is_add, - .is_ip6 = ipv6_set, - .instance = instance, + vnet_vxlan_add_del_tunnel_args_t a = { .is_add = is_add, + .is_ip6 = ipv6_set, + .is_l3 = is_l3, + .instance = instance, #define _(x) .x = x, - foreach_copy_field + foreach_copy_field #undef _ }; @@ -893,7 +915,7 @@ VLIB_CLI_COMMAND (create_vxlan_tunnel_command, static) = { "create vxlan tunnel src <local-vtep-addr>" " {dst <remote-vtep-addr>|group <mcast-vtep-addr> <intf-name>} vni <nn>" " [instance <id>]" - " [encap-vrf-id <nn>] [decap-next [l2|node <name>]] [del]" + " [encap-vrf-id <nn>] [decap-next [l2|node <name>]] [del] [l3]" " [src_port <local-vtep-udp-port>] [dst_port <remote-vtep-udp-port>]", .function = vxlan_add_del_tunnel_command_fn, }; |