📄 etherswitch.cc
字号:
/* * etherswitch.{cc,hh} -- learning, forwarding Ethernet bridge * John Jannotti * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * * 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 <click/config.h>#include "etherswitch.hh"#include <clicknet/ether.h>#include <click/etheraddress.hh>#include <click/glue.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <click/error.hh>CLICK_DECLSEtherSwitch::EtherSwitch() : _table(AddrInfo(-1, Timestamp())), _timeout(300){}EtherSwitch::~EtherSwitch(){ _table.clear();}intEtherSwitch::configure(Vector<String> &conf, ErrorHandler *errh){ return cp_va_kparse(conf, this, errh, "TIMEOUT", 0, cpSeconds, &_timeout, cpEnd);}voidEtherSwitch::broadcast(int source, Packet *p){ int n = noutputs(); assert((unsigned) source < (unsigned) n); int sent = 0; for (int i = 0; i < n; i++) if (i != source) { Packet *pp = (sent < n - 2 ? p->clone() : p); output(i).push(pp); sent++; } assert(sent == n - 1);}voidEtherSwitch::push(int source, Packet *p){ click_ether* e = (click_ether*) p->data(); int outport = -1; // Broadcast // 0 timeout means dumb switch if (_timeout != 0) { _table.set(EtherAddress(e->ether_shost), AddrInfo(source, p->timestamp_anno())); // Set outport if dst is unicast, we have info about it, and the // info is still valid. EtherAddress dst(e->ether_dhost); if (!dst.is_group()) { if (Table::iterator dst_info = _table.find(dst)) { if (p->timestamp_anno() < dst_info.value().stamp + Timestamp(_timeout, 0)) outport = dst_info.value().port; else _table.erase(dst_info); } } } if (outport < 0) broadcast(source, p); else if (outport == source) // Don't send back out on same interface p->kill(); else // forward output(outport).push(p);}StringEtherSwitch::reader(Element* f, void *thunk){ EtherSwitch* sw = (EtherSwitch*)f; switch ((intptr_t) thunk) { case 0: { StringAccum sa; for (Table::iterator iter = sw->_table.begin(); iter.live(); iter++) sa << iter.key() << ' ' << iter.value().port << '\n'; return sa.take_string(); } case 1: return String(sw->_timeout); default: return String(); }}intEtherSwitch::writer(const String &s, Element *e, void *, ErrorHandler *errh){ EtherSwitch *sw = (EtherSwitch *) e; if (!cp_seconds_as(s, 0, &sw->_timeout)) return errh->error("expected timeout (integer)"); return 0;}voidEtherSwitch::add_handlers(){ add_read_handler("table", reader, 0); add_read_handler("timeout", reader, (void *) 1); add_write_handler("timeout", writer, 0);}EXPORT_ELEMENT(EtherSwitch)CLICK_ENDDECLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -