Deleted Added
full compact
netmap_vale.c (270063) netmap_vale.c (285349)
1/*
2 * Copyright (C) 2013-2014 Universita` di Pisa. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 43 unchanged lines hidden (view full) ---

52/*
53 * OS-specific code that is used only within this file.
54 * Other OS-specific code that must be accessed by drivers
55 * is present in netmap_kern.h
56 */
57
58#if defined(__FreeBSD__)
59#include <sys/cdefs.h> /* prerequisite */
1/*
2 * Copyright (C) 2013-2014 Universita` di Pisa. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 43 unchanged lines hidden (view full) ---

52/*
53 * OS-specific code that is used only within this file.
54 * Other OS-specific code that must be accessed by drivers
55 * is present in netmap_kern.h
56 */
57
58#if defined(__FreeBSD__)
59#include <sys/cdefs.h> /* prerequisite */
60__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap_vale.c 270063 2014-08-16 15:00:01Z luigi $");
60__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap_vale.c 285349 2015-07-10 05:51:36Z luigi $");
61
62#include <sys/types.h>
63#include <sys/errno.h>
64#include <sys/param.h> /* defines used in kernel.h */
65#include <sys/kernel.h> /* types used in module initialization */
66#include <sys/conf.h> /* cdevsw struct, UID, GID */
67#include <sys/sockio.h>
68#include <sys/socketvar.h> /* struct socket */

--- 148 unchanged lines hidden (view full) ---

217 */
218 struct netmap_bdg_ops bdg_ops;
219
220 /* the forwarding table, MAC+ports.
221 * XXX should be changed to an argument to be passed to
222 * the lookup function, and allocated on attach
223 */
224 struct nm_hash_ent ht[NM_BDG_HASH];
61
62#include <sys/types.h>
63#include <sys/errno.h>
64#include <sys/param.h> /* defines used in kernel.h */
65#include <sys/kernel.h> /* types used in module initialization */
66#include <sys/conf.h> /* cdevsw struct, UID, GID */
67#include <sys/sockio.h>
68#include <sys/socketvar.h> /* struct socket */

--- 148 unchanged lines hidden (view full) ---

217 */
218 struct netmap_bdg_ops bdg_ops;
219
220 /* the forwarding table, MAC+ports.
221 * XXX should be changed to an argument to be passed to
222 * the lookup function, and allocated on attach
223 */
224 struct nm_hash_ent ht[NM_BDG_HASH];
225
226#ifdef CONFIG_NET_NS
227 struct net *ns;
228#endif /* CONFIG_NET_NS */
225};
226
227const char*
228netmap_bdg_name(struct netmap_vp_adapter *vp)
229{
230 struct nm_bridge *b = vp->na_bdg;
231 if (b == NULL)
232 return NULL;
233 return b->bdg_basename;
234}
235
236
229};
230
231const char*
232netmap_bdg_name(struct netmap_vp_adapter *vp)
233{
234 struct nm_bridge *b = vp->na_bdg;
235 if (b == NULL)
236 return NULL;
237 return b->bdg_basename;
238}
239
240
241#ifndef CONFIG_NET_NS
237/*
238 * XXX in principle nm_bridges could be created dynamically
239 * Right now we have a static array and deletions are protected
240 * by an exclusive lock.
241 */
242/*
243 * XXX in principle nm_bridges could be created dynamically
244 * Right now we have a static array and deletions are protected
245 * by an exclusive lock.
246 */
242struct nm_bridge nm_bridges[NM_BRIDGES];
247struct nm_bridge *nm_bridges;
248#endif /* !CONFIG_NET_NS */
243
244
245/*
246 * this is a slightly optimized copy routine which rounds
247 * to multiple of 64 bytes and is often faster than dealing
248 * with other odd sizes. We assume there is enough room
249 * in the source and destination buffers.
250 *

--- 27 unchanged lines hidden (view full) ---

278 *
279 * a ':' in the name terminates the bridge name. Otherwise, just NM_NAME.
280 * We assume that this is called with a name of at least NM_NAME chars.
281 */
282static struct nm_bridge *
283nm_find_bridge(const char *name, int create)
284{
285 int i, l, namelen;
249
250
251/*
252 * this is a slightly optimized copy routine which rounds
253 * to multiple of 64 bytes and is often faster than dealing
254 * with other odd sizes. We assume there is enough room
255 * in the source and destination buffers.
256 *

--- 27 unchanged lines hidden (view full) ---

284 *
285 * a ':' in the name terminates the bridge name. Otherwise, just NM_NAME.
286 * We assume that this is called with a name of at least NM_NAME chars.
287 */
288static struct nm_bridge *
289nm_find_bridge(const char *name, int create)
290{
291 int i, l, namelen;
286 struct nm_bridge *b = NULL;
292 struct nm_bridge *b = NULL, *bridges;
293 u_int num_bridges;
287
288 NMG_LOCK_ASSERT();
289
294
295 NMG_LOCK_ASSERT();
296
297 netmap_bns_getbridges(&bridges, &num_bridges);
298
290 namelen = strlen(NM_NAME); /* base length */
291 l = name ? strlen(name) : 0; /* actual length */
292 if (l < namelen) {
293 D("invalid bridge name %s", name ? name : NULL);
294 return NULL;
295 }
296 for (i = namelen + 1; i < l; i++) {
297 if (name[i] == ':') {
298 namelen = i;
299 break;
300 }
301 }
302 if (namelen >= IFNAMSIZ)
303 namelen = IFNAMSIZ;
304 ND("--- prefix is '%.*s' ---", namelen, name);
305
306 /* lookup the name, remember empty slot if there is one */
299 namelen = strlen(NM_NAME); /* base length */
300 l = name ? strlen(name) : 0; /* actual length */
301 if (l < namelen) {
302 D("invalid bridge name %s", name ? name : NULL);
303 return NULL;
304 }
305 for (i = namelen + 1; i < l; i++) {
306 if (name[i] == ':') {
307 namelen = i;
308 break;
309 }
310 }
311 if (namelen >= IFNAMSIZ)
312 namelen = IFNAMSIZ;
313 ND("--- prefix is '%.*s' ---", namelen, name);
314
315 /* lookup the name, remember empty slot if there is one */
307 for (i = 0; i < NM_BRIDGES; i++) {
308 struct nm_bridge *x = nm_bridges + i;
316 for (i = 0; i < num_bridges; i++) {
317 struct nm_bridge *x = bridges + i;
309
310 if (x->bdg_active_ports == 0) {
311 if (create && b == NULL)
312 b = x; /* record empty slot */
313 } else if (x->bdg_namelen != namelen) {
314 continue;
315 } else if (strncmp(name, x->bdg_basename, namelen) == 0) {
316 ND("found '%.*s' at %d", namelen, name, i);
317 b = x;
318 break;
319 }
320 }
318
319 if (x->bdg_active_ports == 0) {
320 if (create && b == NULL)
321 b = x; /* record empty slot */
322 } else if (x->bdg_namelen != namelen) {
323 continue;
324 } else if (strncmp(name, x->bdg_basename, namelen) == 0) {
325 ND("found '%.*s' at %d", namelen, name, i);
326 b = x;
327 break;
328 }
329 }
321 if (i == NM_BRIDGES && b) { /* name not found, can create entry */
330 if (i == num_bridges && b) { /* name not found, can create entry */
322 /* initialize the bridge */
323 strncpy(b->bdg_basename, name, namelen);
324 ND("create new bridge %s with ports %d", b->bdg_basename,
325 b->bdg_active_ports);
326 b->bdg_namelen = namelen;
327 b->bdg_active_ports = 0;
328 for (i = 0; i < NM_BDG_MAXPORTS; i++)
329 b->bdg_port_index[i] = i;
330 /* set the default function */
331 b->bdg_ops.lookup = netmap_bdg_learning;
332 /* reset the MAC address table */
333 bzero(b->ht, sizeof(struct nm_hash_ent) * NM_BDG_HASH);
331 /* initialize the bridge */
332 strncpy(b->bdg_basename, name, namelen);
333 ND("create new bridge %s with ports %d", b->bdg_basename,
334 b->bdg_active_ports);
335 b->bdg_namelen = namelen;
336 b->bdg_active_ports = 0;
337 for (i = 0; i < NM_BDG_MAXPORTS; i++)
338 b->bdg_port_index[i] = i;
339 /* set the default function */
340 b->bdg_ops.lookup = netmap_bdg_learning;
341 /* reset the MAC address table */
342 bzero(b->ht, sizeof(struct nm_hash_ent) * NM_BDG_HASH);
343 NM_BNS_GET(b);
334 }
335 return b;
336}
337
338
339/*
340 * Free the forwarding tables for rings attached to switch ports.
341 */

--- 26 unchanged lines hidden (view full) ---

368
369 NMG_LOCK_ASSERT();
370 /* all port:rings + broadcast */
371 num_dstq = NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1;
372 l = sizeof(struct nm_bdg_fwd) * NM_BDG_BATCH_MAX;
373 l += sizeof(struct nm_bdg_q) * num_dstq;
374 l += sizeof(uint16_t) * NM_BDG_BATCH_MAX;
375
344 }
345 return b;
346}
347
348
349/*
350 * Free the forwarding tables for rings attached to switch ports.
351 */

