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:
Tom Jones 2024-02-07 14:55:20 +00:00 committed by Damjan Marion
parent 2516b1ac73
commit 16cc51b88a
13 changed files with 134 additions and 133 deletions

View File

@ -892,3 +892,8 @@ M: vpp-dev Mailing List <vpp-dev@fd.io>
C: Missing Maintainer
F: *
F: */
Netmap
I: netmap
M: Tom Jones <thj@freebsd.org>
F: src/plugins/netmap/

View File

@ -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 %% ?*/

View 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
)

View File

@ -1,11 +1,11 @@
---
name: Netmap Device
maintainer: Damjan Marion <damarion@cisco.com>
maintainer: Tom Jones <thj@freebsd.org>
features:
- L4 checksum offload
description: "Create a netmap interface, which is a high speed user-space
interface that allows VPP to patch into a linux namespace,
a linux container, or a physical NIC without the use of DPDK."
interface that allows VPP to patch to a physical or virtual NIC
without the use of DPDK"
missing:
- API dump
state: production

View File

@ -22,8 +22,8 @@
#include <vlib/unix/unix.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/devices/netmap/net_netmap.h>
#include <vnet/devices/netmap/netmap.h>
#include <netmap/net_netmap.h>
#include <netmap/netmap.h>
static clib_error_t *
netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,

View File

@ -23,8 +23,8 @@
#include <vlib/unix/unix.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/devices/netmap/net_netmap.h>
#include <vnet/devices/netmap/netmap.h>
#include <netmap/net_netmap.h>
#include <netmap/netmap.h>
#define foreach_netmap_tx_func_error \
_(NO_FREE_SLOTS, "no free tx slots") \

View File

@ -39,10 +39,10 @@
#ifndef _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_MAX_API 15
#define NETMAP_MIN_API 14 /* min and max versions accepted */
#define NETMAP_MAX_API 15
/*
* Some fields should be cache-aligned to reduce contention.
* The alignment is architecture and OS dependent, but rather than

View File

@ -20,23 +20,18 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <vnet/devices/netmap/net_netmap.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.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;
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 *
netmap_fd_read_ready (clib_file_t * uf)
{
@ -88,12 +83,11 @@ int
netmap_worker_thread_enable ()
{
/* if worker threads are enabled, switch to polling mode */
foreach_vlib_main ((
{
vlib_node_set_state (this_vlib_main,
netmap_input_node.index,
VLIB_NODE_STATE_POLLING);
}));
foreach_vlib_main ()
{
vlib_node_set_state (this_vlib_main, netmap_input_node.index,
VLIB_NODE_STATE_POLLING);
}
return 0;
}
@ -101,12 +95,11 @@ netmap_worker_thread_enable ()
int
netmap_worker_thread_disable ()
{
foreach_vlib_main ((
{
vlib_node_set_state (this_vlib_main,
netmap_input_node.index,
VLIB_NODE_STATE_INTERRUPT);
}));
foreach_vlib_main ()
{
vlib_node_set_state (this_vlib_main, netmap_input_node.index,
VLIB_NODE_STATE_INTERRUPT);
}
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;
int ret = 0;
uint32_t nr_reg;
netmap_if_t *nif = 0;
u8 hw_addr[6];
clib_error_t *error = 0;
vnet_sw_interface_t *sw;
vnet_main_t *vnm = vnet_get_main ();
uword *p;
@ -179,10 +172,39 @@ netmap_create_if (vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
reg->refcnt++;
nif->nifp = NETMAP_IF (reg->mem, req->nr_offset);
nif->first_rx_ring = 0;
nif->last_rx_ring = 0;
nif->first_tx_ring = 0;
nif->last_tx_ring = 0;
nr_reg = nif->req->nr_flags & NR_REG_MASK;
if (nr_reg == NR_REG_SW)
{ /* 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->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;
}
error = ethernet_register_interface (vnm, netmap_device_class.index,
nif->if_index, hw_addr,
&nif->hw_if_index,
netmap_eth_flag_change);
vnet_eth_interface_registration_t eir = {};
if (error)
{
clib_error_report (error);
ret = VNET_API_ERROR_SYSCALL_ERROR_1;
goto error;
}
eir.dev_class_index = netmap_device_class.index;
eir.dev_instance = nif->if_index;
eir.address = hw_addr;
eir.cb.set_max_frame_size = NULL;
nif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
sw = vnet_get_hw_sw_interface (vnm, nif->hw_if_index);
nif->sw_if_index = sw->sw_if_index;

View File

@ -22,23 +22,11 @@
#include <vnet/interface.h>
#include <vnet/api_errno.h>
#include <vnet/devices/netmap/netmap.h>
#include <netmap/netmap.h>
#include <vnet/vnet_msg_enum.h>
#define vl_typedefs /* define message structures */
#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 <vnet/format_fns.h>
#include <netmap/netmap.api_enum.h>
#include <netmap/netmap.api_types.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);
}
/*
* 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 _
}
#include <netmap/netmap.api.c>
static clib_error_t *
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
*/
setup_message_id_table (am);
setup_message_id_table ();
return 0;
}

View File

@ -25,8 +25,8 @@
#include <vnet/devices/devices.h>
#include <vnet/feature/feature.h>
#include <vnet/devices/netmap/net_netmap.h>
#include <vnet/devices/netmap/netmap.h>
#include <netmap/net_netmap.h>
#include <netmap/netmap.h>
#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 +=
vlib_buffer_alloc (vm, &nm->rx_buffers[thread_index][n_free_bufs],
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;
@ -166,7 +166,8 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
prev_bi0 = bi0;
bi0 = nm->rx_buffers[thread_index][last_empty_buffer];
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--;
/* copy data */
@ -200,11 +201,12 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* trace */
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;
vlib_trace_buffer (vm, node, next0, first_b0,
/* follow_chain */ 0);
vlib_set_trace_count (vm, node, --n_trace);
tr = vlib_add_trace (vm, node, first_b0, sizeof (*tr));
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 */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, first_bi0,

View 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",
};