📄 ipratemon.cc
字号:
c->fwd_and_rev_rate.freq(), c->fwd_and_rev_rate.scale); ret += "\t"; ret += cp_unparse_real2(c->fwd_and_rev_rate.average(1) * c->fwd_and_rev_rate.freq(), c->fwd_and_rev_rate.scale); ret += "\n"; if (c->next_level) ret += print(c->next_level, "\t" + this_ip); } } return ret;}StringIPRateMonitor::look_read_handler(Element *e, void *){ IPRateMonitor *me = (IPRateMonitor*) e; String ret = String(MyEWMA::now() - me->_resettime) + "\n"; if (me->_lock->attempt()) { ret = ret + me->print(me->_base); me->_lock->release(); return ret; } else { return ret + "unavailable\n"; }}StringIPRateMonitor::thresh_read_handler(Element *e, void *){ IPRateMonitor *me = (IPRateMonitor *) e; return String(me->_thresh);}StringIPRateMonitor::mem_read_handler(Element *e, void *){ IPRateMonitor *me = (IPRateMonitor *) e; return String(me->_alloced_mem) + "\n";}StringIPRateMonitor::memmax_read_handler(Element *e, void *){ IPRateMonitor *me = (IPRateMonitor *) e; return String(me->_memmax) + "\n";}intIPRateMonitor::reset_write_handler(const String &, Element *e, void *, ErrorHandler *){ IPRateMonitor* me = (IPRateMonitor *) e; me->_lock->acquire(); for (int i = 0; i < Stats::MAX_COUNTERS; i++) { if (me->_base->counter[i]) { if (me->_base->counter[i]->next_level) delete me->_base->counter[i]->next_level; delete me->_base->counter[i]; me->_base->counter[i] = 0; } } me->set_resettime(); me->_lock->release(); return 0;}intIPRateMonitor::memmax_write_handler(const String &conf, Element *e, void *, ErrorHandler *errh){ Vector<String> args; cp_argvec(conf, args); IPRateMonitor* me = (IPRateMonitor *) e; if (args.size() != 1) { errh->error("expecting 1 integer"); return -1; } int memmax; if (!cp_integer(args[0], &memmax)) { errh->error("not an integer"); return -1; } if (memmax && memmax < (int)MEMMAX_MIN) memmax = MEMMAX_MIN; me->_lock->acquire(); me->_memmax = memmax * 1024; // count bytes, not kbytes // Fold if necessary if (me->_memmax && me->_alloced_mem > me->_memmax) me->forced_fold(); me->_lock->release(); return 0;}intIPRateMonitor::anno_level_write_handler(const String &conf, Element *e, void *, ErrorHandler *errh){ Vector<String> args; cp_argvec(conf, args); IPRateMonitor* me = (IPRateMonitor *) e; IPAddress a; int level, when; if (args.size() != 3) { errh->error("expecting 3 arguments"); return -1; } if (!cp_ip_address(args[0], &a)) { errh->error("not an IP address"); return -1; } if (!cp_integer(args[1], &level) || !(level >= 0 && level < 4)) { errh->error("2nd argument specifies a level, between 0 and 3, to annotate"); return -1; } if (!cp_integer(args[2], &when) || when < 1) { errh->error("3rd argument specifies when this rule expires, must be > 0"); return -1; } when *= MyEWMA::freq(); when += MyEWMA::now(); me->_lock->acquire(); unsigned addr = a.addr(); me->set_anno_level(addr, static_cast<unsigned>(level), static_cast<unsigned>(when)); me->_lock->release(); return 0;}voidIPRateMonitor::add_handlers(){ add_read_handler("thresh", thresh_read_handler, 0); add_read_handler("look", look_read_handler, 0); add_read_handler("mem", mem_read_handler, 0); add_read_handler("memmax", memmax_read_handler, 0); add_write_handler("anno_level", anno_level_write_handler, 0); add_write_handler("reset", reset_write_handler, 0); add_write_handler("memmax", memmax_write_handler, 0);}intIPRateMonitor::llrpc(unsigned command, void *data){ if (command == CLICK_LLRPC_IPRATEMON_LEVEL_FWD_AVG || command == CLICK_LLRPC_IPRATEMON_LEVEL_REV_AVG) { // Data : int data[256] // Incoming : data[0] is the level to drill down; 0 is top level, // values between 0 and 3 inclusive are valid // data[1] is the network-byte-order IP address to drill down // on; it is irrelevant if data[0] == 0 // data[2..255] are ignored // Outgoing : If there is no data at that level, returns -EAGAIN. // If there is data at that level, then puts the forward // or reverse rate for each of the 256 buckets at that level // into data[]. If a bucket has no rate, puts -1 into that // element of data[]. int which = (command == CLICK_LLRPC_IPRATEMON_LEVEL_FWD_AVG ? 0 : 1); unsigned *udata = (unsigned *)data; unsigned level, ipaddr; if (CLICK_LLRPC_GET(level, udata) < 0) return -EFAULT; if (CLICK_LLRPC_GET(ipaddr, udata + 1) < 0) return -EFAULT; if (level > 3) return -EINVAL; int averages[256]; _lock->acquire(); // ipaddr is in network order Stats *s = _base; ipaddr = ntohl(ipaddr); for (int bitshift = 24; bitshift > 0 && level > 0; bitshift -= 8, level--) { unsigned char b = (ipaddr >> bitshift) & 255; if (!s->counter[b] || !s->counter[b]->next_level) { _lock->release(); return -EAGAIN; } s = s->counter[b]->next_level; } unsigned freq = MyEWMA::freq(); unsigned scale = MyEWMA::scale; for (int i = 0; i < 256; i++) { if (s->counter[i]) { s->counter[i]->fwd_and_rev_rate.update_time(); averages[i] = (s->counter[i]->fwd_and_rev_rate.average(which) * freq) >> scale; } else averages[i] = -1; } _lock->release(); return CLICK_LLRPC_PUT_DATA(data, averages, sizeof(averages)); } else if (command == CLICK_LLRPC_IPRATEMON_FWD_N_REV_AVG) { // Data : int data[9] // Incoming : data[0] is the network-byte-order IP address to drill down // on. data[1...8] are ignored. // Outgoing : data[0] specifies how many level of rates are returned. for // example, if user request data for 18.26.4.10, and only rates // upto 18.26.4 is available, returns 3. data[1...9] contain // rates, starting with the highest order byte (e.g. 18). unsigned *udata = (unsigned *)data; unsigned ipaddr; if (CLICK_LLRPC_GET(ipaddr, udata) < 0) return -EFAULT; int averages[9]; int n = 0; _lock->acquire(); // ipaddr is in network order Stats *s = _base; ipaddr = ntohl(ipaddr); for (int bitshift = 24; bitshift >= 0; bitshift -= 8) { unsigned char b = (ipaddr >> bitshift) & 255; if (!s->counter[b]) break; unsigned freq = s->counter[b]->fwd_and_rev_rate.freq(); unsigned scale = s->counter[b]->fwd_and_rev_rate.scale; s->counter[b]->fwd_and_rev_rate.update_time(); averages[n*2+1] = (s->counter[b]->fwd_and_rev_rate.average(0) * freq) >> scale; averages[n*2+2] = (s->counter[b]->fwd_and_rev_rate.average(1) * freq) >> scale; n++; if (!s->counter[b]->next_level) break; s = s->counter[b]->next_level; } _lock->release(); averages[0] = n; return CLICK_LLRPC_PUT_DATA(data, averages, sizeof(averages)); } else if (command == CLICK_LLRPC_IPRATEMON_SET_ANNO_LEVEL) { // Data : int data[3] // Incoming : data[0] is the network-byte-order IP address. data[1] is the // level at which annotations and expansion should stop. // data[2] is the duration of this rule. // Outgoing : nada. unsigned *udata = (unsigned *)data; unsigned ipaddr, level, when; if (CLICK_LLRPC_GET(ipaddr, udata) < 0) return -EFAULT; if (CLICK_LLRPC_GET(level, udata+1) < 0 || level > 3) return -EFAULT; if (CLICK_LLRPC_GET(when, udata+2) < 0 || when < 1) return -EFAULT; when *= MyEWMA::freq(); when += MyEWMA::now(); _lock->acquire(); set_anno_level(ipaddr, static_cast<unsigned>(level), static_cast<unsigned>(when)); _lock->release(); return 0; } else return Element::llrpc(command, data);}EXPORT_ELEMENT(IPRateMonitor)ELEMENT_REQUIRES(userlevel)// template instances#include <click/ewma.cc>CLICK_ENDDECLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -