netmap: Reinstate and update netmap plugin
Thet netmap plugin was moved to depreciated in commit 998b8fe. On FreeBSD netmap offers a natively supported kernel interface for userspace networking and enables VPP without the use of DPDK. Reinstate the netmap plugin and adapt it to the newer plugin interface. Type: improvement Change-Id: I113daa33a490f04cbb29909f9789fa66284ac80e Signed-off-by: Tom Jones <thj@freebsd.org>
This commit is contained in:
@ -892,3 +892,8 @@ M: vpp-dev Mailing List <vpp-dev@fd.io>
|
|||||||
C: Missing Maintainer
|
C: Missing Maintainer
|
||||||
F: *
|
F: *
|
||||||
F: */
|
F: */
|
||||||
|
|
||||||
|
Netmap
|
||||||
|
I: netmap
|
||||||
|
M: Tom Jones <thj@freebsd.org>
|
||||||
|
F: src/plugins/netmap/
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Doxygen directory documentation */
|
|
||||||
|
|
||||||
/**
|
|
||||||
@dir
|
|
||||||
@brief netmap Interface Implementation.
|
|
||||||
|
|
||||||
This directory contains the source code for the netmap driver.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/*? %%clicmd:group_label netmap %% ?*/
|
|
||||||
/*? %%syscfg:group_label netmap %% ?*/
|
|
32
src/plugins/netmap/CMakeLists.txt
Normal file
32
src/plugins/netmap/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
# Copyright (c) 2024 Tom Jones <thj@freebsd.org>
|
||||||
|
#
|
||||||
|
# This software was developed by Tom Jones <thj@freebsd.org> under sponsorship
|
||||||
|
# from the FreeBSD Foundation.
|
||||||
|
#
|
||||||
|
|
||||||
|
if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
|
||||||
|
message(WARNING "Netmap is only currently support on FreeBSD - netmap plugin disabled")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_vpp_plugin(netmap
|
||||||
|
SOURCES
|
||||||
|
plugin.c
|
||||||
|
netmap.c
|
||||||
|
node.c
|
||||||
|
device.c
|
||||||
|
cli.c
|
||||||
|
netmap_api.c
|
||||||
|
|
||||||
|
MULTIARCH_SOURCES
|
||||||
|
node.c
|
||||||
|
device.c
|
||||||
|
|
||||||
|
INSTALL_HEADERS
|
||||||
|
netmap.h
|
||||||
|
net_netmap.h
|
||||||
|
|
||||||
|
API_FILES
|
||||||
|
netmap.api
|
||||||
|
)
|
@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
name: Netmap Device
|
name: Netmap Device
|
||||||
maintainer: Damjan Marion <damarion@cisco.com>
|
maintainer: Tom Jones <thj@freebsd.org>
|
||||||
features:
|
features:
|
||||||
- L4 checksum offload
|
- L4 checksum offload
|
||||||
description: "Create a netmap interface, which is a high speed user-space
|
description: "Create a netmap interface, which is a high speed user-space
|
||||||
interface that allows VPP to patch into a linux namespace,
|
interface that allows VPP to patch to a physical or virtual NIC
|
||||||
a linux container, or a physical NIC without the use of DPDK."
|
without the use of DPDK"
|
||||||
missing:
|
missing:
|
||||||
- API dump
|
- API dump
|
||||||
state: production
|
state: production
|
@ -22,8 +22,8 @@
|
|||||||
#include <vlib/unix/unix.h>
|
#include <vlib/unix/unix.h>
|
||||||
#include <vnet/ethernet/ethernet.h>
|
#include <vnet/ethernet/ethernet.h>
|
||||||
|
|
||||||
#include <vnet/devices/netmap/net_netmap.h>
|
#include <netmap/net_netmap.h>
|
||||||
#include <vnet/devices/netmap/netmap.h>
|
#include <netmap/netmap.h>
|
||||||
|
|
||||||
static clib_error_t *
|
static clib_error_t *
|
||||||
netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
@ -23,8 +23,8 @@
|
|||||||
#include <vlib/unix/unix.h>
|
#include <vlib/unix/unix.h>
|
||||||
#include <vnet/ethernet/ethernet.h>
|
#include <vnet/ethernet/ethernet.h>
|
||||||
|
|
||||||
#include <vnet/devices/netmap/net_netmap.h>
|
#include <netmap/net_netmap.h>
|
||||||
#include <vnet/devices/netmap/netmap.h>
|
#include <netmap/netmap.h>
|
||||||
|
|
||||||
#define foreach_netmap_tx_func_error \
|
#define foreach_netmap_tx_func_error \
|
||||||
_(NO_FREE_SLOTS, "no free tx slots") \
|
_(NO_FREE_SLOTS, "no free tx slots") \
|
@ -39,10 +39,10 @@
|
|||||||
#ifndef _NET_NETMAP_H_
|
#ifndef _NET_NETMAP_H_
|
||||||
#define _NET_NETMAP_H_
|
#define _NET_NETMAP_H_
|
||||||
|
|
||||||
#define NETMAP_API 11 /* current API version */
|
#define NETMAP_API 14 /* current API version */
|
||||||
|
|
||||||
#define NETMAP_MIN_API 11 /* min and max versions accepted */
|
#define NETMAP_MIN_API 14 /* min and max versions accepted */
|
||||||
#define NETMAP_MAX_API 15
|
#define NETMAP_MAX_API 15
|
||||||
/*
|
/*
|
||||||
* Some fields should be cache-aligned to reduce contention.
|
* Some fields should be cache-aligned to reduce contention.
|
||||||
* The alignment is architecture and OS dependent, but rather than
|
* The alignment is architecture and OS dependent, but rather than
|
@ -20,23 +20,18 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <vnet/devices/netmap/net_netmap.h>
|
|
||||||
|
|
||||||
#include <vlib/vlib.h>
|
#include <vlib/vlib.h>
|
||||||
#include <vlib/unix/unix.h>
|
#include <vlib/unix/unix.h>
|
||||||
#include <vnet/ethernet/ethernet.h>
|
#include <vnet/ethernet/ethernet.h>
|
||||||
#include <vnet/devices/netmap/netmap.h>
|
|
||||||
|
#include <netmap/net_netmap.h>
|
||||||
|
#include <netmap/netmap.h>
|
||||||
|
#include <netmap/netmap.api_enum.h>
|
||||||
|
#include <netmap/netmap.api_types.h>
|
||||||
|
|
||||||
netmap_main_t netmap_main;
|
netmap_main_t netmap_main;
|
||||||
|
|
||||||
static u32
|
|
||||||
netmap_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
|
|
||||||
u32 flags)
|
|
||||||
{
|
|
||||||
/* nothing for now */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static clib_error_t *
|
static clib_error_t *
|
||||||
netmap_fd_read_ready (clib_file_t * uf)
|
netmap_fd_read_ready (clib_file_t * uf)
|
||||||
{
|
{
|
||||||
@ -88,12 +83,11 @@ int
|
|||||||
netmap_worker_thread_enable ()
|
netmap_worker_thread_enable ()
|
||||||
{
|
{
|
||||||
/* if worker threads are enabled, switch to polling mode */
|
/* if worker threads are enabled, switch to polling mode */
|
||||||
foreach_vlib_main ((
|
foreach_vlib_main ()
|
||||||
{
|
{
|
||||||
vlib_node_set_state (this_vlib_main,
|
vlib_node_set_state (this_vlib_main, netmap_input_node.index,
|
||||||
netmap_input_node.index,
|
VLIB_NODE_STATE_POLLING);
|
||||||
VLIB_NODE_STATE_POLLING);
|
}
|
||||||
}));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -101,12 +95,11 @@ netmap_worker_thread_enable ()
|
|||||||
int
|
int
|
||||||
netmap_worker_thread_disable ()
|
netmap_worker_thread_disable ()
|
||||||
{
|
{
|
||||||
foreach_vlib_main ((
|
foreach_vlib_main ()
|
||||||
{
|
{
|
||||||
vlib_node_set_state (this_vlib_main,
|
vlib_node_set_state (this_vlib_main, netmap_input_node.index,
|
||||||
netmap_input_node.index,
|
VLIB_NODE_STATE_INTERRUPT);
|
||||||
VLIB_NODE_STATE_INTERRUPT);
|
}
|
||||||
}));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -117,9 +110,9 @@ netmap_create_if (vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
|
|||||||
{
|
{
|
||||||
netmap_main_t *nm = &netmap_main;
|
netmap_main_t *nm = &netmap_main;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
uint32_t nr_reg;
|
||||||
netmap_if_t *nif = 0;
|
netmap_if_t *nif = 0;
|
||||||
u8 hw_addr[6];
|
u8 hw_addr[6];
|
||||||
clib_error_t *error = 0;
|
|
||||||
vnet_sw_interface_t *sw;
|
vnet_sw_interface_t *sw;
|
||||||
vnet_main_t *vnm = vnet_get_main ();
|
vnet_main_t *vnm = vnet_get_main ();
|
||||||
uword *p;
|
uword *p;
|
||||||
@ -179,10 +172,39 @@ netmap_create_if (vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
|
|||||||
reg->refcnt++;
|
reg->refcnt++;
|
||||||
|
|
||||||
nif->nifp = NETMAP_IF (reg->mem, req->nr_offset);
|
nif->nifp = NETMAP_IF (reg->mem, req->nr_offset);
|
||||||
nif->first_rx_ring = 0;
|
nr_reg = nif->req->nr_flags & NR_REG_MASK;
|
||||||
nif->last_rx_ring = 0;
|
|
||||||
nif->first_tx_ring = 0;
|
if (nr_reg == NR_REG_SW)
|
||||||
nif->last_tx_ring = 0;
|
{ /* host stack */
|
||||||
|
nif->first_tx_ring = nif->last_tx_ring = nif->req->nr_tx_rings;
|
||||||
|
nif->first_rx_ring = nif->last_rx_ring = nif->req->nr_rx_rings;
|
||||||
|
}
|
||||||
|
else if (nr_reg == NR_REG_ALL_NIC)
|
||||||
|
{ /* only nic */
|
||||||
|
nif->first_tx_ring = 0;
|
||||||
|
nif->first_rx_ring = 0;
|
||||||
|
nif->last_tx_ring = nif->req->nr_tx_rings - 1;
|
||||||
|
nif->last_rx_ring = nif->req->nr_rx_rings - 1;
|
||||||
|
}
|
||||||
|
else if (nr_reg == NR_REG_NIC_SW)
|
||||||
|
{
|
||||||
|
nif->first_tx_ring = 0;
|
||||||
|
nif->first_rx_ring = 0;
|
||||||
|
nif->last_tx_ring = nif->req->nr_tx_rings;
|
||||||
|
nif->last_rx_ring = nif->req->nr_rx_rings;
|
||||||
|
}
|
||||||
|
else if (nr_reg == NR_REG_ONE_NIC)
|
||||||
|
{
|
||||||
|
/* XXX check validity */
|
||||||
|
nif->first_tx_ring = nif->last_tx_ring = nif->first_rx_ring =
|
||||||
|
nif->last_rx_ring = nif->req->nr_ringid & NETMAP_RING_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* pipes */
|
||||||
|
nif->first_tx_ring = nif->last_tx_ring = 0;
|
||||||
|
nif->first_rx_ring = nif->last_rx_ring = 0;
|
||||||
|
}
|
||||||
|
|
||||||
nif->host_if_name = if_name;
|
nif->host_if_name = if_name;
|
||||||
nif->per_interface_next_index = ~0;
|
nif->per_interface_next_index = ~0;
|
||||||
|
|
||||||
@ -213,17 +235,14 @@ netmap_create_if (vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
|
|||||||
hw_addr[1] = 0xfe;
|
hw_addr[1] = 0xfe;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ethernet_register_interface (vnm, netmap_device_class.index,
|
vnet_eth_interface_registration_t eir = {};
|
||||||
nif->if_index, hw_addr,
|
|
||||||
&nif->hw_if_index,
|
|
||||||
netmap_eth_flag_change);
|
|
||||||
|
|
||||||
if (error)
|
eir.dev_class_index = netmap_device_class.index;
|
||||||
{
|
eir.dev_instance = nif->if_index;
|
||||||
clib_error_report (error);
|
eir.address = hw_addr;
|
||||||
ret = VNET_API_ERROR_SYSCALL_ERROR_1;
|
eir.cb.set_max_frame_size = NULL;
|
||||||
goto error;
|
|
||||||
}
|
nif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
|
||||||
|
|
||||||
sw = vnet_get_hw_sw_interface (vnm, nif->hw_if_index);
|
sw = vnet_get_hw_sw_interface (vnm, nif->hw_if_index);
|
||||||
nif->sw_if_index = sw->sw_if_index;
|
nif->sw_if_index = sw->sw_if_index;
|
@ -22,23 +22,11 @@
|
|||||||
|
|
||||||
#include <vnet/interface.h>
|
#include <vnet/interface.h>
|
||||||
#include <vnet/api_errno.h>
|
#include <vnet/api_errno.h>
|
||||||
#include <vnet/devices/netmap/netmap.h>
|
#include <netmap/netmap.h>
|
||||||
|
|
||||||
#include <vnet/vnet_msg_enum.h>
|
#include <vnet/format_fns.h>
|
||||||
|
#include <netmap/netmap.api_enum.h>
|
||||||
#define vl_typedefs /* define message structures */
|
#include <netmap/netmap.api_types.h>
|
||||||
#include <vnet/vnet_all_api_h.h>
|
|
||||||
#undef vl_typedefs
|
|
||||||
|
|
||||||
#define vl_endianfun /* define message structures */
|
|
||||||
#include <vnet/vnet_all_api_h.h>
|
|
||||||
#undef vl_endianfun
|
|
||||||
|
|
||||||
/* instantiate all the print functions we know about */
|
|
||||||
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
|
|
||||||
#define vl_printfun
|
|
||||||
#include <vnet/vnet_all_api_h.h>
|
|
||||||
#undef vl_printfun
|
|
||||||
|
|
||||||
#include <vlibapi/api_helper_macros.h>
|
#include <vlibapi/api_helper_macros.h>
|
||||||
|
|
||||||
@ -84,44 +72,14 @@ vl_api_netmap_delete_t_handler (vl_api_netmap_delete_t * mp)
|
|||||||
REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
|
REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#include <netmap/netmap.api.c>
|
||||||
* netmap_api_hookup
|
|
||||||
* Add vpe's API message handlers to the table.
|
|
||||||
* vlib has already mapped shared memory and
|
|
||||||
* added the client registration handlers.
|
|
||||||
* See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
|
|
||||||
*/
|
|
||||||
#define vl_msg_name_crc_list
|
|
||||||
#include <vnet/vnet_all_api_h.h>
|
|
||||||
#undef vl_msg_name_crc_list
|
|
||||||
|
|
||||||
static void
|
|
||||||
setup_message_id_table (api_main_t * am)
|
|
||||||
{
|
|
||||||
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
|
|
||||||
foreach_vl_msg_name_crc_netmap;
|
|
||||||
#undef _
|
|
||||||
}
|
|
||||||
|
|
||||||
static clib_error_t *
|
static clib_error_t *
|
||||||
netmap_api_hookup (vlib_main_t * vm)
|
netmap_api_hookup (vlib_main_t * vm)
|
||||||
{
|
{
|
||||||
api_main_t *am = vlibapi_get_main ();
|
|
||||||
|
|
||||||
#define _(N,n) \
|
|
||||||
vl_msg_api_set_handlers(VL_API_##N, #n, \
|
|
||||||
vl_api_##n##_t_handler, \
|
|
||||||
vl_noop_handler, \
|
|
||||||
vl_api_##n##_t_endian, \
|
|
||||||
vl_api_##n##_t_print, \
|
|
||||||
sizeof(vl_api_##n##_t), 1);
|
|
||||||
foreach_vpe_api_msg;
|
|
||||||
#undef _
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the (msg_name, crc, message-id) table
|
* Set up the (msg_name, crc, message-id) table
|
||||||
*/
|
*/
|
||||||
setup_message_id_table (am);
|
setup_message_id_table ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -25,8 +25,8 @@
|
|||||||
#include <vnet/devices/devices.h>
|
#include <vnet/devices/devices.h>
|
||||||
#include <vnet/feature/feature.h>
|
#include <vnet/feature/feature.h>
|
||||||
|
|
||||||
#include <vnet/devices/netmap/net_netmap.h>
|
#include <netmap/net_netmap.h>
|
||||||
#include <vnet/devices/netmap/netmap.h>
|
#include <netmap/netmap.h>
|
||||||
|
|
||||||
#define foreach_netmap_input_error
|
#define foreach_netmap_input_error
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
n_free_bufs +=
|
n_free_bufs +=
|
||||||
vlib_buffer_alloc (vm, &nm->rx_buffers[thread_index][n_free_bufs],
|
vlib_buffer_alloc (vm, &nm->rx_buffers[thread_index][n_free_bufs],
|
||||||
VLIB_FRAME_SIZE);
|
VLIB_FRAME_SIZE);
|
||||||
_vec_len (nm->rx_buffers[thread_index]) = n_free_bufs;
|
vec_set_len (nm->rx_buffers[thread_index], n_free_bufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_ring = nif->first_rx_ring;
|
cur_ring = nif->first_rx_ring;
|
||||||
@ -166,7 +166,8 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
prev_bi0 = bi0;
|
prev_bi0 = bi0;
|
||||||
bi0 = nm->rx_buffers[thread_index][last_empty_buffer];
|
bi0 = nm->rx_buffers[thread_index][last_empty_buffer];
|
||||||
b0 = vlib_get_buffer (vm, bi0);
|
b0 = vlib_get_buffer (vm, bi0);
|
||||||
_vec_len (nm->rx_buffers[thread_index]) = last_empty_buffer;
|
vec_set_len (nm->rx_buffers[thread_index],
|
||||||
|
last_empty_buffer);
|
||||||
n_free_bufs--;
|
n_free_bufs--;
|
||||||
|
|
||||||
/* copy data */
|
/* copy data */
|
||||||
@ -200,11 +201,12 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
/* trace */
|
/* trace */
|
||||||
if (PREDICT_FALSE (n_trace > 0))
|
if (PREDICT_FALSE (n_trace > 0))
|
||||||
{
|
{
|
||||||
if (PREDICT_TRUE (first_b0 != 0))
|
if (PREDICT_TRUE (first_b0 != 0) &&
|
||||||
|
vlib_trace_buffer (vm, node, next0, first_b0,
|
||||||
|
/* follow_chain */ 0))
|
||||||
{
|
{
|
||||||
netmap_input_trace_t *tr;
|
netmap_input_trace_t *tr;
|
||||||
vlib_trace_buffer (vm, node, next0, first_b0,
|
|
||||||
/* follow_chain */ 0);
|
|
||||||
vlib_set_trace_count (vm, node, --n_trace);
|
vlib_set_trace_count (vm, node, --n_trace);
|
||||||
tr = vlib_add_trace (vm, node, first_b0, sizeof (*tr));
|
tr = vlib_add_trace (vm, node, first_b0, sizeof (*tr));
|
||||||
tr->next_index = next0;
|
tr->next_index = next0;
|
||||||
@ -213,10 +215,6 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* redirect if feature path enabled */
|
|
||||||
vnet_feature_start_device_input_x1 (nif->sw_if_index, &next0,
|
|
||||||
first_b0);
|
|
||||||
|
|
||||||
/* enque and take next packet */
|
/* enque and take next packet */
|
||||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
||||||
n_left_to_next, first_bi0,
|
n_left_to_next, first_bi0,
|
16
src/plugins/netmap/plugin.c
Normal file
16
src/plugins/netmap/plugin.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright (c) 2024 Tom Jones <thj@freebsd.org>
|
||||||
|
*
|
||||||
|
* This software was developed by Tom Jones <thj@freebsd.org> under sponsorship
|
||||||
|
* from the FreeBSD Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vlib/vlib.h>
|
||||||
|
#include <vnet/plugin/plugin.h>
|
||||||
|
#include <vpp/app/version.h>
|
||||||
|
|
||||||
|
VLIB_PLUGIN_REGISTER () = {
|
||||||
|
.version = VPP_BUILD_VER,
|
||||||
|
.description = "netmap",
|
||||||
|
};
|
Reference in New Issue
Block a user