netmap: Reinstate and update netmap plugin 75/40875/2
authorTom Jones <thj@freebsd.org>
Wed, 7 Feb 2024 14:55:20 +0000 (14:55 +0000)
committerDamjan Marion <dmarion@0xa5.net>
Tue, 14 May 2024 07:15:12 +0000 (07:15 +0000)
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>
13 files changed:
MAINTAINERS
extras/deprecated/netmap/dir.dox [deleted file]
src/plugins/netmap/CMakeLists.txt [new file with mode: 0644]
src/plugins/netmap/FEATURE.yaml [moved from extras/deprecated/netmap/FEATURE.yaml with 52% similarity]
src/plugins/netmap/cli.c [moved from extras/deprecated/netmap/cli.c with 98% similarity]
src/plugins/netmap/device.c [moved from extras/deprecated/netmap/device.c with 98% similarity]
src/plugins/netmap/net_netmap.h [moved from extras/deprecated/netmap/net_netmap.h with 99% similarity]
src/plugins/netmap/netmap.api [moved from extras/deprecated/netmap/netmap.api with 100% similarity]
src/plugins/netmap/netmap.c [moved from extras/deprecated/netmap/netmap.c with 80% similarity]
src/plugins/netmap/netmap.h [moved from extras/deprecated/netmap/netmap.h with 100% similarity]
src/plugins/netmap/netmap_api.c [moved from extras/deprecated/netmap/netmap_api.c with 59% similarity]
src/plugins/netmap/node.c [moved from extras/deprecated/netmap/node.c with 95% similarity]
src/plugins/netmap/plugin.c [new file with mode: 0644]

index c310e72..abc7faf 100644 (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/
diff --git a/extras/deprecated/netmap/dir.dox b/extras/deprecated/netmap/dir.dox
deleted file mode 100644 (file)
index 7ddbf94..0000000
+++ /dev/null
@@ -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 %% ?*/
diff --git a/src/plugins/netmap/CMakeLists.txt b/src/plugins/netmap/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d53a9e0
--- /dev/null
@@ -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
+)
similarity index 52%
rename from extras/deprecated/netmap/FEATURE.yaml
rename to src/plugins/netmap/FEATURE.yaml
index e23e5c2..a9dfb21 100644 (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
similarity index 98%
rename from extras/deprecated/netmap/cli.c
rename to src/plugins/netmap/cli.c
index 7136329..b54d397 100644 (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,
similarity index 98%
rename from extras/deprecated/netmap/device.c
rename to src/plugins/netmap/device.c
index 47407aa..505deb9 100644 (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")           \
similarity index 99%
rename from extras/deprecated/netmap/net_netmap.h
rename to src/plugins/netmap/net_netmap.h
index fd4253b..ecccedd 100644 (file)
 #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
similarity index 80%
rename from extras/deprecated/netmap/netmap.c
rename to src/plugins/netmap/netmap.c
index 7cab6bb..ebef215 100644 (file)
 #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>
 
-netmap_main_t netmap_main;
+#include <netmap/net_netmap.h>
+#include <netmap/netmap.h>
+#include <netmap/netmap.api_enum.h>
+#include <netmap/netmap.api_types.h>
 
-static u32
-netmap_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
-                       u32 flags)
-{
-  /* nothing for now */
-  return 0;
-}
+netmap_main_t netmap_main;
 
 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;
similarity index 59%
rename from extras/deprecated/netmap/netmap_api.c
rename to src/plugins/netmap/netmap_api.c
index ee05ec2..51f572a 100644 (file)
 
 #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;
 }
similarity index 95%
rename from extras/deprecated/netmap/node.c
rename to src/plugins/netmap/node.c
index b0a6882..6169847 100644 (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,
diff --git a/src/plugins/netmap/plugin.c b/src/plugins/netmap/plugin.c
new file mode 100644 (file)
index 0000000..1673225
--- /dev/null
@@ -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",
+};