Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jul 2018 14:40:34 GMT
From:      sduo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r337267 - in soc2018/sduo: head/sys/conf head/sys/dev/netmap head/sys/net netmap_utils netmap_utils/tests
Message-ID:  <201807061440.w66EeYWi014114@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sduo
Date: Fri Jul  6 14:40:31 2018
New Revision: 337267
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337267

Log:
  Added test suite for netmap. Updated netmap source files.

Added:
  soc2018/sduo/head/sys/dev/netmap/netmap_bdg.c
  soc2018/sduo/head/sys/dev/netmap/netmap_bdg.h
  soc2018/sduo/netmap_utils/GNUmakefile
  soc2018/sduo/netmap_utils/get_tx_rings_avail_sends.c
  soc2018/sduo/netmap_utils/get_tx_rings_max_sends.c
  soc2018/sduo/netmap_utils/randomized_tests   (contents, props changed)
  soc2018/sduo/netmap_utils/test_lib
  soc2018/sduo/netmap_utils/tests/
  soc2018/sduo/netmap_utils/tests/exclusive_open_ephemeral_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/exclusive_open_persistent_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/exclusive_open_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/extra_buf_send_rec_ephemeral_vale_ports_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/extra_buf_send_rec_persistent_vale_ports_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/extra_buf_send_rec_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/learning_bridge_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/partial_read_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/persistent_vale_port_destroy   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/persistent_vale_port_double_attach   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/persistent_vale_port_double_create   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_cp_mon_ephemeral_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_cp_mon_persistent_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_cp_mon_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_zcp_mon_ephemeral_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_zcp_mon_persistent_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/rec_zcp_mon_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_cp_mon_ephemeral_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_cp_mon_persistent_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_cp_mon_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_rec_ephemeral_vale_ports_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_rec_persistent_vale_ports_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_rec_pipe_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_rec_veth_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_zcp_mon_ephemeral_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_zcp_mon_persistent_vale_port_test   (contents, props changed)
  soc2018/sduo/netmap_utils/tests/send_zcp_mon_pipe_test   (contents, props changed)
Modified:
  soc2018/sduo/head/sys/conf/files
  soc2018/sduo/head/sys/dev/netmap/if_em_netmap.h
  soc2018/sduo/head/sys/dev/netmap/if_igb_netmap.h
  soc2018/sduo/head/sys/dev/netmap/if_lem_netmap.h
  soc2018/sduo/head/sys/dev/netmap/if_ptnet.c
  soc2018/sduo/head/sys/dev/netmap/if_re_netmap.h
  soc2018/sduo/head/sys/dev/netmap/ixgbe_netmap.h
  soc2018/sduo/head/sys/dev/netmap/netmap.c
  soc2018/sduo/head/sys/dev/netmap/netmap_freebsd.c
  soc2018/sduo/head/sys/dev/netmap/netmap_generic.c
  soc2018/sduo/head/sys/dev/netmap/netmap_kern.h
  soc2018/sduo/head/sys/dev/netmap/netmap_legacy.c
  soc2018/sduo/head/sys/dev/netmap/netmap_mbq.c
  soc2018/sduo/head/sys/dev/netmap/netmap_mbq.h
  soc2018/sduo/head/sys/dev/netmap/netmap_mem2.c
  soc2018/sduo/head/sys/dev/netmap/netmap_mem2.h
  soc2018/sduo/head/sys/dev/netmap/netmap_monitor.c
  soc2018/sduo/head/sys/dev/netmap/netmap_offloadings.c
  soc2018/sduo/head/sys/dev/netmap/netmap_pipe.c
  soc2018/sduo/head/sys/dev/netmap/netmap_pt.c
  soc2018/sduo/head/sys/dev/netmap/netmap_vale.c
  soc2018/sduo/head/sys/net/netmap.h
  soc2018/sduo/head/sys/net/netmap_legacy.h
  soc2018/sduo/head/sys/net/netmap_user.h
  soc2018/sduo/netmap_utils/fd_server.c
  soc2018/sduo/netmap_utils/fd_server.h
  soc2018/sduo/netmap_utils/functional.c

Modified: soc2018/sduo/head/sys/conf/files
==============================================================================
--- soc2018/sduo/head/sys/conf/files	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/conf/files	Fri Jul  6 14:40:31 2018	(r337267)
@@ -673,7 +673,7 @@
 crypto/rijndael/rijndael-api.c	optional crypto | ipsec | ipsec_support | \
 	wlan_ccmp
 crypto/sha1.c			optional carp | crypto | ipsec | \
-	ipsec_support | netgraph_mppc_encryption | sctp 
+	ipsec_support | netgraph_mppc_encryption | sctp
 crypto/sha2/sha256c.c		optional crypto | ekcd | geom_bde | ipsec | \
 	ipsec_support | random !random_loadable | sctp | zfs
 crypto/sha2/sha512c.c		optional crypto | geom_bde | ipsec | \
@@ -1280,7 +1280,7 @@
 dev/bhnd/cores/chipc/bhnd_sprom_chipc.c	optional bhnd
 dev/bhnd/cores/chipc/bhnd_pmu_chipc.c	optional bhnd
 dev/bhnd/cores/chipc/chipc.c		optional bhnd
-dev/bhnd/cores/chipc/chipc_cfi.c	optional bhnd cfi 
+dev/bhnd/cores/chipc/chipc_cfi.c	optional bhnd cfi
 dev/bhnd/cores/chipc/chipc_gpio.c	optional bhnd gpio
 dev/bhnd/cores/chipc/chipc_slicer.c	optional bhnd cfi | bhnd spibus
 dev/bhnd/cores/chipc/chipc_spi.c	optional bhnd spibus
