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 */ |