def __listen(self, interface): receiver = netmap.NetmapDesc('netmap:' + interface) while 1: # sync RX rings with kernel receiver.rxsync() # scan all the receive rings rxr = None for i in range(receiver.interface.rx_rings): if receiver.receive_rings[i].head != receiver.receive_rings[i].tail: # At least one packet has been received on # this ring rxr = receiver.receive_rings[i] break if rxr is None: # no packets received on the rings, let's sleep a bit time.sleep(1) continue # slot pointed by rxr.head has been received # and can be extracted slot = rxr.slots[rxr.head] # convert the buffer associated to the slot to # a string of hexadecimal digits, up to the received length self.receive_queue.append(Packet(slot.buf[:slot.len].tobytes(), slot.buf[:slot.len].tolist(), slot.len)) self.receive_queue_length = self.receive_queue_length + 1 # update head and cur, managing index wraparound rxr.head = rxr.head + 1 if rxr.head >= rxr.num_slots: rxr.head -= rxr.num_slots rxr.cur = rxr.head
def transmit(idx, ifname, args, parser, queue): # use nm_open() to open the netmap device and register an interface # using an extended interface name nmd = netmap.NetmapDesc(ifname) time.sleep(args.wait_link) # build the packet that will be transmitted pkt = build_packet(args, parser) # fill in the netmap slots and netmap buffers for tx ring 0 txr = nmd.transmit_rings[idx] num_slots = txr.num_slots for i in range(num_slots): txr.slots[i].buf[0:len(pkt)] = pkt txr.slots[i].len = len(pkt) # transmit at maximum speed until Ctr-C is pressed cnt = 0 # packet counter batch = args.batch poller = select.poll() poller.register(nmd.getfd(), select.POLLOUT) t_start = time.time() try: cur = txr.cur while 1: ready_list = poller.poll(2) if len(ready_list) == 0: print("Timeout occurred") break n = txr.tail - cur # avail if n < 0: n += num_slots if n > batch: n = batch cur += n if cur >= num_slots: cur -= num_slots txr.cur = txr.head = cur # lazy update txr.cur and txr.head nmd.txsync() cnt += n except KeyboardInterrupt: # report the result to the main process queue.put([cnt, time.time() - t_start]) pass
def receive(idx, ifname, args, parser, queue): # use nm_open() to open the netmap device and register an interface # using an extended interface name nmd = netmap.NetmapDesc(ifname) time.sleep(args.wait_link) # select the right ring rxr = nmd.receive_rings[idx] num_slots = rxr.num_slots cnt = 0 # packet counter poller = select.poll() poller.register(nmd.getfd(), select.POLLIN) # wait for the first packet try: poller.poll() except KeyboardInterrupt: # report the result to the main process queue.put([cnt, None]) return # receive (throwing away everything) until Ctr-C is pressed t_start = time.time() try: cur = rxr.cur while 1: ready_list = poller.poll() if len(ready_list) == 0: print("Timeout occurred") break n = rxr.tail - cur # avail if n < 0: n += num_slots cur += n if cur >= num_slots: cur -= num_slots rxr.cur = rxr.head = cur # lazy update rxr.cur and rxr.head cnt += n except KeyboardInterrupt: # report the result to the main process queue.put([cnt, time.time() - t_start]) pass
# parse the input args = parser.parse_args() # print args # bound checking if args.length < 60: print('Invalid packet length\n') help_quit(parser) if args.threads < 1: print('Invalid number of threads\n') help_quit(parser) # Temporary open a netmap descriptor to get some info about # number of involved rings or the specific ring couple involved d = netmap.NetmapDesc(args.interface) if d.getflags() in [netmap.RegAllNic, netmap.RegNicSw]: max_couples = min(len(d.receive_rings), len(d.transmit_rings)) if d.getflags() == netmap.RegAllNic: max_couples -= 1 ringid_offset = 0 suffix_required = True else: max_couples = 1 ringid_offset = d.getringid() suffix_required = False del d if args.threads > max_couples: print('You cannot use more than %s (tx,rx) rings couples with "%s"' % (max_couples, args.interface))
#!/usr/bin/env python # Written by Vincenzo Maffione <v.maffione AT gmail DOT com> import netmap import time # open a netmap interface and register desc = netmap.NetmapDesc('netmap:enp2s0f1') while 1: print('Waiting for a packet to come') # sync RX rings with kernel desc.rxsync() # scan all the receive rings rxr = None for r in desc.receive_rings: if r.head != r.tail: # At least one packet has been received on # this ring rxr = r break if rxr == None: # no packets received on the rings, let's sleep a bit time.sleep(1) continue # slot pointed by rxr.head has been received