@@ -2537,6 +2537,7 @@
 dev/netmap/netmap_pipe.c	optional netmap
 dev/netmap/netmap_pt.c		optional netmap
 dev/netmap/netmap_vale.c	optional netmap
+dev/netmap/netmap_bdg.c		optional netmap
 dev/netmap/netmap_legacy.c	optional netmap
 dev/vale_vlan/vale_vlan.c	optional vale_vlan
 dev/vale_vlan/vv_freebsd_interface.c	optional vale_vlan

Modified: soc2018/sduo/head/sys/dev/netmap/if_em_netmap.h
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/if_em_netmap.h	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/if_em_netmap.h	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: soc2018/sduo/head/sys/dev/netmap/if_igb_netmap.h
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/if_igb_netmap.h	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/if_igb_netmap.h	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Universita` di Pisa. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: soc2018/sduo/head/sys/dev/netmap/if_lem_netmap.h
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/if_lem_netmap.h	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/if_lem_netmap.h	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: soc2018/sduo/head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/if_ptnet.c	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/if_ptnet.c	Fri Jul  6 14:40:31 2018	(r337267)
@@ -210,7 +210,7 @@
 static void	ptnet_irqs_fini(struct ptnet_softc *sc);
 
 static uint32_t ptnet_nm_ptctl(if_t ifp, uint32_t cmd);
-static int	ptnet_nm_config(struct netmap_adapter *na,
+static int      ptnet_nm_config(struct netmap_adapter *na,
 				struct nm_config_info *info);
 static void	ptnet_update_vnet_hdr(struct ptnet_softc *sc);
 static int	ptnet_nm_register(struct netmap_adapter *na, int onoff);

Modified: soc2018/sduo/head/sys/dev/netmap/if_re_netmap.h
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/if_re_netmap.h	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/if_re_netmap.h	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: soc2018/sduo/head/sys/dev/netmap/ixgbe_netmap.h
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/ixgbe_netmap.h	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/ixgbe_netmap.h	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without

Modified: soc2018/sduo/head/sys/dev/netmap/netmap.c
==============================================================================
--- soc2018/sduo/head/sys/dev/netmap/netmap.c	Fri Jun 29 19:38:59 2018	(r337266)
+++ soc2018/sduo/head/sys/dev/netmap/netmap.c	Fri Jul  6 14:40:31 2018	(r337267)
@@ -1,6 +1,4 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
+/*
  * Copyright (C) 2011-2014 Matteo Landi
  * Copyright (C) 2011-2016 Luigi Rizzo
  * Copyright (C) 2011-2016 Giuseppe Lettieri
@@ -521,6 +519,9 @@
 int netmap_generic_ringsize = 1024;
 int netmap_generic_rings = 1;
 
+/* Non-zero to enable checksum offloading in NIC drivers */
+int netmap_generic_hwcsum = 0;
+
 /* Non-zero if ptnet devices are allowed to use virtio-net headers. */
 int ptnet_vnet_hdr = 1;
 
@@ -536,35 +537,38 @@
 SYSCTL_DECL(_dev_netmap);
 SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
 SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,
-    CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode");
+		CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode");
 SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp,
-    CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp");
+		CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp");
 SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr, CTLFLAG_RW, &netmap_no_pendintr,
-    0, "Always look for new received packets.");
+		0, "Always look for new received packets.");
 SYSCTL_INT(_dev_netmap, OID_AUTO, txsync_retry, CTLFLAG_RW,
-    &netmap_txsync_retry, 0, "Number of txsync loops in bridge's flush.");
+		&netmap_txsync_retry, 0, "Number of txsync loops in bridge's flush.");
 
 SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0,
-    "Force NR_FORWARD mode");
+		"Force NR_FORWARD mode");
 SYSCTL_INT(_dev_netmap, OID_AUTO, admode, CTLFLAG_RW, &netmap_admode, 0,
-    "Adapter mode. 0 selects the best option available,"
-    "1 forces native adapter, 2 forces emulated adapter");
+		"Adapter mode. 0 selects the best option available,"
+		"1 forces native adapter, 2 forces emulated adapter");
+SYSCTL_INT(_dev_netmap, OID_AUTO, generic_hwcsum, CTLFLAG_RW, &netmap_generic_hwcsum,
+		0, "Hardware checksums. 0 to disable checksum generation by the NIC (default),"
+		"1 to enable checksum generation by the NIC");
 SYSCTL_INT(_dev_netmap, OID_AUTO, generic_mit, CTLFLAG_RW, &netmap_generic_mit,
-    0, "RX notification interval in nanoseconds");
+		0, "RX notification interval in nanoseconds");
 SYSCTL_INT(_dev_netmap, OID_AUTO, generic_ringsize, CTLFLAG_RW,
-    &netmap_generic_ringsize, 0,
-    "Number of per-ring slots for emulated netmap mode");
+		&netmap_generic_ringsize, 0,
+		"Number of per-ring slots for emulated netmap mode");
 SYSCTL_INT(_dev_netmap, OID_AUTO, generic_rings, CTLFLAG_RW,
-    &netmap_generic_rings, 0,
-    "Number of TX/RX queues for emulated netmap adapters");
+		&netmap_generic_rings, 0,
+		"Number of TX/RX queues for emulated netmap adapters");
 #ifdef linux
 SYSCTL_INT(_dev_netmap, OID_AUTO, generic_txqdisc, CTLFLAG_RW,
-    &netmap_generic_txqdisc, 0, "Use qdisc for generic adapters");
+		&netmap_generic_txqdisc, 0, "Use qdisc for generic adapters");
 #endif
 SYSCTL_INT(_dev_netmap, OID_AUTO, ptnet_vnet_hdr, CTLFLAG_RW, &ptnet_vnet_hdr,
-    0, "Allow ptnet devices to use virtio-net headers");
+		0, "Allow ptnet devices to use virtio-net headers");
 SYSCTL_INT(_dev_netmap, OID_AUTO, ptnetmap_tx_workers, CTLFLAG_RW,
-    &ptnetmap_tx_workers, 0, "Use worker threads for pnetmap TX processing");
+		&ptnetmap_tx_workers, 0, "Use worker threads for pnetmap TX processing");
 
 SYSEND;
 
@@ -765,15 +769,15 @@
 	    na->rx_buf_maxsize == info.rx_buf_maxsize)
 		return 0; /* nothing changed */
 	if (na->active_fds == 0) {
-		D("configuration changed for %s: txring %d x %d, "
-			"rxring %d x %d, rxbufsz %d",
-			na->name, na->num_tx_rings, na->num_tx_desc,
-			na->num_rx_rings, na->num_rx_desc, na->rx_buf_maxsize);
 		na->num_tx_rings = info.num_tx_rings;
 		na->num_tx_desc = info.num_tx_descs;
 		na->num_rx_rings = info.num_rx_rings;
 		na->num_rx_desc = info.num_rx_descs;
 		na->rx_buf_maxsize = info.rx_buf_maxsize;
+		D("configuration changed for %s: txring %d x %d, "
+			"rxring %d x %d, rxbufsz %d",
+			na->name, na->num_tx_rings, na->num_tx_desc,
+			na->num_rx_rings, na->num_rx_desc, na->rx_buf_maxsize);
 		return 0;
 	}
 	D("WARNING: configuration changed for %s while active: "
@@ -827,10 +831,10 @@
 	}
 
 	/* account for the (possibly fake) host rings */
-	n[NR_TX] = na->num_tx_rings + 1;
-	n[NR_RX] = na->num_rx_rings + 1;
+	n[NR_TX] = netmap_all_rings(na, NR_TX);
+	n[NR_RX] = netmap_all_rings(na, NR_RX);
 
-	len = (n[NR_TX] + n[NR_RX]) * 
+	len = (n[NR_TX] + n[NR_RX]) *
 		(sizeof(struct netmap_kring) + sizeof(struct netmap_kring *))
 		+ tailroom;
 
@@ -841,7 +845,7 @@
 	}
 	na->rx_rings = na->tx_rings + n[NR_TX];
 	na->tailroom = na->rx_rings + n[NR_RX];
- 
+
 	/* link the krings in the krings array */
 	kring = (struct netmap_kring *)((char *)na->tailroom + tailroom);
 	for (i = 0; i < n[NR_TX] + n[NR_RX]; i++) {
@@ -930,11 +934,14 @@
 void
 netmap_hw_krings_delete(struct netmap_adapter *na)
 {
-	struct mbq *q = &na->rx_rings[na->num_rx_rings]->rx_queue;
+	u_int lim = netmap_real_rings(na, NR_RX), i;
 
-	ND("destroy sw mbq with len %d", mbq_len(q));
-	mbq_purge(q);
-	mbq_safe_fini(q);
+	for (i = nma_get_nrings(na, NR_RX); i < lim; i++) {
+		struct mbq *q = &NMR(na, NR_RX)[i]->rx_queue;
+		ND("destroy sw mbq with len %d", mbq_len(q));
+		mbq_purge(q);
+		mbq_safe_fini(q);
+	}
 	netmap_krings_delete(na);
 }
 
@@ -1006,9 +1013,9 @@
 		if (netmap_verbose)
 			D("deleting last instance for %s", na->name);
 
-                if (nm_netmap_on(na)) {
-                    D("BUG: netmap on while going to delete the krings");
-                }
+		if (nm_netmap_on(na)) {
+			D("BUG: netmap on while going to delete the krings");
+		}
 
 		na->nm_krings_delete(na);
 	}
@@ -1324,7 +1331,7 @@
 			m_copydata(m, 0, len, NMB(na, slot));
 			ND("nm %d len %d", nm_i, len);
 			if (netmap_verbose)
-                                D("%s", nm_dump_buf(NMB(na, slot),len, 128, NULL));
+				D("%s", nm_dump_buf(NMB(na, slot),len, 128, NULL));
 
 			slot->len = len;
 			slot->flags = 0;
@@ -1476,7 +1483,7 @@
 	      struct netmap_adapter **na, struct ifnet **ifp,
 	      struct netmap_mem_d *nmd, int create)
 {
-	struct nmreq_register *req = (struct nmreq_register *)hdr->nr_body;
+	struct nmreq_register *req = (struct nmreq_register *)(uintptr_t)hdr->nr_body;
 	int error = 0;
 	struct netmap_adapter *ret = NULL;
 	int nmd_ref = 0;
@@ -1535,7 +1542,7 @@
 		goto out;
 
 	/* try to see if this is a bridge port */
-	error = netmap_get_bdg_na(hdr, na, nmd, create);
+	error = netmap_get_vale_na(hdr, na, nmd, create);
 	if (error)
 		goto out;
 
@@ -1827,7 +1834,7 @@
 			}
 			priv->np_qfirst[t] = (nr_mode == NR_REG_SW ?
 				nma_get_nrings(na, t) : 0);
-			priv->np_qlast[t] = nma_get_nrings(na, t) + 1;
+			priv->np_qlast[t] = netmap_all_rings(na, t);
 			ND("%s: %s %d %d", nr_mode == NR_REG_SW ? "SW" : "NIC+SW",
 				nm_txrx2str(t),
 				priv->np_qfirst[t], priv->np_qlast[t]);
@@ -2091,9 +2098,6 @@
 
 	NMG_LOCK_ASSERT();
 	priv->np_na = na;     /* store the reference */
-	error = netmap_set_ringid(priv, nr_mode, nr_ringid, nr_flags);
-	if (error)
-		goto err;
 	error = netmap_mem_finalize(na->nm_mem, na);
 	if (error)
 		goto err;
@@ -2109,7 +2113,14 @@
 
 		/* ring configuration may have changed, fetch from the card */
 		netmap_update_config(na);
+	}
+
+	/* compute the range of tx and rx rings to monitor */
+	error = netmap_set_ringid(priv, nr_mode, nr_ringid, nr_flags);
+	if (error)
+		goto err_put_lut;
 
+	if (na->active_fds == 0) {
 		/*
 		 * If this is the first registration of the adapter,
 		 * perform sanity checks and create the in-kernel view
@@ -2117,11 +2128,17 @@
 		 */
 		if (na->ifp && nm_priv_rx_enabled(priv)) {
 			/* This netmap adapter is attached to an ifnet. */
-			unsigned nbs = netmap_mem_bufsize(na->nm_mem);
+			unsigned nbs = NETMAP_BUF_SIZE(na);
 			unsigned mtu = nm_os_ifnet_mtu(na->ifp);
 
-			ND("mtu %d rx_buf_maxsize %d netmap_buf_size %d",
-					mtu, na->rx_buf_maxsize, nbs);
+			ND("%s: mtu %d rx_buf_maxsize %d netmap_buf_size %d",
+					na->name, mtu, na->rx_buf_maxsize, nbs);
+
+			if (na->rx_buf_maxsize == 0) {
+				D("%s: error: rx_buf_maxsize == 0", na->name);
+				error = EIO;
+				goto err_drop_mem;
+			}
 
 			if (mtu <= na->rx_buf_maxsize) {
 				/* The MTU fits a single NIC slot. We only
@@ -2191,7 +2208,7 @@
 	nifp = netmap_mem_if_new(na, priv);
 	if (nifp == NULL) {
 		error = ENOMEM;
-		goto err_del_rings;
+		goto err_rel_excl;
 	}
 
 	if (nm_kring_pending(priv)) {
@@ -2217,10 +2234,9 @@
 
 err_del_if:
 	netmap_mem_if_delete(na, nifp);
-err_del_rings:
-	netmap_mem_rings_delete(na);
 err_rel_excl:
 	netmap_krings_put(priv);
+	netmap_mem_rings_delete(na);
 err_del_krings:
 	if (na->active_fds == 0)
 		na->nm_krings_delete(na);
@@ -2313,8 +2329,8 @@
 		 * For convenince, the nr_body pointer and the pointers
 		 * in the options list will be replaced with their
 		 * kernel-space counterparts. The original pointers are
-                * saved internally and later restored by nmreq_copyout
-                */
+		 * saved internally and later restored by nmreq_copyout
+		 */
 		error = nmreq_copyin(hdr, nr_body_is_user);
 		if (error) {
 			return error;
@@ -2326,7 +2342,7 @@
 		switch (hdr->nr_reqtype) {
 		case NETMAP_REQ_REGISTER: {
 			struct nmreq_register *req =
-				(struct nmreq_register *)hdr->nr_body;
+				(struct nmreq_register *)(uintptr_t)hdr->nr_body;
 			/* Protect access to priv from concurrent requests. */
 			NMG_LOCK();
 			do {
@@ -2341,7 +2357,7 @@
 				}
 
 #ifdef WITH_EXTMEM
-				opt = nmreq_findoption((struct nmreq_option *)hdr->nr_options,
+				opt = nmreq_findoption((struct nmreq_option *)(uintptr_t)hdr->nr_options,
 						NETMAP_REQ_OPT_EXTMEM);
 				if (opt != NULL) {
 					struct nmreq_opt_extmem *e =
@@ -2444,7 +2460,7 @@
 
 		case NETMAP_REQ_PORT_INFO_GET: {
 			struct nmreq_port_info_get *req =
-				(struct nmreq_port_info_get *)hdr->nr_body;
+				(struct nmreq_port_info_get *)(uintptr_t)hdr->nr_body;
 
 			NMG_LOCK();
 			do {
@@ -2463,10 +2479,10 @@
 
 					/* get a refcount */
 					hdr->nr_reqtype = NETMAP_REQ_REGISTER;
-					hdr->nr_body = (uint64_t)&regreq;
+					hdr->nr_body = (uintptr_t)&regreq;
 					error = netmap_get_na(hdr, &na, &ifp, NULL, 1 /* create */);
 					hdr->nr_reqtype = NETMAP_REQ_PORT_INFO_GET; /* reset type */
-					hdr->nr_body = (uint64_t)req; /* reset nr_body */
+					hdr->nr_body = (uintptr_t)req; /* reset nr_body */
 					if (error) {
 						na = NULL;
 						ifp = NULL;
@@ -2517,7 +2533,7 @@
 
 		case NETMAP_REQ_PORT_HDR_SET: {
 			struct nmreq_port_hdr *req =
-				(struct nmreq_port_hdr *)hdr->nr_body;
+				(struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body;
 			/* Build a nmreq_register out of the nmreq_port_hdr,
 			 * so that we can call netmap_get_bdg_na(). */
 			struct nmreq_register regreq;
@@ -2533,10 +2549,10 @@
 			}
 			NMG_LOCK();
 			hdr->nr_reqtype = NETMAP_REQ_REGISTER;
-			hdr->nr_body = (uint64_t)&regreq;
-			error = netmap_get_bdg_na(hdr, &na, NULL, 0);
+			hdr->nr_body = (uintptr_t)&regreq;
+			error = netmap_get_vale_na(hdr, &na, NULL, 0);
 			hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_SET;
-			hdr->nr_body = (uint64_t)req;
+			hdr->nr_body = (uintptr_t)req;
 			if (na && !error) {
 				struct netmap_vp_adapter *vpna =
 					(struct netmap_vp_adapter *)na;
@@ -2556,7 +2572,7 @@
 		case NETMAP_REQ_PORT_HDR_GET: {
 			/* Get vnet-header length for this netmap port */
 			struct nmreq_port_hdr *req =
-				(struct nmreq_port_hdr *)hdr->nr_body;
+				(struct nmreq_port_hdr *)(uintptr_t)hdr->nr_body;
 			/* Build a nmreq_register out of the nmreq_port_hdr,
 			 * so that we can call netmap_get_bdg_na(). */
 			struct nmreq_register regreq;
@@ -2565,10 +2581,10 @@
 			bzero(&regreq, sizeof(regreq));
 			NMG_LOCK();
 			hdr->nr_reqtype = NETMAP_REQ_REGISTER;
-			hdr->nr_body = (uint64_t)&regreq;
+			hdr->nr_body = (uintptr_t)&regreq;
 			error = netmap_get_na(hdr, &na, &ifp, NULL, 0);
 			hdr->nr_reqtype = NETMAP_REQ_PORT_HDR_GET;
-			hdr->nr_body = (uint64_t)req;
+			hdr->nr_body = (uintptr_t)req;
 			if (na && !error) {
 				req->nr_hdr_len = na->virt_hdr_len;
 			}
@@ -2595,7 +2611,7 @@
 #endif  /* WITH_VALE */
 		case NETMAP_REQ_POOLS_INFO_GET: {
 			struct nmreq_pools_info *req =
-				(struct nmreq_pools_info *)hdr->nr_body;
+				(struct nmreq_pools_info *)(uintptr_t)hdr->nr_body;
 			/* Get information from the memory allocator. This
 			 * netmap device must already be bound to a port.
 			 * Note that hdr->nr_name is ignored. */
@@ -2774,8 +2790,8 @@
 		error = EMSGSIZE;
 		goto out_err;
 	}
-	if ((rqsz && hdr->nr_body == (uint64_t)NULL) ||
-		(!rqsz && hdr->nr_body != (uint64_t)NULL)) {
+	if ((rqsz && hdr->nr_body == (uintptr_t)NULL) ||
+		(!rqsz && hdr->nr_body != (uintptr_t)NULL)) {
 		/* Request body expected, but not found; or
 		 * request body found but unexpected. */
 		error = EINVAL;
@@ -2784,8 +2800,8 @@
 
 	bufsz = 2 * sizeof(void *) + rqsz;
 	optsz = 0;
-	for (src = (struct nmreq_option *)hdr->nr_options; src;
-	     src = (struct nmreq_option *)buf.nro_next)
+	for (src = (struct nmreq_option *)(uintptr_t)hdr->nr_options; src;
+	     src = (struct nmreq_option *)(uintptr_t)buf.nro_next)
 	{
 		error = copyin(src, &buf, sizeof(*src));
 		if (error)
@@ -2813,11 +2829,11 @@
 	p = (char *)ptrs;
 
 	/* copy the body */
-	error = copyin((void *)hdr->nr_body, p, rqsz);
+	error = copyin((void *)(uintptr_t)hdr->nr_body, p, rqsz);
 	if (error)
 		goto out_restore;
 	/* overwrite the user pointer with the in-kernel one */
-	hdr->nr_body = (uint64_t)p;
+	hdr->nr_body = (uintptr_t)p;
 	p += rqsz;
 
 	/* copy the options */
@@ -2874,7 +2890,7 @@
 nmreq_copyout(struct nmreq_header *hdr, int rerror)
 {
 	struct nmreq_option *src, *dst;
-	void *ker = (void *)hdr->nr_body, *bufstart;
+	void *ker = (void *)(uintptr_t)hdr->nr_body, *bufstart;
 	uint64_t *ptrs;
 	size_t bodysz;
 	int error;
@@ -2886,13 +2902,13 @@
 	ptrs = (uint64_t *)ker - 2;
 	bufstart = ptrs;
 	hdr->nr_body = *ptrs++;
-	src = (struct nmreq_option *)hdr->nr_options;
+	src = (struct nmreq_option *)(uintptr_t)hdr->nr_options;
 	hdr->nr_options = *ptrs;
 
 	if (!rerror) {
 		/* copy the body */
 		bodysz = nmreq_size_by_type(hdr->nr_reqtype);
-		error = copyout(ker, (void *)hdr->nr_body, bodysz);
+		error = copyout(ker, (void *)(uintptr_t)hdr->nr_body, bodysz);
 		if (error) {
 			rerror = error;
 			goto out;
@@ -2900,7 +2916,7 @@
 	}
 
 	/* copy the options */
-	dst = (struct nmreq_option *)hdr->nr_options;
+	dst = (struct nmreq_option *)(uintptr_t)hdr->nr_options;
 	while (src) {
 		size_t optsz;
 		uint64_t next;
@@ -2916,7 +2932,7 @@
 			rerror = error;
 			goto out;
 		}
-		       
+
 		/* copy the option body only if there was no error */
 		if (!rerror && !src->nro_status) {
 			optsz = nmreq_opt_size_by_type(src->nro_reqtype);
@@ -2928,8 +2944,8 @@
 				}
 			}
 		}
-		src = (struct nmreq_option *)next;
-		dst = (struct nmreq_option *)*ptrs;
+		src = (struct nmreq_option *)(uintptr_t)next;
+		dst = (struct nmreq_option *)(uintptr_t)*ptrs;
 	}
 
 
@@ -2942,7 +2958,7 @@
 struct nmreq_option *
 nmreq_findoption(struct nmreq_option *opt, uint16_t reqtype)
 {
-	for ( ; opt; opt = (struct nmreq_option *)opt->nro_next)
+	for ( ; opt; opt = (struct nmreq_option *)(uintptr_t)opt->nro_next)
 		if (opt->nro_reqtype == reqtype)
 			return opt;
 	return NULL;
@@ -2953,7 +2969,7 @@
 	uint16_t type = opt->nro_reqtype;
 	int dup = 0;
 
-	while ((opt = nmreq_findoption((struct nmreq_option *)opt->nro_next,
+	while ((opt = nmreq_findoption((struct nmreq_option *)(uintptr_t)opt->nro_next,
 			type))) {
 		dup++;
 		opt->nro_status = EINVAL;
@@ -2969,8 +2985,8 @@
 	 * marked as not supported
 	 */
 
-	for (opt = (struct nmreq_option *)hdr->nr_options; opt;
-	     opt = (struct nmreq_option *)opt->nro_next)
+	for (opt = (struct nmreq_option *)(uintptr_t)hdr->nr_options; opt;
+	     opt = (struct nmreq_option *)(uintptr_t)opt->nro_next)
 		if (opt->nro_status == EOPNOTSUPP)
 			return EOPNOTSUPP;
 
@@ -3327,6 +3343,12 @@
 	}
 	na->pdev = na; /* make sure netmap_mem_map() is called */
 #endif /* __FreeBSD__ */
+	if (na->na_flags & NAF_HOST_RINGS) {
+		if (na->num_host_rx_rings == 0)
+			na->num_host_rx_rings = 1;
+		if (na->num_host_tx_rings == 0)
+			na->num_host_tx_rings = 1;
+	}
 	if (na->nm_krings_create == NULL) {
 		/* we assume that we have been called by a driver,
 		 * since other port types all provide their own
@@ -3348,7 +3370,7 @@
 		/* no special nm_bdg_attach callback. On VALE
 		 * attach, we need to interpose a bwrap
 		 */
-		na->nm_bdg_attach = netmap_bwrap_attach;
+		na->nm_bdg_attach = netmap_default_bdg_attach;
 #endif
 
 	return 0;
@@ -3390,10 +3412,10 @@
 static void
 netmap_hw_dtor(struct netmap_adapter *na)
 {
-	if (nm_iszombie(na) || na->ifp == NULL)
+	if (na->ifp == NULL)
 		return;
 
-	WNA(na->ifp) = NULL;
+	NM_DETACH_NA(na->ifp);
 }
 
 
@@ -3417,10 +3439,10 @@
 	}
 
 	if (arg == NULL || arg->ifp == NULL)
-		goto fail;
+		return EINVAL;
 
 	ifp = arg->ifp;
-	if (NA(ifp) && !NM_NA_VALID(ifp)) {
+	if (NM_NA_CLASH(ifp)) {
 		/* If NA(ifp) is not null but there is no valid netmap
 		 * adapter it means that someone else is using the same
 		 * pointer (e.g. ax25_ptr on linux). This happens for
@@ -3447,28 +3469,8 @@
 
 	NM_ATTACH_NA(ifp, &hwna->up);
 
-#ifdef linux
-	if (ifp->netdev_ops) {
-		/* prepare a clone of the netdev ops */
-#ifndef NETMAP_LINUX_HAVE_NETDEV_OPS
-		hwna->nm_ndo.ndo_start_xmit = ifp->netdev_ops;
-#else
-		hwna->nm_ndo = *ifp->netdev_ops;
-#endif /* NETMAP_LINUX_HAVE_NETDEV_OPS */
-	}
-	hwna->nm_ndo.ndo_start_xmit = linux_netmap_start_xmit;
-	hwna->nm_ndo.ndo_change_mtu = linux_netmap_change_mtu;
-	if (ifp->ethtool_ops) {
-		hwna->nm_eto = *ifp->ethtool_ops;
-	}
-	hwna->nm_eto.set_ringparam = linux_netmap_set_ringparam;
-#ifdef NETMAP_LINUX_HAVE_SET_CHANNELS
-	hwna->nm_eto.set_channels = linux_netmap_set_channels;
-#endif /* NETMAP_LINUX_HAVE_SET_CHANNELS */
-	if (arg->nm_config == NULL) {
-		hwna->up.nm_config = netmap_linux_config;
-	}
-#endif /* linux */
+	nm_os_onattach(ifp);
+
 	if (arg->nm_dtor == NULL) {
 		hwna->up.nm_dtor = netmap_hw_dtor;
 	}
@@ -3536,7 +3538,10 @@
 	int ret = netmap_krings_create(na, 0);
 	if (ret == 0) {
 		/* initialize the mbq for the sw rx ring */
-		mbq_safe_init(&na->rx_rings[na->num_rx_rings]->rx_queue);
+		u_int lim = netmap_real_rings(na, NR_RX), i;
+		for (i = na->num_rx_rings; i < lim; i++) {
+			mbq_safe_init(&NMR(na, NR_RX)[i]->rx_queue);
+		}
 		ND("initialized sw rx queue %d", na->num_rx_rings);
 	}
 	return ret;
@@ -3599,8 +3604,14 @@
 	unsigned int txr;
 	struct mbq *q;
 	int busy;
+	u_int i;
+
+	i = MBUF_TXQ(m);
+	if (i >= na->num_host_rx_rings) {
+		i = i % na->num_host_rx_rings;
+	}
+	kring = NMR(na, NR_RX)[nma_get_nrings(na, NR_RX) + i];
 
-	kring = na->rx_rings[na->num_rx_rings];
 	// XXX [Linux] we do not need this lock
 	// if we follow the down/configure/up protocol -gl
 	// mtx_lock(&na->core_lock);
@@ -3630,8 +3641,15 @@
 		goto done;
 	}
 
-	if (nm_os_mbuf_has_offld(m)) {
-		RD(1, "%s drop mbuf that needs offloadings", na->name);
+	if (!netmap_generic_hwcsum) {
+		if (nm_os_mbuf_has_csum_offld(m)) {
+			RD(1, "%s drop mbuf that needs checksum offload", na->name);
+			goto done;
+		}
+	}
+
+	if (nm_os_mbuf_has_seg_offld(m)) {
+		RD(1, "%s drop mbuf that needs generic segmentation offload", na->name);
 		goto done;
 	}
 
@@ -3643,9 +3661,9 @@
 	 */
 	mbq_lock(q);
 
-        busy = kring->nr_hwtail - kring->nr_hwcur;
-        if (busy < 0)
-                busy += kring->nkr_num_slots;
+	busy = kring->nr_hwtail - kring->nr_hwcur;
+	if (busy < 0)
+		busy += kring->nkr_num_slots;
 	if (busy + mbq_len(q) >= kring->nkr_num_slots - 1) {
 		RD(2, "%s full hwcur %d hwtail %d qlen %d", na->name,
 			kring->nr_hwcur, kring->nr_hwtail, mbq_len(q));
@@ -3836,6 +3854,40 @@
 	return netmap_common_irq(na, q, work_done);
 }
 
+/* set/clear native flags and if_transmit/netdev_ops */
+void
+nm_set_native_flags(struct netmap_adapter *na)
+{
+	struct ifnet *ifp = na->ifp;
+
+	/* We do the setup for intercepting packets only if we are the
+	 * first user of this adapapter. */
+	if (na->active_fds > 0) {
+		return;
+	}
+
+	na->na_flags |= NAF_NETMAP_ON;
+	nm_os_onenter(ifp);
+	nm_update_hostrings_mode(na);
+}
+
+void
+nm_clear_native_flags(struct netmap_adapter *na)
+{
+	struct ifnet *ifp = na->ifp;
+
+	/* We undo the setup for intercepting packets only if we are the
+	 * last user of this adapapter. */
+	if (na->active_fds > 0) {
+		return;
+	}
+
+	nm_update_hostrings_mode(na);
+	nm_os_onexit(ifp);
+
+	na->na_flags &= ~NAF_NETMAP_ON;
+}
+
 
 /*
  * Module loader and unloader

Added: soc2018/sduo/head/sys/dev/netmap/netmap_bdg.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2018/sduo/head/sys/dev/netmap/netmap_bdg.c	Fri Jul  6 14:40:31 2018	(r337267)
@@ -0,0 +1,1811 @@
+/*
+ * Copyright (C) 2013-2016 Universita` di Pisa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+/*
+ * This module implements the VALE switch for netmap
+
+--- VALE SWITCH ---
+
+NMG_LOCK() serializes all modifications to switches and ports.
+A switch cannot be deleted until all ports are gone.
+
+For each switch, an SX lock (RWlock on linux) protects
+deletion of ports. When configuring or deleting a new port, the
+lock is acquired in exclusive mode (after holding NMG_LOCK).
+When forwarding, the lock is acquired in shared mode (without NMG_LOCK).
+The lock is held throughout the entire forwarding cycle,
+during which the thread may incur in a page fault.
+Hence it is important that sleepable shared locks are used.
+
+On the rx ring, the per-port lock is grabbed initially to reserve
+a number of slot in the ring, then the lock is released,
+packets are copied from source to destination, and then
+the lock is acquired again and the receive ring is updated.
+(A similar thing is done on the tx ring for NIC and host stack
+ports attached to the switch)
+
+ */
+
+/*
+ * OS-specific code that is used only within this file.
+ * Other OS-specific code that must be accessed by drivers
+ * is present in netmap_kern.h
+ */
+
+#if defined(__FreeBSD__)
+#include <sys/cdefs.h> /* prerequisite */
+__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 257176 2013-10-26 17:58:36Z glebius $");
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/param.h>	/* defines used in kernel.h */
+#include <sys/kernel.h>	/* types used in module initialization */
+#include <sys/conf.h>	/* cdevsw struct, UID, GID */
+#include <sys/sockio.h>
+#include <sys/socketvar.h>	/* struct socket */
+#include <sys/malloc.h>
+#include <sys/poll.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h> /* sockaddrs */
+#include <sys/selinfo.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/bpf.h>		/* BIOCIMMEDIATE */
+#include <machine/bus.h>	/* bus_dmamap_* */
+#include <sys/endian.h>
+#include <sys/refcount.h>
+#include <sys/smp.h>
+
+
+#elif defined(linux)
+
+#include "bsd_glue.h"
+
+#elif defined(__APPLE__)
+
+#warning OSX support is only partial
+#include "osx_glue.h"
+
+#elif defined(_WIN32)
+#include "win_glue.h"
+
+#else
+
+#error	Unsupported platform
+
+#endif /* unsupported */
+
+/*
+ * common headers
+ */
+
+#include <net/netmap.h>
+#include <dev/netmap/netmap_kern.h>
+#include <dev/netmap/netmap_mem2.h>
+
+#include <dev/netmap/netmap_bdg.h>
+
+const char*
+netmap_bdg_name(struct netmap_vp_adapter *vp)
+{
+	struct nm_bridge *b = vp->na_bdg;
+	if (b == NULL)
+		return NULL;
+	return b->bdg_basename;
+}
+
+
+#ifndef CONFIG_NET_NS
+/*
+ * XXX in principle nm_bridges could be created dynamically
+ * Right now we have a static array and deletions are protected
+ * by an exclusive lock.
+ */
+static struct nm_bridge *nm_bridges;
+#endif /* !CONFIG_NET_NS */
+
+
+static int
+nm_is_id_char(const char c)
+{
+	return (c >= 'a' && c <= 'z') ||
+	       (c >= 'A' && c <= 'Z') ||
+	       (c >= '0' && c <= '9') ||
+	       (c == '_');
+}
+
+/* Validate the name of a VALE bridge port and return the
+ * position of the ":" character. */
+static int
+nm_vale_name_validate(const char *name)
+{
+	int colon_pos = -1;
+	int i;
+
+	if (!name || strlen(name) < strlen(NM_BDG_NAME)) {
+		return -1;
+	}
+
+	for (i = 0; i < NM_BDG_IFNAMSIZ && name[i]; i++) {
+		if (name[i] == ':') {
+			colon_pos = i;
+			break;
+		} else if (!nm_is_id_char(name[i])) {
+			return -1;
+		}
+	}
+
+	if (strlen(name) - colon_pos > IFNAMSIZ) {
+		/* interface name too long */
+		return -1;
+	}
+
+	return colon_pos;
+}
+
+/*
+ * locate a bridge among the existing ones.
+ * MUST BE CALLED WITH NMG_LOCK()
+ *
+ * a ':' in the name terminates the bridge name. Otherwise, just NM_NAME.
+ * We assume that this is called with a name of at least NM_NAME chars.
+ */
+struct nm_bridge *
+nm_find_bridge(const char *name, int create, struct netmap_bdg_ops *ops)
+{
+	int i, namelen;
+	struct nm_bridge *b = NULL, *bridges;
+	u_int num_bridges;
+
+	NMG_LOCK_ASSERT();
+
+	netmap_bns_getbridges(&bridges, &num_bridges);
+
+	namelen = nm_vale_name_validate(name);
+	if (namelen < 0) {
+		D("invalid bridge name %s", name ? name : NULL);
+		return NULL;
+	}
+
+	/* lookup the name, remember empty slot if there is one */
+	for (i = 0; i < num_bridges; i++) {
+		struct nm_bridge *x = bridges + i;
+
+		if ((x->bdg_flags & NM_BDG_ACTIVE) + x->bdg_active_ports == 0) {
+			if (create && b == NULL)
+				b = x;	/* record empty slot */
+		} else if (x->bdg_namelen != namelen) {
+			continue;
+		} else if (strncmp(name, x->bdg_basename, namelen) == 0) {
+			ND("found '%.*s' at %d", namelen, name, i);
+			b = x;
+			break;
+		}
+	}
+	if (i == num_bridges && b) { /* name not found, can create entry */
+		/* initialize the bridge */
+		ND("create new bridge %s with ports %d", b->bdg_basename,
+			b->bdg_active_ports);
+		b->ht = nm_os_malloc(sizeof(struct nm_hash_ent) * NM_BDG_HASH);
+		if (b->ht == NULL) {
+			D("failed to allocate hash table");
+			return NULL;
+		}
+		strncpy(b->bdg_basename, name, namelen);
+		b->bdg_namelen = namelen;
+		b->bdg_active_ports = 0;
+		for (i = 0; i < NM_BDG_MAXPORTS; i++)
+			b->bdg_port_index[i] = i;
+		/* set the default function */
+		b->bdg_ops = ops;
+		b->private_data = b->ht;
+		b->bdg_flags = 0;
+		NM_BNS_GET(b);
+	}
+	return b;
+}
+
+
+int
+netmap_bdg_free(struct nm_bridge *b)
+{
+	if ((b->bdg_flags & NM_BDG_ACTIVE) + b->bdg_active_ports != 0) {
+		return EBUSY;
+	}
+
+	ND("marking bridge %s as free", b->bdg_basename);
+	nm_os_free(b->ht);
+	b->bdg_ops = NULL;
+	b->bdg_flags = 0;
+	NM_BNS_PUT(b);
+	return 0;
+}
+
+
+/* remove from bridge b the ports in slots hw and sw
+ * (sw can be -1 if not needed)
+ */
+void

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807061440.w66EeYWi014114>