--- 26 unchanged lines hidden (view full) ---

378
379 NMG_LOCK_ASSERT();
380 /* all port:rings + broadcast */
381 num_dstq = NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1;
382 l = sizeof(struct nm_bdg_fwd) * NM_BDG_BATCH_MAX;
383 l += sizeof(struct nm_bdg_q) * num_dstq;
384 l += sizeof(uint16_t) * NM_BDG_BATCH_MAX;
385
376 nrings = netmap_real_tx_rings(na);
386 nrings = netmap_real_rings(na, NR_TX);
377 kring = na->tx_rings;
378 for (i = 0; i < nrings; i++) {
379 struct nm_bdg_fwd *ft;
380 struct nm_bdg_q *dstq;
381 int j;
382
383 ft = malloc(l, M_DEVBUF, M_NOWAIT | M_ZERO);
384 if (!ft) {

--- 68 unchanged lines hidden (view full) ---

453 memcpy(b->bdg_port_index, tmp, sizeof(tmp));
454 b->bdg_active_ports = lim;
455 BDG_WUNLOCK(b);
456
457 ND("now %d active ports", lim);
458 if (lim == 0) {
459 ND("marking bridge %s as free", b->bdg_basename);
460 bzero(&b->bdg_ops, sizeof(b->bdg_ops));
387 kring = na->tx_rings;
388 for (i = 0; i < nrings; i++) {
389 struct nm_bdg_fwd *ft;
390 struct nm_bdg_q *dstq;
391 int j;
392
393 ft = malloc(l, M_DEVBUF, M_NOWAIT | M_ZERO);
394 if (!ft) {

--- 68 unchanged lines hidden (view full) ---

463 memcpy(b->bdg_port_index, tmp, sizeof(tmp));
464 b->bdg_active_ports = lim;
465 BDG_WUNLOCK(b);
466
467 ND("now %d active ports", lim);
468 if (lim == 0) {
469 ND("marking bridge %s as free", b->bdg_basename);
470 bzero(&b->bdg_ops, sizeof(b->bdg_ops));
471 NM_BNS_PUT(b);
461 }
462}
463
464/* nm_bdg_ctl callback for VALE ports */
465static int
466netmap_vp_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach)
467{
468 struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter *)na;

--- 158 unchanged lines hidden (view full) ---

627 * that there are no other possible writers.
628 */
629
630 /* lookup in the local list of ports */
631 for (j = 0; j < b->bdg_active_ports; j++) {
632 i = b->bdg_port_index[j];
633 vpna = b->bdg_ports[i];
634 // KASSERT(na != NULL);
472 }
473}
474
475/* nm_bdg_ctl callback for VALE ports */
476static int
477netmap_vp_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach)
478{
479 struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter *)na;

--- 158 unchanged lines hidden (view full) ---

638 * that there are no other possible writers.
639 */
640
641 /* lookup in the local list of ports */
642 for (j = 0; j < b->bdg_active_ports; j++) {
643 i = b->bdg_port_index[j];
644 vpna = b->bdg_ports[i];
645 // KASSERT(na != NULL);
635 D("checking %s", vpna->up.name);
646 ND("checking %s", vpna->up.name);
636 if (!strcmp(vpna->up.name, nr_name)) {
637 netmap_adapter_get(&vpna->up);
638 ND("found existing if %s refs %d", nr_name)
639 *na = &vpna->up;
640 return 0;
641 }
642 }
643 /* not found, should we create it? */

--- 164 unchanged lines hidden (view full) ---

808 * NETMAP_BDG_OPS that sets configure/lookup/dtor functions to the bridge
809 * requires bdg_ops argument; the other commands ignore this argument.
810 *
811 * Called without NMG_LOCK.
812 */
813int
814netmap_bdg_ctl(struct nmreq *nmr, struct netmap_bdg_ops *bdg_ops)
815{
647 if (!strcmp(vpna->up.name, nr_name)) {
648 netmap_adapter_get(&vpna->up);
649 ND("found existing if %s refs %d", nr_name)
650 *na = &vpna->up;
651 return 0;
652 }
653 }
654 /* not found, should we create it? */

--- 164 unchanged lines hidden (view full) ---

819 * NETMAP_BDG_OPS that sets configure/lookup/dtor functions to the bridge
820 * requires bdg_ops argument; the other commands ignore this argument.
821 *
822 * Called without NMG_LOCK.
823 */
824int
825netmap_bdg_ctl(struct nmreq *nmr, struct netmap_bdg_ops *bdg_ops)
826{
816 struct nm_bridge *b;
827 struct nm_bridge *b, *bridges;
817 struct netmap_adapter *na;
818 struct netmap_vp_adapter *vpna;
819 char *name = nmr->nr_name;
820 int cmd = nmr->nr_cmd, namelen = strlen(name);
821 int error = 0, i, j;
828 struct netmap_adapter *na;
829 struct netmap_vp_adapter *vpna;
830 char *name = nmr->nr_name;
831 int cmd = nmr->nr_cmd, namelen = strlen(name);
832 int error = 0, i, j;
833 u_int num_bridges;
822
834
835 netmap_bns_getbridges(&bridges, &num_bridges);
836
823 switch (cmd) {
824 case NETMAP_BDG_NEWIF:
825 error = nm_vi_create(nmr);
826 break;
827
828 case NETMAP_BDG_DELIF:
829 error = nm_vi_destroy(nmr->nr_name);
830 break;

--- 16 unchanged lines hidden (view full) ---

847 NMG_LOCK();
848 b = nm_find_bridge(name, 0 /* don't create */);
849 if (!b) {
850 error = ENOENT;
851 NMG_UNLOCK();
852 break;
853 }
854
837 switch (cmd) {
838 case NETMAP_BDG_NEWIF:
839 error = nm_vi_create(nmr);
840 break;
841
842 case NETMAP_BDG_DELIF:
843 error = nm_vi_destroy(nmr->nr_name);
844 break;

--- 16 unchanged lines hidden (view full) ---

861 NMG_LOCK();
862 b = nm_find_bridge(name, 0 /* don't create */);
863 if (!b) {
864 error = ENOENT;
865 NMG_UNLOCK();
866 break;
867 }
868
855 name = name + b->bdg_namelen + 1;
856 error = ENOENT;
857 for (j = 0; j < b->bdg_active_ports; j++) {
858 i = b->bdg_port_index[j];
859 vpna = b->bdg_ports[i];
860 if (vpna == NULL) {
861 D("---AAAAAAAAARGH-------");
862 continue;
863 }
864 /* the former and the latter identify a
865 * virtual port and a NIC, respectively
866 */
867 if (!strcmp(vpna->up.name, name)) {
868 /* bridge index */
869 error = ENOENT;
870 for (j = 0; j < b->bdg_active_ports; j++) {
871 i = b->bdg_port_index[j];
872 vpna = b->bdg_ports[i];
873 if (vpna == NULL) {
874 D("---AAAAAAAAARGH-------");
875 continue;
876 }
877 /* the former and the latter identify a
878 * virtual port and a NIC, respectively
879 */
880 if (!strcmp(vpna->up.name, name)) {
881 /* bridge index */
869 nmr->nr_arg1 = b - nm_bridges;
882 nmr->nr_arg1 = b - bridges;
870 nmr->nr_arg2 = i; /* port index */
871 error = 0;
872 break;
873 }
874 }
875 NMG_UNLOCK();
876 } else {
877 /* return the first non-empty entry starting from
878 * bridge nr_arg1 and port nr_arg2.
879 *
880 * Users can detect the end of the same bridge by
881 * seeing the new and old value of nr_arg1, and can
882 * detect the end of all the bridge by error != 0
883 */
884 i = nmr->nr_arg1;
885 j = nmr->nr_arg2;
886
887 NMG_LOCK();
888 for (error = ENOENT; i < NM_BRIDGES; i++) {
883 nmr->nr_arg2 = i; /* port index */
884 error = 0;
885 break;
886 }
887 }
888 NMG_UNLOCK();
889 } else {
890 /* return the first non-empty entry starting from
891 * bridge nr_arg1 and port nr_arg2.
892 *
893 * Users can detect the end of the same bridge by
894 * seeing the new and old value of nr_arg1, and can
895 * detect the end of all the bridge by error != 0
896 */
897 i = nmr->nr_arg1;
898 j = nmr->nr_arg2;
899
900 NMG_LOCK();
901 for (error = ENOENT; i < NM_BRIDGES; i++) {
889 b = nm_bridges + i;
902 b = bridges + i;
890 if (j >= b->bdg_active_ports) {
891 j = 0; /* following bridges scan from 0 */
892 continue;
893 }
894 nmr->nr_arg1 = i;
895 nmr->nr_arg2 = j;
896 j = b->bdg_port_index[j];
897 vpna = b->bdg_ports[j];

--- 81 unchanged lines hidden (view full) ---

979 * rings and bdgfwd on tx rings.
980 */
981static int
982netmap_vp_krings_create(struct netmap_adapter *na)
983{
984 u_int tailroom;
985 int error, i;
986 uint32_t *leases;
903 if (j >= b->bdg_active_ports) {
904 j = 0; /* following bridges scan from 0 */
905 continue;
906 }
907 nmr->nr_arg1 = i;
908 nmr->nr_arg2 = j;
909 j = b->bdg_port_index[j];
910 vpna = b->bdg_ports[j];

--- 81 unchanged lines hidden (view full) ---

992 * rings and bdgfwd on tx rings.
993 */
994static int
995netmap_vp_krings_create(struct netmap_adapter *na)
996{
997 u_int tailroom;
998 int error, i;
999 uint32_t *leases;
987 u_int nrx = netmap_real_rx_rings(na);
1000 u_int nrx = netmap_real_rings(na, NR_RX);
988
989 /*
990 * Leases are attached to RX rings on vale ports
991 */
992 tailroom = sizeof(uint32_t) * na->num_rx_desc * nrx;
993
994 error = netmap_krings_create(na, tailroom);
995 if (error)

--- 65 unchanged lines hidden (view full) ---

1061 for (; likely(j != end); j = nm_next(j, lim)) {
1062 struct netmap_slot *slot = &ring->slot[j];
1063 char *buf;
1064
1065 ft[ft_i].ft_len = slot->len;
1066 ft[ft_i].ft_flags = slot->flags;
1067
1068 ND("flags is 0x%x", slot->flags);
1001
1002 /*
1003 * Leases are attached to RX rings on vale ports
1004 */
1005 tailroom = sizeof(uint32_t) * na->num_rx_desc * nrx;
1006
1007 error = netmap_krings_create(na, tailroom);
1008 if (error)

--- 65 unchanged lines hidden (view full) ---

1074 for (; likely(j != end); j = nm_next(j, lim)) {
1075 struct netmap_slot *slot = &ring->slot[j];
1076 char *buf;
1077
1078 ft[ft_i].ft_len = slot->len;
1079 ft[ft_i].ft_flags = slot->flags;
1080
1081 ND("flags is 0x%x", slot->flags);
1082 /* we do not use the buf changed flag, but we still need to reset it */
1083 slot->flags &= ~NS_BUF_CHANGED;
1084
1069 /* this slot goes into a list so initialize the link field */
1070 ft[ft_i].ft_next = NM_FT_NULL;
1071 buf = ft[ft_i].ft_buf = (slot->flags & NS_INDIRECT) ?
1072 (void *)(uintptr_t)slot->ptr : NMB(&na->up, slot);
1073 if (unlikely(buf == NULL)) {
1074 RD(5, "NULL %s buffer pointer from %s slot %d len %d",
1075 (slot->flags & NS_INDIRECT) ? "INDIRECT" : "DIRECT",
1076 kring->name, j, ft[ft_i].ft_len);

--- 98 unchanged lines hidden (view full) ---

1175/*
1176 * Lookup function for a learning bridge.
1177 * Update the hash table with the source address,
1178 * and then returns the destination port index, and the
1179 * ring in *dst_ring (at the moment, always use ring 0)
1180 */
1181u_int
1182netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
1085 /* this slot goes into a list so initialize the link field */
1086 ft[ft_i].ft_next = NM_FT_NULL;
1087 buf = ft[ft_i].ft_buf = (slot->flags & NS_INDIRECT) ?
1088 (void *)(uintptr_t)slot->ptr : NMB(&na->up, slot);
1089 if (unlikely(buf == NULL)) {
1090 RD(5, "NULL %s buffer pointer from %s slot %d len %d",
1091 (slot->flags & NS_INDIRECT) ? "INDIRECT" : "DIRECT",
1092 kring->name, j, ft[ft_i].ft_len);

--- 98 unchanged lines hidden (view full) ---

1191/*
1192 * Lookup function for a learning bridge.
1193 * Update the hash table with the source address,
1194 * and then returns the destination port index, and the
1195 * ring in *dst_ring (at the moment, always use ring 0)
1196 */
1197u_int
1198netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
1183 const struct netmap_vp_adapter *na)
1199 struct netmap_vp_adapter *na)
1184{
1185 uint8_t *buf = ft->ft_buf;
1186 u_int buf_len = ft->ft_len;
1187 struct nm_hash_ent *ht = na->na_bdg->ht;
1188 uint32_t sh, dh;
1189 u_int dst, mysrc = na->bdg_port;
1190 uint64_t smac, dmac;
1191

--- 14 unchanged lines hidden (view full) ---

1206 dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff;
1207 smac = le64toh(*(uint64_t *)(buf + 4));
1208 smac >>= 16;
1209
1210 /*
1211 * The hash is somewhat expensive, there might be some
1212 * worthwhile optimizations here.
1213 */
1200{
1201 uint8_t *buf = ft->ft_buf;
1202 u_int buf_len = ft->ft_len;
1203 struct nm_hash_ent *ht = na->na_bdg->ht;
1204 uint32_t sh, dh;
1205 u_int dst, mysrc = na->bdg_port;
1206 uint64_t smac, dmac;
1207

--- 14 unchanged lines hidden (view full) ---

1222 dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff;
1223 smac = le64toh(*(uint64_t *)(buf + 4));
1224 smac >>= 16;
1225
1226 /*
1227 * The hash is somewhat expensive, there might be some
1228 * worthwhile optimizations here.
1229 */
1214 if ((buf[6] & 1) == 0) { /* valid src */
1230 if (((buf[6] & 1) == 0) && (na->last_smac != smac)) { /* valid src */
1215 uint8_t *s = buf+6;
1216 sh = nm_bridge_rthash(s); // XXX hash of source
1217 /* update source port forwarding entry */
1231 uint8_t *s = buf+6;
1232 sh = nm_bridge_rthash(s); // XXX hash of source
1233 /* update source port forwarding entry */
1218 ht[sh].mac = smac; /* XXX expire ? */
1234 na->last_smac = ht[sh].mac = smac; /* XXX expire ? */
1219 ht[sh].ports = mysrc;
1220 if (netmap_verbose)
1221 D("src %02x:%02x:%02x:%02x:%02x:%02x on port %d",
1222 s[0], s[1], s[2], s[3], s[4], s[5], mysrc);
1223 }
1224 dst = NM_BDG_BROADCAST;
1225 if ((buf[0] & 1) == 0) { /* unicast */
1226 dh = nm_bridge_rthash(buf); // XXX hash of dst
1227 if (ht[dh].mac == dmac) { /* found dst */
1228 dst = ht[dh].ports;
1229 }
1230 /* XXX otherwise return NM_BDG_UNKNOWN ? */
1231 }
1235 ht[sh].ports = mysrc;
1236 if (netmap_verbose)
1237 D("src %02x:%02x:%02x:%02x:%02x:%02x on port %d",
1238 s[0], s[1], s[2], s[3], s[4], s[5], mysrc);
1239 }
1240 dst = NM_BDG_BROADCAST;
1241 if ((buf[0] & 1) == 0) { /* unicast */
1242 dh = nm_bridge_rthash(buf); // XXX hash of dst
1243 if (ht[dh].mac == dmac) { /* found dst */
1244 dst = ht[dh].ports;
1245 }
1246 /* XXX otherwise return NM_BDG_UNKNOWN ? */
1247 }
1232 *dst_ring = 0;
1233 return dst;
1234}
1235
1236
1237/*
1238 * Available space in the ring. Only used in VALE code
1239 * and only with is_rx = 1
1240 */

--- 229 unchanged lines hidden (view full) ---

1470 kring = &dst_na->up.rx_rings[dst_nr];
1471 ring = kring->ring;
1472 lim = kring->nkr_num_slots - 1;
1473
1474retry:
1475
1476 if (dst_na->retry && retry) {
1477 /* try to get some free slot from the previous run */
1248 return dst;
1249}
1250
1251
1252/*
1253 * Available space in the ring. Only used in VALE code
1254 * and only with is_rx = 1
1255 */

--- 229 unchanged lines hidden (view full) ---

1485 kring = &dst_na->up.rx_rings[dst_nr];
1486 ring = kring->ring;
1487 lim = kring->nkr_num_slots - 1;
1488
1489retry:
1490
1491 if (dst_na->retry && retry) {
1492 /* try to get some free slot from the previous run */
1478 dst_na->up.nm_notify(&dst_na->up, dst_nr, NR_RX, 0);
1493 kring->nm_notify(kring, 0);
1479 /* actually useful only for bwraps, since there
1480 * the notify will trigger a txsync on the hwna. VALE ports
1481 * have dst_na->retry == 0
1482 */
1483 }
1484 /* reserve the buffers in the queue and an entry
1485 * to report completion, and drop lock.
1486 * XXX this might become a helper function.

--- 124 unchanged lines hidden (view full) ---

1611 }
1612 /* j is the new 'write' position. j != my_start
1613 * means there are new buffers to report
1614 */
1615 if (likely(j != my_start)) {
1616 kring->nr_hwtail = j;
1617 still_locked = 0;
1618 mtx_unlock(&kring->q_lock);
1494 /* actually useful only for bwraps, since there
1495 * the notify will trigger a txsync on the hwna. VALE ports
1496 * have dst_na->retry == 0
1497 */
1498 }
1499 /* reserve the buffers in the queue and an entry
1500 * to report completion, and drop lock.
1501 * XXX this might become a helper function.

--- 124 unchanged lines hidden (view full) ---

1626 }
1627 /* j is the new 'write' position. j != my_start
1628 * means there are new buffers to report
1629 */
1630 if (likely(j != my_start)) {
1631 kring->nr_hwtail = j;
1632 still_locked = 0;
1633 mtx_unlock(&kring->q_lock);
1619 dst_na->up.nm_notify(&dst_na->up, dst_nr, NR_RX, 0);
1634 kring->nm_notify(kring, 0);
1620 /* this is netmap_notify for VALE ports and
1621 * netmap_bwrap_notify for bwrap. The latter will
1622 * trigger a txsync on the underlying hwna
1623 */
1624 if (dst_na->retry && retry--) {
1625 /* XXX this is going to call nm_notify again.
1626 * Only useful for bwrap in virtual machines
1627 */

--- 16 unchanged lines hidden (view full) ---

1644/* nm_txsync callback for VALE ports */
1645static int
1646netmap_vp_txsync(struct netmap_kring *kring, int flags)
1647{
1648 struct netmap_vp_adapter *na =
1649 (struct netmap_vp_adapter *)kring->na;
1650 u_int done;
1651 u_int const lim = kring->nkr_num_slots - 1;
1635 /* this is netmap_notify for VALE ports and
1636 * netmap_bwrap_notify for bwrap. The latter will
1637 * trigger a txsync on the underlying hwna
1638 */
1639 if (dst_na->retry && retry--) {
1640 /* XXX this is going to call nm_notify again.
1641 * Only useful for bwrap in virtual machines
1642 */

--- 16 unchanged lines hidden (view full) ---

1659/* nm_txsync callback for VALE ports */
1660static int
1661netmap_vp_txsync(struct netmap_kring *kring, int flags)
1662{
1663 struct netmap_vp_adapter *na =
1664 (struct netmap_vp_adapter *)kring->na;
1665 u_int done;
1666 u_int const lim = kring->nkr_num_slots - 1;
1652 u_int const cur = kring->rcur;
1667 u_int const head = kring->rhead;
1653
1654 if (bridge_batch <= 0) { /* testing only */
1668
1669 if (bridge_batch <= 0) { /* testing only */
1655 done = cur; // used all
1670 done = head; // used all
1656 goto done;
1657 }
1658 if (!na->na_bdg) {
1671 goto done;
1672 }
1673 if (!na->na_bdg) {
1659 done = cur;
1674 done = head;
1660 goto done;
1661 }
1662 if (bridge_batch > NM_BDG_BATCH)
1663 bridge_batch = NM_BDG_BATCH;
1664
1675 goto done;
1676 }
1677 if (bridge_batch > NM_BDG_BATCH)
1678 bridge_batch = NM_BDG_BATCH;
1679
1665 done = nm_bdg_preflush(kring, cur);
1680 done = nm_bdg_preflush(kring, head);
1666done:
1681done:
1667 if (done != cur)
1668 D("early break at %d/ %d, tail %d", done, cur, kring->nr_hwtail);
1682 if (done != head)
1683 D("early break at %d/ %d, tail %d", done, head, kring->nr_hwtail);
1669 /*
1670 * packets between 'done' and 'cur' are left unsent.
1671 */
1672 kring->nr_hwcur = done;
1673 kring->nr_hwtail = nm_prev(done, lim);
1684 /*
1685 * packets between 'done' and 'cur' are left unsent.
1686 */
1687 kring->nr_hwcur = done;
1688 kring->nr_hwtail = nm_prev(done, lim);
1674 nm_txsync_finalize(kring);
1675 if (netmap_verbose)
1676 D("%s ring %d flags %d", na->up.name, kring->ring_id, flags);
1677 return 0;
1678}
1679
1680
1681/* rxsync code used by VALE ports nm_rxsync callback and also
1682 * internally by the brwap
1683 */
1684static int
1685netmap_vp_rxsync_locked(struct netmap_kring *kring, int flags)
1686{
1687 struct netmap_adapter *na = kring->na;
1688 struct netmap_ring *ring = kring->ring;
1689 u_int nm_i, lim = kring->nkr_num_slots - 1;
1689 if (netmap_verbose)
1690 D("%s ring %d flags %d", na->up.name, kring->ring_id, flags);
1691 return 0;
1692}
1693
1694
1695/* rxsync code used by VALE ports nm_rxsync callback and also
1696 * internally by the brwap
1697 */
1698static int
1699netmap_vp_rxsync_locked(struct netmap_kring *kring, int flags)
1700{
1701 struct netmap_adapter *na = kring->na;
1702 struct netmap_ring *ring = kring->ring;
1703 u_int nm_i, lim = kring->nkr_num_slots - 1;
1690 u_int head = nm_rxsync_prologue(kring);
1704 u_int head = kring->rhead;
1691 int n;
1692
1693 if (head > lim) {
1694 D("ouch dangerous reset!!!");
1695 n = netmap_ring_reinit(kring);
1696 goto done;
1697 }
1698

--- 13 unchanged lines hidden (view full) ---

1712 slot->buf_idx);
1713 }
1714 slot->flags &= ~NS_BUF_CHANGED;
1715 nm_i = nm_next(nm_i, lim);
1716 }
1717 kring->nr_hwcur = head;
1718 }
1719
1705 int n;
1706
1707 if (head > lim) {
1708 D("ouch dangerous reset!!!");
1709 n = netmap_ring_reinit(kring);
1710 goto done;
1711 }
1712

--- 13 unchanged lines hidden (view full) ---

1726 slot->buf_idx);
1727 }
1728 slot->flags &= ~NS_BUF_CHANGED;
1729 nm_i = nm_next(nm_i, lim);
1730 }
1731 kring->nr_hwcur = head;
1732 }
1733
1720 /* tell userspace that there are new packets */
1721 nm_rxsync_finalize(kring);
1722 n = 0;
1723done:
1724 return n;
1725}
1726
1727/*
1728 * nm_rxsync callback for VALE ports
1729 * user process reading from a VALE switch.

--- 69 unchanged lines hidden (view full) ---

1799 nm_bound_var(&npipes, 2, 1, NM_MAXPIPES, NULL);
1800 nmr->nr_arg1 = npipes; /* write back */
1801 /* validate extra bufs */
1802 nm_bound_var(&nmr->nr_arg3, 0, 0,
1803 128*NM_BDG_MAXSLOTS, NULL);
1804 na->num_rx_desc = nmr->nr_rx_slots;
1805 vpna->virt_hdr_len = 0;
1806 vpna->mfs = 1514;
1734 n = 0;
1735done:
1736 return n;
1737}
1738
1739/*
1740 * nm_rxsync callback for VALE ports
1741 * user process reading from a VALE switch.

--- 69 unchanged lines hidden (view full) ---

1811 nm_bound_var(&npipes, 2, 1, NM_MAXPIPES, NULL);
1812 nmr->nr_arg1 = npipes; /* write back */
1813 /* validate extra bufs */
1814 nm_bound_var(&nmr->nr_arg3, 0, 0,
1815 128*NM_BDG_MAXSLOTS, NULL);
1816 na->num_rx_desc = nmr->nr_rx_slots;
1817 vpna->virt_hdr_len = 0;
1818 vpna->mfs = 1514;
1819 vpna->last_smac = ~0llu;
1807 /*if (vpna->mfs > netmap_buf_size) TODO netmap_buf_size is zero??
1808 vpna->mfs = netmap_buf_size; */
1809 if (netmap_verbose)
1810 D("max frame size %u", vpna->mfs);
1811
1820 /*if (vpna->mfs > netmap_buf_size) TODO netmap_buf_size is zero??
1821 vpna->mfs = netmap_buf_size; */
1822 if (netmap_verbose)
1823 D("max frame size %u", vpna->mfs);
1824
1812 na->na_flags |= NAF_BDG_MAYSLEEP | NAF_MEM_OWNER;
1825 na->na_flags |= NAF_BDG_MAYSLEEP;
1813 na->nm_txsync = netmap_vp_txsync;
1814 na->nm_rxsync = netmap_vp_rxsync;
1815 na->nm_register = netmap_vp_reg;
1816 na->nm_krings_create = netmap_vp_krings_create;
1817 na->nm_krings_delete = netmap_vp_krings_delete;
1818 na->nm_dtor = netmap_vp_dtor;
1819 na->nm_mem = netmap_mem_private_new(na->name,
1820 na->num_tx_rings, na->num_tx_desc,

--- 6 unchanged lines hidden (view full) ---

1827 error = netmap_attach_common(na);
1828 if (error)
1829 goto err;
1830 *ret = vpna;
1831 return 0;
1832
1833err:
1834 if (na->nm_mem != NULL)
1826 na->nm_txsync = netmap_vp_txsync;
1827 na->nm_rxsync = netmap_vp_rxsync;
1828 na->nm_register = netmap_vp_reg;
1829 na->nm_krings_create = netmap_vp_krings_create;
1830 na->nm_krings_delete = netmap_vp_krings_delete;
1831 na->nm_dtor = netmap_vp_dtor;
1832 na->nm_mem = netmap_mem_private_new(na->name,
1833 na->num_tx_rings, na->num_tx_desc,

--- 6 unchanged lines hidden (view full) ---

1840 error = netmap_attach_common(na);
1841 if (error)
1842 goto err;
1843 *ret = vpna;
1844 return 0;
1845
1846err:
1847 if (na->nm_mem != NULL)
1835 netmap_mem_private_delete(na->nm_mem);
1848 netmap_mem_delete(na->nm_mem);
1836 free(vpna, M_DEVBUF);
1837 return error;
1838}
1839
1840/* Bridge wrapper code (bwrap).
1841 * This is used to connect a non-VALE-port netmap_adapter (hwna) to a
1842 * VALE switch.
1843 * The main task is to swap the meaning of tx and rx rings to match the

--- 64 unchanged lines hidden (view full) ---

1908 * and head/cur/tail are set from the kring as needed
1909 * (part as a receive ring, part as a transmit ring).
1910 *
1911 * callback that overwrites the hwna notify callback.
1912 * Packets come from the outside or from the host stack and are put on an hwna rx ring.
1913 * The bridge wrapper then sends the packets through the bridge.
1914 */
1915static int
1849 free(vpna, M_DEVBUF);
1850 return error;
1851}
1852
1853/* Bridge wrapper code (bwrap).
1854 * This is used to connect a non-VALE-port netmap_adapter (hwna) to a
1855 * VALE switch.
1856 * The main task is to swap the meaning of tx and rx rings to match the

--- 64 unchanged lines hidden (view full) ---

1921 * and head/cur/tail are set from the kring as needed
1922 * (part as a receive ring, part as a transmit ring).
1923 *
1924 * callback that overwrites the hwna notify callback.
1925 * Packets come from the outside or from the host stack and are put on an hwna rx ring.
1926 * The bridge wrapper then sends the packets through the bridge.
1927 */
1928static int
1916netmap_bwrap_intr_notify(struct netmap_adapter *na, u_int ring_nr, enum txrx tx, int flags)
1929netmap_bwrap_intr_notify(struct netmap_kring *kring, int flags)
1917{
1930{
1931 struct netmap_adapter *na = kring->na;
1918 struct netmap_bwrap_adapter *bna = na->na_private;
1932 struct netmap_bwrap_adapter *bna = na->na_private;
1919 struct netmap_vp_adapter *hostna = &bna->host;
1920 struct netmap_kring *kring, *bkring;
1933 struct netmap_kring *bkring;
1921 struct netmap_ring *ring;
1934 struct netmap_ring *ring;
1922 int is_host_ring = ring_nr == na->num_rx_rings;
1923 struct netmap_vp_adapter *vpna = &bna->up;
1935 struct netmap_vp_adapter *vpna = &bna->up;
1936 u_int ring_nr = kring->ring_id;
1924 int error = 0;
1925
1926 if (netmap_verbose)
1937 int error = 0;
1938
1939 if (netmap_verbose)
1927 D("%s %s%d 0x%x", na->name,
1928 (tx == NR_TX ? "TX" : "RX"), ring_nr, flags);
1940 D("%s %s 0x%x", na->name, kring->name, flags);
1929
1941
1930 if (flags & NAF_DISABLE_NOTIFY) {
1931 /* the enabled/disabled state of the ring has changed,
1932 * propagate the info to the wrapper (with tx/rx swapped)
1933 */
1934 if (tx == NR_TX) {
1935 netmap_set_rxring(&vpna->up, ring_nr,
1936 na->tx_rings[ring_nr].nkr_stopped);
1937 } else {
1938 netmap_set_txring(&vpna->up, ring_nr,
1939 na->rx_rings[ring_nr].nkr_stopped);
1940 }
1941 return 0;
1942 }
1943
1944 if (!nm_netmap_on(na))
1945 return 0;
1946
1942 if (!nm_netmap_on(na))
1943 return 0;
1944
1947 /* we only care about receive interrupts */
1948 if (tx == NR_TX)
1949 return 0;
1945 bkring = &vpna->up.tx_rings[ring_nr];
1946 ring = kring->ring; /* == kbkring->ring */
1950
1947
1951 kring = &na->rx_rings[ring_nr];
1952 ring = kring->ring;
1953
1954 /* make sure the ring is not disabled */
1955 if (nm_kr_tryget(kring))
1956 return 0;
1957
1948 /* make sure the ring is not disabled */
1949 if (nm_kr_tryget(kring))
1950 return 0;
1951
1958 if (is_host_ring && hostna->na_bdg == NULL) {
1959 error = bna->save_notify(na, ring_nr, tx, flags);
1960 goto put_out;
1961 }
1962
1963 /* Here we expect ring->head = ring->cur = ring->tail
1964 * because everything has been released from the previous round.
1965 * However the ring is shared and we might have info from
1966 * the wrong side (the tx ring). Hence we overwrite with
1967 * the info from the rx kring.
1968 */
1969 if (netmap_verbose)
1952 if (netmap_verbose)
1970 D("%s head %d cur %d tail %d (kring %d %d %d)", na->name,
1971 ring->head, ring->cur, ring->tail,
1953 D("%s head %d cur %d tail %d", na->name,
1972 kring->rhead, kring->rcur, kring->rtail);
1973
1954 kring->rhead, kring->rcur, kring->rtail);
1955
1974 ring->head = kring->rhead;
1975 ring->cur = kring->rcur;
1976 ring->tail = kring->rtail;
1977
1978 if (is_host_ring) {
1979 vpna = hostna;
1980 ring_nr = 0;
1981 }
1982 /* simulate a user wakeup on the rx ring */
1983 /* fetch packets that have arrived.
1984 * XXX maybe do this in a loop ?
1956 /* simulate a user wakeup on the rx ring
1957 * fetch packets that have arrived.
1985 */
1986 error = kring->nm_sync(kring, 0);
1987 if (error)
1988 goto put_out;
1989 if (kring->nr_hwcur == kring->nr_hwtail && netmap_verbose) {
1990 D("how strange, interrupt with no packets on %s",
1991 na->name);
1992 goto put_out;
1993 }
1994
1958 */
1959 error = kring->nm_sync(kring, 0);
1960 if (error)
1961 goto put_out;
1962 if (kring->nr_hwcur == kring->nr_hwtail && netmap_verbose) {
1963 D("how strange, interrupt with no packets on %s",
1964 na->name);
1965 goto put_out;
1966 }
1967
1995 /* new packets are ring->cur to ring->tail, and the bkring
1996 * had hwcur == ring->cur. So advance ring->cur to ring->tail
1968 /* new packets are kring->rcur to kring->nr_hwtail, and the bkring
1969 * had hwcur == bkring->rhead. So advance bkring->rhead to kring->nr_hwtail
1997 * to push all packets out.
1998 */
1970 * to push all packets out.
1971 */
1999 ring->head = ring->cur = ring->tail;
1972 bkring->rhead = bkring->rcur = kring->nr_hwtail;
2000
1973
2001 /* also set tail to what the bwrap expects */
2002 bkring = &vpna->up.tx_rings[ring_nr];
2003 ring->tail = bkring->nr_hwtail; // rtail too ?
2004
2005 /* pass packets to the switch */
2006 nm_txsync_prologue(bkring); // XXX error checking ?
2007 netmap_vp_txsync(bkring, flags);
2008
2009 /* mark all buffers as released on this ring */
1974 netmap_vp_txsync(bkring, flags);
1975
1976 /* mark all buffers as released on this ring */
2010 ring->head = ring->cur = kring->nr_hwtail;
2011 ring->tail = kring->rtail;
1977 kring->rhead = kring->rcur = kring->rtail = kring->nr_hwtail;
2012 /* another call to actually release the buffers */
1978 /* another call to actually release the buffers */
2013 if (!is_host_ring) {
2014 error = kring->nm_sync(kring, 0);
2015 } else {
2016 /* mark all packets as released, as in the
2017 * second part of netmap_rxsync_from_host()
2018 */
2019 kring->nr_hwcur = kring->nr_hwtail;
2020 nm_rxsync_finalize(kring);
2021 }
1979 error = kring->nm_sync(kring, 0);
2022
2023put_out:
2024 nm_kr_put(kring);
2025 return error;
2026}
2027
2028
2029/* nm_register callback for bwrap */
2030static int
2031netmap_bwrap_register(struct netmap_adapter *na, int onoff)
2032{
2033 struct netmap_bwrap_adapter *bna =
2034 (struct netmap_bwrap_adapter *)na;
2035 struct netmap_adapter *hwna = bna->hwna;
2036 struct netmap_vp_adapter *hostna = &bna->host;
2037 int error;
1980
1981put_out:
1982 nm_kr_put(kring);
1983 return error;
1984}
1985
1986
1987/* nm_register callback for bwrap */
1988static int
1989netmap_bwrap_register(struct netmap_adapter *na, int onoff)
1990{
1991 struct netmap_bwrap_adapter *bna =
1992 (struct netmap_bwrap_adapter *)na;
1993 struct netmap_adapter *hwna = bna->hwna;
1994 struct netmap_vp_adapter *hostna = &bna->host;
1995 int error;
1996 enum txrx t;
2038
2039 ND("%s %s", na->name, onoff ? "on" : "off");
2040
2041 if (onoff) {
2042 int i;
2043
2044 /* netmap_do_regif has been called on the bwrap na.
2045 * We need to pass the information about the
2046 * memory allocator down to the hwna before
2047 * putting it in netmap mode
2048 */
2049 hwna->na_lut = na->na_lut;
1997
1998 ND("%s %s", na->name, onoff ? "on" : "off");
1999
2000 if (onoff) {
2001 int i;
2002
2003 /* netmap_do_regif has been called on the bwrap na.
2004 * We need to pass the information about the
2005 * memory allocator down to the hwna before
2006 * putting it in netmap mode
2007 */
2008 hwna->na_lut = na->na_lut;
2050 hwna->na_lut_objtotal = na->na_lut_objtotal;
2051 hwna->na_lut_objsize = na->na_lut_objsize;
2052
2053 if (hostna->na_bdg) {
2054 /* if the host rings have been attached to switch,
2055 * we need to copy the memory allocator information
2056 * in the hostna also
2057 */
2058 hostna->up.na_lut = na->na_lut;
2009
2010 if (hostna->na_bdg) {
2011 /* if the host rings have been attached to switch,
2012 * we need to copy the memory allocator information
2013 * in the hostna also
2014 */
2015 hostna->up.na_lut = na->na_lut;
2059 hostna->up.na_lut_objtotal = na->na_lut_objtotal;
2060 hostna->up.na_lut_objsize = na->na_lut_objsize;
2061 }
2062
2063 /* cross-link the netmap rings
2064 * The original number of rings comes from hwna,
2065 * rx rings on one side equals tx rings on the other.
2066 * We need to do this now, after the initialization
2067 * of the kring->ring pointers
2068 */
2016 }
2017
2018 /* cross-link the netmap rings
2019 * The original number of rings comes from hwna,
2020 * rx rings on one side equals tx rings on the other.
2021 * We need to do this now, after the initialization
2022 * of the kring->ring pointers
2023 */
2069 for (i = 0; i < na->num_rx_rings + 1; i++) {
2070 hwna->tx_rings[i].nkr_num_slots = na->rx_rings[i].nkr_num_slots;
2071 hwna->tx_rings[i].ring = na->rx_rings[i].ring;
2024 for_rx_tx(t) {
2025 enum txrx r= nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */
2026 for (i = 0; i < nma_get_nrings(na, r) + 1; i++) {
2027 NMR(hwna, t)[i].nkr_num_slots = NMR(na, r)[i].nkr_num_slots;
2028 NMR(hwna, t)[i].ring = NMR(na, r)[i].ring;
2029 }
2072 }
2030 }
2073 for (i = 0; i < na->num_tx_rings + 1; i++) {
2074 hwna->rx_rings[i].nkr_num_slots = na->tx_rings[i].nkr_num_slots;
2075 hwna->rx_rings[i].ring = na->tx_rings[i].ring;
2076 }
2077 }
2078
2079 /* forward the request to the hwna */
2080 error = hwna->nm_register(hwna, onoff);
2081 if (error)
2082 return error;
2083
2084 /* impersonate a netmap_vp_adapter */
2085 netmap_vp_reg(na, onoff);
2086 if (hostna->na_bdg)
2087 netmap_vp_reg(&hostna->up, onoff);
2088
2089 if (onoff) {
2031 }
2032
2033 /* forward the request to the hwna */
2034 error = hwna->nm_register(hwna, onoff);
2035 if (error)
2036 return error;
2037
2038 /* impersonate a netmap_vp_adapter */
2039 netmap_vp_reg(na, onoff);
2040 if (hostna->na_bdg)
2041 netmap_vp_reg(&hostna->up, onoff);
2042
2043 if (onoff) {
2090 /* intercept the hwna nm_nofify callback */
2091 bna->save_notify = hwna->nm_notify;
2092 hwna->nm_notify = netmap_bwrap_intr_notify;
2044 u_int i;
2045 /* intercept the hwna nm_nofify callback on the hw rings */
2046 for (i = 0; i < hwna->num_rx_rings; i++) {
2047 hwna->rx_rings[i].save_notify = hwna->rx_rings[i].nm_notify;
2048 hwna->rx_rings[i].nm_notify = netmap_bwrap_intr_notify;
2049 }
2050 i = hwna->num_rx_rings; /* for safety */
2051 /* save the host ring notify unconditionally */
2052 hwna->rx_rings[i].save_notify = hwna->rx_rings[i].nm_notify;
2053 if (hostna->na_bdg) {
2054 /* also intercept the host ring notify */
2055 hwna->rx_rings[i].nm_notify = netmap_bwrap_intr_notify;
2056 }
2093 } else {
2057 } else {
2094 hwna->nm_notify = bna->save_notify;
2095 hwna->na_lut = NULL;
2096 hwna->na_lut_objtotal = 0;
2097 hwna->na_lut_objsize = 0;
2058 u_int i;
2059 /* reset all notify callbacks (including host ring) */
2060 for (i = 0; i <= hwna->num_rx_rings; i++) {
2061 hwna->rx_rings[i].nm_notify = hwna->rx_rings[i].save_notify;
2062 hwna->rx_rings[i].save_notify = NULL;
2063 }
2064 hwna->na_lut.lut = NULL;
2065 hwna->na_lut.objtotal = 0;
2066 hwna->na_lut.objsize = 0;
2098 }
2099
2100 return 0;
2101}
2102
2103/* nm_config callback for bwrap */
2104static int
2105netmap_bwrap_config(struct netmap_adapter *na, u_int *txr, u_int *txd,

--- 43 unchanged lines hidden (view full) ---

2149 * now the kring->ring pointers have not been initialized yet
2150 */
2151
2152 if (na->na_flags & NAF_HOST_RINGS) {
2153 /* the hostna rings are the host rings of the bwrap.
2154 * The corresponding krings must point back to the
2155 * hostna
2156 */
2067 }
2068
2069 return 0;
2070}
2071
2072/* nm_config callback for bwrap */
2073static int
2074netmap_bwrap_config(struct netmap_adapter *na, u_int *txr, u_int *txd,

--- 43 unchanged lines hidden (view full) ---

2118 * now the kring->ring pointers have not been initialized yet
2119 */
2120
2121 if (na->na_flags & NAF_HOST_RINGS) {
2122 /* the hostna rings are the host rings of the bwrap.
2123 * The corresponding krings must point back to the
2124 * hostna
2125 */
2157 hostna->tx_rings = na->tx_rings + na->num_tx_rings;
2126 hostna->tx_rings = &na->tx_rings[na->num_tx_rings];
2158 hostna->tx_rings[0].na = hostna;
2127 hostna->tx_rings[0].na = hostna;
2159 hostna->rx_rings = na->rx_rings + na->num_rx_rings;
2128 hostna->rx_rings = &na->rx_rings[na->num_rx_rings];
2160 hostna->rx_rings[0].na = hostna;
2161 }
2162
2163 return 0;
2164}
2165
2166
2167static void

--- 7 unchanged lines hidden (view full) ---

2175
2176 hwna->nm_krings_delete(hwna);
2177 netmap_vp_krings_delete(na);
2178}
2179
2180
2181/* notify method for the bridge-->hwna direction */
2182static int
2129 hostna->rx_rings[0].na = hostna;
2130 }
2131
2132 return 0;
2133}
2134
2135
2136static void

--- 7 unchanged lines hidden (view full) ---

2144
2145 hwna->nm_krings_delete(hwna);
2146 netmap_vp_krings_delete(na);
2147}
2148
2149
2150/* notify method for the bridge-->hwna direction */
2151static int
2183netmap_bwrap_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx, int flags)
2152netmap_bwrap_notify(struct netmap_kring *kring, int flags)
2184{
2153{
2185 struct netmap_bwrap_adapter *bna =
2186 (struct netmap_bwrap_adapter *)na;
2154 struct netmap_adapter *na = kring->na;
2155 struct netmap_bwrap_adapter *bna = na->na_private;
2187 struct netmap_adapter *hwna = bna->hwna;
2156 struct netmap_adapter *hwna = bna->hwna;
2188 struct netmap_kring *kring, *hw_kring;
2189 struct netmap_ring *ring;
2190 u_int lim;
2157 u_int ring_n = kring->ring_id;
2158 u_int lim = kring->nkr_num_slots - 1;
2159 struct netmap_kring *hw_kring;
2191 int error = 0;
2192
2160 int error = 0;
2161
2193 if (tx == NR_TX)
2194 return EINVAL;
2195
2196 kring = &na->rx_rings[ring_n];
2162 ND("%s: na %s hwna %s",
2163 (kring ? kring->name : "NULL!"),
2164 (na ? na->name : "NULL!"),
2165 (hwna ? hwna->name : "NULL!"));
2197 hw_kring = &hwna->tx_rings[ring_n];
2166 hw_kring = &hwna->tx_rings[ring_n];
2198 ring = kring->ring;
2199 lim = kring->nkr_num_slots - 1;
2200
2167
2168 if (nm_kr_tryget(hw_kring))
2169 return 0;
2170
2201 if (!nm_netmap_on(hwna))
2202 return 0;
2171 if (!nm_netmap_on(hwna))
2172 return 0;
2203 mtx_lock(&kring->q_lock);
2204 /* first step: simulate a user wakeup on the rx ring */
2173 /* first step: simulate a user wakeup on the rx ring */
2205 netmap_vp_rxsync_locked(kring, flags);
2174 netmap_vp_rxsync(kring, flags);
2206 ND("%s[%d] PRE rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)",
2207 na->name, ring_n,
2208 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease,
2209 ring->head, ring->cur, ring->tail,
2210 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_ring->rtail);
2175 ND("%s[%d] PRE rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)",
2176 na->name, ring_n,
2177 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease,
2178 ring->head, ring->cur, ring->tail,
2179 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_ring->rtail);
2211 /* second step: the simulated user consumes all new packets */
2212 ring->head = ring->cur = ring->tail;
2213
2214 /* third step: the new packets are sent on the tx ring
2180 /* second step: the new packets are sent on the tx ring
2215 * (which is actually the same ring)
2216 */
2181 * (which is actually the same ring)
2182 */
2217 /* set tail to what the hw expects */
2218 ring->tail = hw_kring->rtail;
2219 nm_txsync_prologue(&hwna->tx_rings[ring_n]); // XXX error checking ?
2183 hw_kring->rhead = hw_kring->rcur = kring->nr_hwtail;
2220 error = hw_kring->nm_sync(hw_kring, flags);
2184 error = hw_kring->nm_sync(hw_kring, flags);
2185 if (error)
2186 goto out;
2221
2187
2222 /* fourth step: now we are back the rx ring */
2188 /* third step: now we are back the rx ring */
2223 /* claim ownership on all hw owned bufs */
2189 /* claim ownership on all hw owned bufs */
2224 ring->head = nm_next(ring->tail, lim); /* skip past reserved slot */
2225 ring->tail = kring->rtail; /* restore saved value of tail, for safety */
2190 kring->rhead = kring->rcur = nm_next(hw_kring->nr_hwtail, lim); /* skip past reserved slot */
2226
2191
2227 /* fifth step: the user goes to sleep again, causing another rxsync */
2228 netmap_vp_rxsync_locked(kring, flags);
2192 /* fourth step: the user goes to sleep again, causing another rxsync */
2193 netmap_vp_rxsync(kring, flags);
2229 ND("%s[%d] PST rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)",
2230 na->name, ring_n,
2231 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease,
2232 ring->head, ring->cur, ring->tail,
2233 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_kring->rtail);
2194 ND("%s[%d] PST rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)",
2195 na->name, ring_n,
2196 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease,
2197 ring->head, ring->cur, ring->tail,
2198 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_kring->rtail);
2234 mtx_unlock(&kring->q_lock);
2199out:
2200 nm_kr_put(hw_kring);
2235 return error;
2236}
2237
2238
2201 return error;
2202}
2203
2204
2239/* notify method for the bridge-->host-rings path */
2240static int
2241netmap_bwrap_host_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx, int flags)
2242{
2243 struct netmap_bwrap_adapter *bna = na->na_private;
2244 struct netmap_adapter *port_na = &bna->up.up;
2245 if (tx == NR_TX || ring_n != 0)
2246 return EINVAL;
2247 return netmap_bwrap_notify(port_na, port_na->num_rx_rings, NR_RX, flags);
2248}
2249
2250
2251/* nm_bdg_ctl callback for the bwrap.
2252 * Called on bridge-attach and detach, as an effect of vale-ctl -[ahd].
2253 * On attach, it needs to provide a fake netmap_priv_d structure and
2254 * perform a netmap_do_regif() on the bwrap. This will put both the
2255 * bwrap and the hwna in netmap mode, with the netmap rings shared
2256 * and cross linked. Moroever, it will start intercepting interrupts
2257 * directed to hwna.
2258 */
2259static int
2260netmap_bwrap_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach)
2261{
2262 struct netmap_priv_d *npriv;
2263 struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na;
2205/* nm_bdg_ctl callback for the bwrap.
2206 * Called on bridge-attach and detach, as an effect of vale-ctl -[ahd].
2207 * On attach, it needs to provide a fake netmap_priv_d structure and
2208 * perform a netmap_do_regif() on the bwrap. This will put both the
2209 * bwrap and the hwna in netmap mode, with the netmap rings shared
2210 * and cross linked. Moroever, it will start intercepting interrupts
2211 * directed to hwna.
2212 */
2213static int
2214netmap_bwrap_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach)
2215{
2216 struct netmap_priv_d *npriv;
2217 struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na;
2264 struct netmap_if *nifp;
2265 int error = 0;
2266
2267 if (attach) {
2268 if (NETMAP_OWNED_BY_ANY(na)) {
2269 return EBUSY;
2270 }
2271 if (bna->na_kpriv) {
2272 /* nothing to do */
2273 return 0;
2274 }
2275 npriv = malloc(sizeof(*npriv), M_DEVBUF, M_NOWAIT|M_ZERO);
2276 if (npriv == NULL)
2277 return ENOMEM;
2218 int error = 0;
2219
2220 if (attach) {
2221 if (NETMAP_OWNED_BY_ANY(na)) {
2222 return EBUSY;
2223 }
2224 if (bna->na_kpriv) {
2225 /* nothing to do */
2226 return 0;
2227 }
2228 npriv = malloc(sizeof(*npriv), M_DEVBUF, M_NOWAIT|M_ZERO);
2229 if (npriv == NULL)
2230 return ENOMEM;
2278 nifp = netmap_do_regif(npriv, na, nmr->nr_ringid, nmr->nr_flags, &error);
2279 if (!nifp) {
2231 error = netmap_do_regif(npriv, na, nmr->nr_ringid, nmr->nr_flags);
2232 if (error) {
2280 bzero(npriv, sizeof(*npriv));
2281 free(npriv, M_DEVBUF);
2282 return error;
2283 }
2284 bna->na_kpriv = npriv;
2285 na->na_flags |= NAF_BUSY;
2286 } else {
2287 int last_instance;

--- 30 unchanged lines hidden (view full) ---

2318/* attach a bridge wrapper to the 'real' device */
2319int
2320netmap_bwrap_attach(const char *nr_name, struct netmap_adapter *hwna)
2321{
2322 struct netmap_bwrap_adapter *bna;
2323 struct netmap_adapter *na = NULL;
2324 struct netmap_adapter *hostna = NULL;
2325 int error = 0;
2233 bzero(npriv, sizeof(*npriv));
2234 free(npriv, M_DEVBUF);
2235 return error;
2236 }
2237 bna->na_kpriv = npriv;
2238 na->na_flags |= NAF_BUSY;
2239 } else {
2240 int last_instance;

--- 30 unchanged lines hidden (view full) ---

2271/* attach a bridge wrapper to the 'real' device */
2272int
2273netmap_bwrap_attach(const char *nr_name, struct netmap_adapter *hwna)
2274{
2275 struct netmap_bwrap_adapter *bna;
2276 struct netmap_adapter *na = NULL;
2277 struct netmap_adapter *hostna = NULL;
2278 int error = 0;
2279 enum txrx t;
2326
2327 /* make sure the NIC is not already in use */
2328 if (NETMAP_OWNED_BY_ANY(hwna)) {
2329 D("NIC %s busy, cannot attach to bridge", hwna->name);
2330 return EBUSY;
2331 }
2332
2333 bna = malloc(sizeof(*bna), M_DEVBUF, M_NOWAIT | M_ZERO);
2334 if (bna == NULL) {
2335 return ENOMEM;
2336 }
2337
2338 na = &bna->up.up;
2280
2281 /* make sure the NIC is not already in use */
2282 if (NETMAP_OWNED_BY_ANY(hwna)) {
2283 D("NIC %s busy, cannot attach to bridge", hwna->name);
2284 return EBUSY;
2285 }
2286
2287 bna = malloc(sizeof(*bna), M_DEVBUF, M_NOWAIT | M_ZERO);
2288 if (bna == NULL) {
2289 return ENOMEM;
2290 }
2291
2292 na = &bna->up.up;
2293 na->na_private = bna;
2339 strncpy(na->name, nr_name, sizeof(na->name));
2340 /* fill the ring data for the bwrap adapter with rx/tx meanings
2341 * swapped. The real cross-linking will be done during register,
2342 * when all the krings will have been created.
2343 */
2294 strncpy(na->name, nr_name, sizeof(na->name));
2295 /* fill the ring data for the bwrap adapter with rx/tx meanings
2296 * swapped. The real cross-linking will be done during register,
2297 * when all the krings will have been created.
2298 */
2344 na->num_rx_rings = hwna->num_tx_rings;
2345 na->num_tx_rings = hwna->num_rx_rings;
2346 na->num_tx_desc = hwna->num_rx_desc;
2347 na->num_rx_desc = hwna->num_tx_desc;
2299 for_rx_tx(t) {
2300 enum txrx r = nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */
2301 nma_set_nrings(na, t, nma_get_nrings(hwna, r));
2302 nma_set_ndesc(na, t, nma_get_ndesc(hwna, r));
2303 }
2348 na->nm_dtor = netmap_bwrap_dtor;
2349 na->nm_register = netmap_bwrap_register;
2350 // na->nm_txsync = netmap_bwrap_txsync;
2351 // na->nm_rxsync = netmap_bwrap_rxsync;
2352 na->nm_config = netmap_bwrap_config;
2353 na->nm_krings_create = netmap_bwrap_krings_create;
2354 na->nm_krings_delete = netmap_bwrap_krings_delete;
2355 na->nm_notify = netmap_bwrap_notify;

--- 15 unchanged lines hidden (view full) ---

2371
2372 if (hwna->na_flags & NAF_HOST_RINGS) {
2373 if (hwna->na_flags & NAF_SW_ONLY)
2374 na->na_flags |= NAF_SW_ONLY;
2375 na->na_flags |= NAF_HOST_RINGS;
2376 hostna = &bna->host.up;
2377 snprintf(hostna->name, sizeof(hostna->name), "%s^", nr_name);
2378 hostna->ifp = hwna->ifp;
2304 na->nm_dtor = netmap_bwrap_dtor;
2305 na->nm_register = netmap_bwrap_register;
2306 // na->nm_txsync = netmap_bwrap_txsync;
2307 // na->nm_rxsync = netmap_bwrap_rxsync;
2308 na->nm_config = netmap_bwrap_config;
2309 na->nm_krings_create = netmap_bwrap_krings_create;
2310 na->nm_krings_delete = netmap_bwrap_krings_delete;
2311 na->nm_notify = netmap_bwrap_notify;

--- 15 unchanged lines hidden (view full) ---

2327
2328 if (hwna->na_flags & NAF_HOST_RINGS) {
2329 if (hwna->na_flags & NAF_SW_ONLY)
2330 na->na_flags |= NAF_SW_ONLY;
2331 na->na_flags |= NAF_HOST_RINGS;
2332 hostna = &bna->host.up;
2333 snprintf(hostna->name, sizeof(hostna->name), "%s^", nr_name);
2334 hostna->ifp = hwna->ifp;
2379 hostna->num_tx_rings = 1;
2380 hostna->num_tx_desc = hwna->num_rx_desc;
2381 hostna->num_rx_rings = 1;
2382 hostna->num_rx_desc = hwna->num_tx_desc;
2335 for_rx_tx(t) {
2336 enum txrx r = nm_txrx_swap(t);
2337 nma_set_nrings(hostna, t, 1);
2338 nma_set_ndesc(hostna, t, nma_get_ndesc(hwna, r));
2339 }
2383 // hostna->nm_txsync = netmap_bwrap_host_txsync;
2384 // hostna->nm_rxsync = netmap_bwrap_host_rxsync;
2340 // hostna->nm_txsync = netmap_bwrap_host_txsync;
2341 // hostna->nm_rxsync = netmap_bwrap_host_rxsync;
2385 hostna->nm_notify = netmap_bwrap_host_notify;
2342 hostna->nm_notify = netmap_bwrap_notify;
2386 hostna->nm_mem = na->nm_mem;
2387 hostna->na_private = bna;
2388 hostna->na_vp = &bna->up;
2389 na->na_hostvp = hwna->na_hostvp =
2390 hostna->na_hostvp = &bna->host;
2391 hostna->na_flags = NAF_BUSY; /* prevent NIOCREGIF */
2392 }
2393

--- 17 unchanged lines hidden (view full) ---

2411 /* make hwna point to the allocator we are actually using,
2412 * so that monitors will be able to find it
2413 */
2414 bna->save_nmd = hwna->nm_mem;
2415 hwna->nm_mem = na->nm_mem;
2416 return 0;
2417
2418err_free:
2343 hostna->nm_mem = na->nm_mem;
2344 hostna->na_private = bna;
2345 hostna->na_vp = &bna->up;
2346 na->na_hostvp = hwna->na_hostvp =
2347 hostna->na_hostvp = &bna->host;
2348 hostna->na_flags = NAF_BUSY; /* prevent NIOCREGIF */
2349 }
2350

--- 17 unchanged lines hidden (view full) ---

2368 /* make hwna point to the allocator we are actually using,
2369 * so that monitors will be able to find it
2370 */
2371 bna->save_nmd = hwna->nm_mem;
2372 hwna->nm_mem = na->nm_mem;
2373 return 0;
2374
2375err_free:
2419 netmap_mem_private_delete(na->nm_mem);
2376 netmap_mem_delete(na->nm_mem);
2420err_put:
2421 hwna->na_vp = hwna->na_hostvp = NULL;
2422 netmap_adapter_put(hwna);
2423 free(bna, M_DEVBUF);
2424 return error;
2425
2426}
2427
2377err_put:
2378 hwna->na_vp = hwna->na_hostvp = NULL;
2379 netmap_adapter_put(hwna);
2380 free(bna, M_DEVBUF);
2381 return error;
2382
2383}
2384
2385struct nm_bridge *
2386netmap_init_bridges2(u_int n)
2387{
2388 int i;
2389 struct nm_bridge *b;
2428
2390
2391 b = malloc(sizeof(struct nm_bridge) * n, M_DEVBUF,
2392 M_NOWAIT | M_ZERO);
2393 if (b == NULL)
2394 return NULL;
2395 for (i = 0; i < n; i++)
2396 BDG_RWINIT(&b[i]);
2397 return b;
2398}
2399
2429void
2400void
2430netmap_init_bridges(void)
2401netmap_uninit_bridges2(struct nm_bridge *b, u_int n)
2431{
2432 int i;
2402{
2403 int i;
2433 bzero(nm_bridges, sizeof(struct nm_bridge) * NM_BRIDGES); /* safety */
2434 for (i = 0; i < NM_BRIDGES; i++)
2435 BDG_RWINIT(&nm_bridges[i]);
2404
2405 if (b == NULL)
2406 return;
2407
2408 for (i = 0; i < n; i++)
2409 BDG_RWDESTROY(&b[i]);
2410 free(b, M_DEVBUF);
2436}
2411}
2412
2413int
2414netmap_init_bridges(void)
2415{
2416#ifdef CONFIG_NET_NS
2417 return netmap_bns_register();
2418#else
2419 nm_bridges = netmap_init_bridges2(NM_BRIDGES);
2420 if (nm_bridges == NULL)
2421 return ENOMEM;
2422 return 0;
2423#endif
2424}
2425
2426void
2427netmap_uninit_bridges(void)
2428{
2429#ifdef CONFIG_NET_NS
2430 netmap_bns_unregister();
2431#else
2432 netmap_uninit_bridges2(nm_bridges, NM_BRIDGES);
2433#endif
2434}
2437#endif /* WITH_VALE */
2435#endif /* WITH_VALE */