1522d5c66SAsim Jamshed /* for io_module_func def'ns */ 2522d5c66SAsim Jamshed #include "io_module.h" 3522d5c66SAsim Jamshed /* for mtcp related def'ns */ 4522d5c66SAsim Jamshed #include "mtcp.h" 5522d5c66SAsim Jamshed /* for errno */ 6522d5c66SAsim Jamshed #include <errno.h> 7522d5c66SAsim Jamshed /* for logging */ 8522d5c66SAsim Jamshed #include "debug.h" 9522d5c66SAsim Jamshed /* for num_devices_* */ 10522d5c66SAsim Jamshed #include "config.h" 11522d5c66SAsim Jamshed /* for netmap definitions */ 12522d5c66SAsim Jamshed #define NETMAP_WITH_LIBS 13522d5c66SAsim Jamshed #include "netmap_user.h" 14522d5c66SAsim Jamshed /* for poll */ 15522d5c66SAsim Jamshed #include <sys/poll.h> 16522d5c66SAsim Jamshed /* for NBBY */ 17522d5c66SAsim Jamshed #include <sys/param.h> 18522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 19522d5c66SAsim Jamshed #define MAX_PKT_BURST 64 20522d5c66SAsim Jamshed #define ETHERNET_FRAME_SIZE 1514 21522d5c66SAsim Jamshed #define MAX_IFNAMELEN (IF_NAMESIZE + 10) 22522d5c66SAsim Jamshed #define EXTRA_BUFS 512 23522d5c66SAsim Jamshed #define IDLE_POLL_WAIT 1 /* msecs */ 24522d5c66SAsim Jamshed #define IDLE_POLL_COUNT 10 25522d5c66SAsim Jamshed //#define CONST_POLLING 1 26522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 27522d5c66SAsim Jamshed 28522d5c66SAsim Jamshed struct netmap_private_context { 29522d5c66SAsim Jamshed struct nm_desc *local_nmd[MAX_DEVICES]; 30522d5c66SAsim Jamshed unsigned char snd_pktbuf[MAX_DEVICES][ETHERNET_FRAME_SIZE]; 31522d5c66SAsim Jamshed unsigned char *rcv_pktbuf[MAX_PKT_BURST]; 32522d5c66SAsim Jamshed uint16_t rcv_pkt_len[MAX_PKT_BURST]; 33522d5c66SAsim Jamshed uint16_t snd_pkt_size[MAX_DEVICES]; 34522d5c66SAsim Jamshed uint8_t dev_poll_flag[MAX_DEVICES]; 35522d5c66SAsim Jamshed uint8_t idle_poll_count; 36522d5c66SAsim Jamshed } __attribute__((aligned(__WORDSIZE))); 37522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 38522d5c66SAsim Jamshed void 39522d5c66SAsim Jamshed netmap_init_handle(struct mtcp_thread_context *ctxt) 40522d5c66SAsim Jamshed { 41522d5c66SAsim Jamshed struct netmap_private_context *npc; 42522d5c66SAsim Jamshed char ifname[MAX_IFNAMELEN]; 43522d5c66SAsim Jamshed char nifname[MAX_IFNAMELEN]; 44522d5c66SAsim Jamshed struct netdev_entry **ent; 45522d5c66SAsim Jamshed int j; 46522d5c66SAsim Jamshed 47522d5c66SAsim Jamshed ent = g_config.mos->netdev_table->ent; 48522d5c66SAsim Jamshed /* create and initialize private I/O module context */ 49522d5c66SAsim Jamshed ctxt->io_private_context = calloc(1, sizeof(struct netmap_private_context)); 50522d5c66SAsim Jamshed if (ctxt->io_private_context == NULL) { 51522d5c66SAsim Jamshed TRACE_ERROR("Failed to initialize ctxt->io_private_context: " 52522d5c66SAsim Jamshed "Can't allocate memory\n"); 53522d5c66SAsim Jamshed exit(EXIT_FAILURE); 54522d5c66SAsim Jamshed } 55522d5c66SAsim Jamshed 56522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 57522d5c66SAsim Jamshed 58522d5c66SAsim Jamshed /* initialize per-thread netmap interfaces */ 59522d5c66SAsim Jamshed for (j = 0; j < g_config.mos->netdev_table->num; j++) { 60522d5c66SAsim Jamshed #if 0 61522d5c66SAsim Jamshed if (if_indextoname(devices_attached[j], ifname) == NULL) { 62522d5c66SAsim Jamshed TRACE_ERROR("Failed to initialize interface %s with ifidx: %d - " 63522d5c66SAsim Jamshed "error string: %s\n", 64522d5c66SAsim Jamshed ifname, devices_attached[j], strerror(errno)); 65522d5c66SAsim Jamshed exit(EXIT_FAILURE); 66522d5c66SAsim Jamshed } 67522d5c66SAsim Jamshed #else 68522d5c66SAsim Jamshed strcpy(ifname, ent[j]->dev_name); 69522d5c66SAsim Jamshed #endif 70522d5c66SAsim Jamshed if (unlikely(g_config.mos->num_cores == 1)) 71522d5c66SAsim Jamshed sprintf(nifname, "netmap:%s", ifname); 72522d5c66SAsim Jamshed else 73522d5c66SAsim Jamshed sprintf(nifname, "netmap:%s-%d", ifname, ctxt->cpu); 74522d5c66SAsim Jamshed 75522d5c66SAsim Jamshed TRACE_INFO("Opening %s with j: %d (cpu: %d)\n", nifname, j, ctxt->cpu); 76522d5c66SAsim Jamshed 77522d5c66SAsim Jamshed struct nmreq base_nmd; 78522d5c66SAsim Jamshed memset(&base_nmd, 0, sizeof(base_nmd)); 79522d5c66SAsim Jamshed base_nmd.nr_arg3 = EXTRA_BUFS; 80522d5c66SAsim Jamshed 81522d5c66SAsim Jamshed npc->local_nmd[j] = nm_open(nifname, &base_nmd, 0, NULL); 82522d5c66SAsim Jamshed if (npc->local_nmd[j] == NULL) { 83522d5c66SAsim Jamshed TRACE_ERROR("Unable to open %s: %s\n", 84522d5c66SAsim Jamshed nifname, strerror(errno)); 85522d5c66SAsim Jamshed exit(EXIT_FAILURE); 86522d5c66SAsim Jamshed } 87522d5c66SAsim Jamshed } 88522d5c66SAsim Jamshed } 89522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 90522d5c66SAsim Jamshed int 91522d5c66SAsim Jamshed netmap_link_devices(struct mtcp_thread_context *ctxt) 92522d5c66SAsim Jamshed { 93522d5c66SAsim Jamshed /* linking takes place during mtcp_init() */ 94522d5c66SAsim Jamshed 95522d5c66SAsim Jamshed return 0; 96522d5c66SAsim Jamshed } 97522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 98522d5c66SAsim Jamshed void 99522d5c66SAsim Jamshed netmap_release_pkt(struct mtcp_thread_context *ctxt, int ifidx, unsigned char *pkt_data, int len) 100522d5c66SAsim Jamshed { 101522d5c66SAsim Jamshed /* 102522d5c66SAsim Jamshed * do nothing over here - memory reclamation 103522d5c66SAsim Jamshed * will take place in dpdk_recv_pkts 104522d5c66SAsim Jamshed */ 105522d5c66SAsim Jamshed } 106522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 107522d5c66SAsim Jamshed int 108522d5c66SAsim Jamshed netmap_send_pkts(struct mtcp_thread_context *ctxt, int nif) 109522d5c66SAsim Jamshed { 110522d5c66SAsim Jamshed int pkt_size, idx; 111522d5c66SAsim Jamshed struct netmap_private_context *npc; 112522d5c66SAsim Jamshed mtcp_manager_t mtcp; 113522d5c66SAsim Jamshed 114522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 115522d5c66SAsim Jamshed idx = nif; 116522d5c66SAsim Jamshed pkt_size = npc->snd_pkt_size[idx]; 117522d5c66SAsim Jamshed mtcp = ctxt->mtcp_manager; 118522d5c66SAsim Jamshed 119522d5c66SAsim Jamshed /* assert-type statement */ 120522d5c66SAsim Jamshed if (pkt_size == 0) return 0; 121522d5c66SAsim Jamshed 122522d5c66SAsim Jamshed #ifdef NETSTAT 123522d5c66SAsim Jamshed mtcp->nstat.tx_packets[nif]++; 124522d5c66SAsim Jamshed mtcp->nstat.tx_bytes[nif] += pkt_size + 24; 125522d5c66SAsim Jamshed #endif 126522d5c66SAsim Jamshed 127522d5c66SAsim Jamshed tx_again: 128522d5c66SAsim Jamshed if (nm_inject(npc->local_nmd[idx], npc->snd_pktbuf[idx], pkt_size) == 0) { 129522d5c66SAsim Jamshed TRACE_DBG("Failed to send pkt of size %d on interface: %d\n", 130522d5c66SAsim Jamshed pkt_size, idx); 131522d5c66SAsim Jamshed 132522d5c66SAsim Jamshed ioctl(npc->local_nmd[idx]->fd, NIOCTXSYNC, NULL); 133522d5c66SAsim Jamshed goto tx_again; 134522d5c66SAsim Jamshed } 135522d5c66SAsim Jamshed 136522d5c66SAsim Jamshed #ifdef NETSTAT 137522d5c66SAsim Jamshed // mtcp->nstat.rx_errors[idx]++; 138522d5c66SAsim Jamshed #endif 139522d5c66SAsim Jamshed npc->snd_pkt_size[idx] = 0; 140522d5c66SAsim Jamshed 141522d5c66SAsim Jamshed return 1; 142522d5c66SAsim Jamshed } 143522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 144522d5c66SAsim Jamshed uint8_t * 145522d5c66SAsim Jamshed netmap_get_wptr(struct mtcp_thread_context *ctxt, int nif, uint16_t pktsize) 146522d5c66SAsim Jamshed { 147522d5c66SAsim Jamshed struct netmap_private_context *npc; 148522d5c66SAsim Jamshed int idx = nif; 149522d5c66SAsim Jamshed 150522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 151522d5c66SAsim Jamshed if (npc->snd_pkt_size[idx] != 0) 152522d5c66SAsim Jamshed netmap_send_pkts(ctxt, nif); 153522d5c66SAsim Jamshed 154522d5c66SAsim Jamshed npc->snd_pkt_size[idx] = pktsize; 155522d5c66SAsim Jamshed 156522d5c66SAsim Jamshed return (uint8_t *)npc->snd_pktbuf[idx]; 157522d5c66SAsim Jamshed } 158522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 159522d5c66SAsim Jamshed int32_t 160522d5c66SAsim Jamshed netmap_recv_pkts(struct mtcp_thread_context *ctxt, int ifidx) 161522d5c66SAsim Jamshed { 162522d5c66SAsim Jamshed struct netmap_private_context *npc; 163522d5c66SAsim Jamshed struct nm_desc *d; 164522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 165522d5c66SAsim Jamshed d = npc->local_nmd[ifidx]; 166522d5c66SAsim Jamshed 167522d5c66SAsim Jamshed int p = 0; 168522d5c66SAsim Jamshed int c, got = 0, ri = d->cur_rx_ring; 169522d5c66SAsim Jamshed int n = d->last_rx_ring - d->first_rx_ring + 1; 170522d5c66SAsim Jamshed int cnt = MAX_PKT_BURST; 171522d5c66SAsim Jamshed 172522d5c66SAsim Jamshed 173522d5c66SAsim Jamshed 174522d5c66SAsim Jamshed for (c = 0; c < n && cnt != got && npc->dev_poll_flag[ifidx]; c++) { 175522d5c66SAsim Jamshed /* compute current ring to use */ 176522d5c66SAsim Jamshed struct netmap_ring *ring; 177522d5c66SAsim Jamshed 178522d5c66SAsim Jamshed ri = d->cur_rx_ring + c; 179522d5c66SAsim Jamshed if (ri > d->last_rx_ring) 180522d5c66SAsim Jamshed ri = d->first_rx_ring; 181522d5c66SAsim Jamshed ring = NETMAP_RXRING(d->nifp, ri); 182522d5c66SAsim Jamshed for ( ; !nm_ring_empty(ring) && cnt != got; got++) { 183522d5c66SAsim Jamshed u_int i = ring->cur; 184522d5c66SAsim Jamshed u_int idx = ring->slot[i].buf_idx; 185522d5c66SAsim Jamshed npc->rcv_pktbuf[p] = (u_char *)NETMAP_BUF(ring, idx); 186522d5c66SAsim Jamshed npc->rcv_pkt_len[p] = ring->slot[i].len; 187522d5c66SAsim Jamshed p++; 188522d5c66SAsim Jamshed ring->head = ring->cur = nm_ring_next(ring, i); 189522d5c66SAsim Jamshed } 190522d5c66SAsim Jamshed } 191522d5c66SAsim Jamshed d->cur_rx_ring = ri; 192522d5c66SAsim Jamshed 193522d5c66SAsim Jamshed npc->dev_poll_flag[ifidx] = 0; 194522d5c66SAsim Jamshed 195522d5c66SAsim Jamshed return p; 196522d5c66SAsim Jamshed } 197522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 198522d5c66SAsim Jamshed uint8_t * 199522d5c66SAsim Jamshed netmap_get_rptr(struct mtcp_thread_context *ctxt, int ifidx, int index, uint16_t *len) 200522d5c66SAsim Jamshed { 201522d5c66SAsim Jamshed struct netmap_private_context *npc; 202522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 203522d5c66SAsim Jamshed 204522d5c66SAsim Jamshed *len = npc->rcv_pkt_len[index]; 205522d5c66SAsim Jamshed return (unsigned char *)npc->rcv_pktbuf[index]; 206522d5c66SAsim Jamshed } 207522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 208522d5c66SAsim Jamshed int32_t 209522d5c66SAsim Jamshed netmap_select(struct mtcp_thread_context *ctxt) 210522d5c66SAsim Jamshed { 211522d5c66SAsim Jamshed int i, rc; 212522d5c66SAsim Jamshed struct pollfd pfd[MAX_DEVICES]; 213522d5c66SAsim Jamshed struct netmap_private_context *npc = 214522d5c66SAsim Jamshed (struct netmap_private_context *)ctxt->io_private_context; 215522d5c66SAsim Jamshed 216522d5c66SAsim Jamshed /* see if num_devices have been registered */ 217522d5c66SAsim Jamshed if (npc->local_nmd[0] == NULL) 218522d5c66SAsim Jamshed return -1; 219522d5c66SAsim Jamshed 220522d5c66SAsim Jamshed for (i = 0; i < g_config.mos->netdev_table->num; i++) { 221522d5c66SAsim Jamshed pfd[i].fd = npc->local_nmd[i]->fd; 222522d5c66SAsim Jamshed pfd[i].events = POLLIN; 223522d5c66SAsim Jamshed } 224522d5c66SAsim Jamshed 225522d5c66SAsim Jamshed #ifndef CONST_POLLING 226522d5c66SAsim Jamshed if (npc->idle_poll_count >= IDLE_POLL_COUNT) { 227522d5c66SAsim Jamshed rc = poll(pfd, g_config.mos->netdev_table->num, IDLE_POLL_WAIT); 228522d5c66SAsim Jamshed } else 229522d5c66SAsim Jamshed #endif 230522d5c66SAsim Jamshed { 231522d5c66SAsim Jamshed rc = poll(pfd, g_config.mos->netdev_table->num, 0); 232522d5c66SAsim Jamshed } 233522d5c66SAsim Jamshed 234522d5c66SAsim Jamshed npc->idle_poll_count = (rc == 0) ? (npc->idle_poll_count + 1) : 0; 235522d5c66SAsim Jamshed 236522d5c66SAsim Jamshed for (i = 0; rc > 0 && i < g_config.mos->netdev_table->num; i++) 237522d5c66SAsim Jamshed if (!(pfd[i].revents & (POLLERR))) 238522d5c66SAsim Jamshed npc->dev_poll_flag[i] = 1; 239522d5c66SAsim Jamshed return 0; 240522d5c66SAsim Jamshed } 241522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 242522d5c66SAsim Jamshed int 243522d5c66SAsim Jamshed netmap_get_nif(struct ifreq *ifr) 244522d5c66SAsim Jamshed { 245522d5c66SAsim Jamshed int i; 246522d5c66SAsim Jamshed struct netdev_entry **ent = g_config.mos->netdev_table->ent; 247522d5c66SAsim Jamshed 248522d5c66SAsim Jamshed for (i = 0; i < g_config.mos->netdev_table->num; i++) 249522d5c66SAsim Jamshed if (!strcmp(ifr->ifr_name, ent[i]->dev_name)) 250522d5c66SAsim Jamshed return i; 251522d5c66SAsim Jamshed 252522d5c66SAsim Jamshed return -1; 253522d5c66SAsim Jamshed } 254522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 255522d5c66SAsim Jamshed int32_t 256522d5c66SAsim Jamshed netmap_dev_ioctl(struct mtcp_thread_context *ctx, int nif, int cmd, void *argp) 257522d5c66SAsim Jamshed { 258522d5c66SAsim Jamshed /* unimplemented */ 259522d5c66SAsim Jamshed return -1; 260522d5c66SAsim Jamshed } 261522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 262522d5c66SAsim Jamshed void 263522d5c66SAsim Jamshed netmap_destroy_handle(struct mtcp_thread_context *ctxt) 264522d5c66SAsim Jamshed { 265522d5c66SAsim Jamshed int i; 266522d5c66SAsim Jamshed struct netmap_private_context *npc; 267522d5c66SAsim Jamshed 268522d5c66SAsim Jamshed npc = (struct netmap_private_context *)ctxt->io_private_context; 269522d5c66SAsim Jamshed 270522d5c66SAsim Jamshed for (i = 0; i < g_config.mos->netdev_table->num; i++) 271522d5c66SAsim Jamshed close(npc->local_nmd[i]->fd); 272522d5c66SAsim Jamshed } 273522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 274522d5c66SAsim Jamshed void 275522d5c66SAsim Jamshed netmap_load_module_upper_half(void) 276522d5c66SAsim Jamshed { 277522d5c66SAsim Jamshed int i; 278522d5c66SAsim Jamshed int num_dev; 279522d5c66SAsim Jamshed uint64_t cpu_mask; 280522d5c66SAsim Jamshed int queue_range; 281522d5c66SAsim Jamshed 282522d5c66SAsim Jamshed num_dev = g_config.mos->netdev_table->num; 283522d5c66SAsim Jamshed 284522d5c66SAsim Jamshed for (i = 0; i < num_dev; i++) { 285522d5c66SAsim Jamshed cpu_mask = g_config.mos->netdev_table->ent[i]->cpu_mask; 286522d5c66SAsim Jamshed queue_range = sizeof(cpu_mask) * NBBY - __builtin_clzll(cpu_mask); 287522d5c66SAsim Jamshed num_queues = (num_queues < queue_range) ? 288522d5c66SAsim Jamshed queue_range : num_queues; 289522d5c66SAsim Jamshed } 290522d5c66SAsim Jamshed } 291522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 292*7e4ac3deSAsim Jamshed static void 293*7e4ac3deSAsim Jamshed set_promisc(char *ifname) 294*7e4ac3deSAsim Jamshed { 295*7e4ac3deSAsim Jamshed int fd, ret; 296*7e4ac3deSAsim Jamshed struct ifreq eth; 297*7e4ac3deSAsim Jamshed 298*7e4ac3deSAsim Jamshed fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 299*7e4ac3deSAsim Jamshed if (fd == -1) { 300*7e4ac3deSAsim Jamshed TRACE_ERROR("Couldn't open socket!\n"); 301*7e4ac3deSAsim Jamshed return; 302*7e4ac3deSAsim Jamshed } 303*7e4ac3deSAsim Jamshed strcpy(eth.ifr_name, ifname); 304*7e4ac3deSAsim Jamshed ret = ioctl(fd, SIOCGIFFLAGS, ð); 305*7e4ac3deSAsim Jamshed if (ret == -1) { 306*7e4ac3deSAsim Jamshed TRACE_ERROR("Get ioctl for %s failed!\n", 307*7e4ac3deSAsim Jamshed ifname); 308*7e4ac3deSAsim Jamshed close(fd); 309*7e4ac3deSAsim Jamshed return; 310*7e4ac3deSAsim Jamshed } 311*7e4ac3deSAsim Jamshed 312*7e4ac3deSAsim Jamshed if (eth.ifr_flags & IFF_PROMISC) { 313*7e4ac3deSAsim Jamshed TRACE_ERROR("Interface %s is already set to " 314*7e4ac3deSAsim Jamshed "promiscuous mode\n", ifname); 315*7e4ac3deSAsim Jamshed close(fd); 316*7e4ac3deSAsim Jamshed return; 317*7e4ac3deSAsim Jamshed } 318*7e4ac3deSAsim Jamshed eth.ifr_flags |= IFF_PROMISC; 319*7e4ac3deSAsim Jamshed 320*7e4ac3deSAsim Jamshed ret = ioctl(fd, SIOCSIFFLAGS, ð); 321*7e4ac3deSAsim Jamshed if (ret == -1) { 322*7e4ac3deSAsim Jamshed TRACE_ERROR("Set ioctl failed for %s\n", ifname); 323*7e4ac3deSAsim Jamshed close(fd); 324*7e4ac3deSAsim Jamshed return; 325*7e4ac3deSAsim Jamshed } 326*7e4ac3deSAsim Jamshed 327*7e4ac3deSAsim Jamshed close(fd); 328*7e4ac3deSAsim Jamshed 329*7e4ac3deSAsim Jamshed } 330*7e4ac3deSAsim Jamshed /*----------------------------------------------------------------------------*/ 331*7e4ac3deSAsim Jamshed void 332*7e4ac3deSAsim Jamshed netmap_load_module_lower_half(void) 333*7e4ac3deSAsim Jamshed { 334*7e4ac3deSAsim Jamshed struct netdev_entry **ent; 335*7e4ac3deSAsim Jamshed int j; 336*7e4ac3deSAsim Jamshed 337*7e4ac3deSAsim Jamshed ent = g_config.mos->netdev_table->ent; 338*7e4ac3deSAsim Jamshed 339*7e4ac3deSAsim Jamshed for (j = 0; j < g_config.mos->netdev_table->num; j++) { 340*7e4ac3deSAsim Jamshed set_promisc(ent[j]->dev_name); 341*7e4ac3deSAsim Jamshed } 342*7e4ac3deSAsim Jamshed } 343*7e4ac3deSAsim Jamshed /*----------------------------------------------------------------------------*/ 344522d5c66SAsim Jamshed io_module_func netmap_module_func = { 345522d5c66SAsim Jamshed .load_module_upper_half = netmap_load_module_upper_half, 346*7e4ac3deSAsim Jamshed .load_module_lower_half = netmap_load_module_lower_half, 347522d5c66SAsim Jamshed .init_handle = netmap_init_handle, 348522d5c66SAsim Jamshed .link_devices = netmap_link_devices, 349522d5c66SAsim Jamshed .release_pkt = netmap_release_pkt, 350522d5c66SAsim Jamshed .send_pkts = netmap_send_pkts, 351522d5c66SAsim Jamshed .get_wptr = netmap_get_wptr, 352522d5c66SAsim Jamshed .set_wptr = NULL, 353522d5c66SAsim Jamshed .recv_pkts = netmap_recv_pkts, 354522d5c66SAsim Jamshed .get_rptr = netmap_get_rptr, 355522d5c66SAsim Jamshed .get_nif = netmap_get_nif, 356522d5c66SAsim Jamshed .select = netmap_select, 357522d5c66SAsim Jamshed .destroy_handle = netmap_destroy_handle, 358522d5c66SAsim Jamshed .dev_ioctl = netmap_dev_ioctl, 359522d5c66SAsim Jamshed }; 360522d5c66SAsim Jamshed /*----------------------------------------------------------------------------*/ 361522d5c66SAsim Jamshed 362