// -*- mode: c++; c-basic-offset: 4 -*- /* * fromhost.{cc,hh} -- element steals packets from kernel * Luigi Rizzo * * Copyright (c) 2001 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #include #include #include "fromhost.hh" #include #include #include #include #include #include static AnyDeviceMap fromhost_map; FromHost::FromHost() : _inq(0) { } FromHost::~FromHost() { } int FromHost::configure(Vector &conf, ErrorHandler *errh) { _burst = 8; // same as in FromDevice if (cp_va_parse(conf, this, errh, cpString, "interface name", &_devname, cpEnd) < 0 ) { printf ("FromHost 1\n"); return -1; } if (find_device(false, &fromhost_map, errh) < 0) return -1; return 0; } int FromHost::initialize(ErrorHandler *errh) { // create queue int s = splimp(); if (device()->if_poll_xmit != NULL) { splx(s); click_chatter("FromHost: %s%d already in use", device()->if_name, device()->if_unit); return -1; } (FromHost *)(device()->if_poll_xmit) = this; _inq = (struct ifqueue *) malloc(sizeof (struct ifqueue), M_DEVBUF, M_NOWAIT|M_ZERO); assert(_inq); _inq->ifq_maxlen = QSIZE; ScheduleInfo::initialize_task(this, &_task, true, errh); splx(s); return 0; } void FromHost::cleanup(CleanupStage) { if (!_inq) return; // Flush the receive queue. int s = splimp(); struct ifqueue *q = _inq ; _inq = NULL; device()->if_poll_xmit = NULL; splx(s); int i, max = q->ifq_maxlen ; for (i = 0; i < max; i++) { struct mbuf *m; IF_DEQUEUE(q, m); if (!m) break; m_freem(m); } free(q, M_DEVBUF); } bool FromHost::run_task() { int npq = 0; // click_chatter("FromHost::run_task()."); while (npq < _burst) { struct mbuf *m = 0; IF_DEQUEUE(_inq, m); if (m == NULL) { return npq > 0; } // Got an mbuf, including the MAC header. Make it a real Packet. Packet *p = Packet::make(m); output(0).push(p); npq++; } #if CLICK_DEVICE_ADJUST_TICKETS adjust_tickets(npq); #endif _task.fast_reschedule(); return true; } ELEMENT_REQUIRES(AnyDevice bsdmodule) EXPORT_ELEMENT(FromHost)