⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directiplookup.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
	_vport[vport_i].ll_prev = -1;	_vport[vport_i].ll_next = _vport_head;	if (_vport_head >= 0)	    _vport[_vport_head].ll_prev = vport_i;	_vport_head = vport_i;    }    ++_vport[vport_i].refcount;    _rtable[rt_i].vport = vport_i;    for (int i = start; i < end; i++) {	if (_tbl_0_23[i] & 0x8000) {	    // Entries with plen > 24 already there in _tbl_24_31[]!	    int sec_i = (_tbl_0_23[i] & 0x7fff) << 8, sec_start, sec_end;	    if (plen > 24) {		sec_start = prefix & 0xFF;		sec_end = sec_start + (1 << (32 - plen));	    } else {		sec_start = 0;		sec_end = 256;	    }	    for (int j = sec_i + sec_start; j < sec_i + sec_end; j++) {		if (plen > _tbl_24_31_plen[j]) {		    _tbl_24_31[j] = vport_i;		    _tbl_24_31_plen[j] = plen;		} else if (plen < _tbl_24_31_plen[j]) {		    // Skip a sequence of more-specific entries		    if (_tbl_24_31_plen[j] > 24) {			j |= 0x000000ff >> (_tbl_24_31_plen[j] - 24);		    } else {			i |= 0x00ffffff >> _tbl_24_31_plen[j];			break;		    }		} else if (allow_replace) {		    _tbl_24_31[j] = vport_i;		} else {		    // plen == _tbl_24_31_plen[j] -> damn!		    return errh->error("BUG: _tbl_24_31[%08X] collision", j);		}	    }	} else {	    if (plen > _tbl_0_23_plen[i]) {		if (plen > 24) {		    // Allocate a new _tbl_24_31[] entry and populate it		    assert(!(_tbl_24_31_empty_head & 0x8000));		    int sec_i = _tbl_24_31_empty_head << 8;		    _tbl_24_31_empty_head = _tbl_24_31[sec_i];		    int sec_start = prefix & 0xFF;		    int sec_end = sec_start + (1 << (32 - plen));		    for (int j = 0; j < 256; j++) {			if (j >= sec_start && j < sec_end) {			    _tbl_24_31[sec_i + j] = vport_i;			    _tbl_24_31_plen[sec_i + j] = plen;			} else {			    _tbl_24_31[sec_i + j] = _tbl_0_23[i];			    _tbl_24_31_plen[sec_i + j] = _tbl_0_23_plen[i];			}		    }		    _tbl_0_23[i] = (sec_i >> 8) | 0x8000;		} else {		    _tbl_0_23[i] = vport_i;		    _tbl_0_23_plen[i] = plen;		}	    } else if (plen < _tbl_0_23_plen[i]) {		// Skip a sequence of more-specific entries		i |= 0x00ffffff >> _tbl_0_23_plen[i];	    } else if (allow_replace) {		_tbl_0_23[i] = vport_i;	    } else {		// plen == _tbl_0_23_plen[i] - must never happen!!!		return errh->error("BUG: _tbl_0_23[%08X] collision", i);	    }	}    }    return 0;}intDirectIPLookup::Table::remove_route(const IPRoute& route, IPRoute* old_route, ErrorHandler *errh){    uint32_t prefix = ntohl(route.addr.addr());    uint32_t plen = route.prefix_len();    int rt_i = find_entry(prefix, plen);    IPRoute found_route;    if (rt_i < 0 || (rt_i == 0 && _vport[0].port == DISCARD_PORT))	return -ENOENT;    found_route = IPRoute(IPAddress(htonl(_rtable[rt_i].prefix)),			  IPAddress::make_prefix(_rtable[rt_i].plen),			  _vport[_rtable[rt_i].vport].gw,			  _vport[_rtable[rt_i].vport].port);    if (!route.match(found_route))	return -ENOENT;    if (old_route)	*old_route = found_route;    if (plen == 0) {	// Default route is a special case.  We never remove it from lookup	// tables, but instead only point it to the "discard port".	if (rt_i > 0)	// Must never happen, checking it just in case...	    return errh->error("BUG: default route rt_i=%d, should be 0", rt_i);	_vport[0].port = DISCARD_PORT;    } else {	uint32_t start, end, i, j, sec_i, sec_start, sec_end;	int newent = -1;	int newmask, prev, next;	vport_unref(_rtable[rt_i].vport);	// Prune our entry from the prefix/len hashtable	prev = _rtable[rt_i].ll_prev;	next = _rtable[rt_i].ll_next;	if (prev >= 0)	    _rtable[prev].ll_next = next;	else	    _rt_hashtbl[prefix_hash(prefix, plen)] = next;	if (next >= 0)	    _rtable[next].ll_prev = prev;	// Add entry to the list of empty _rtable entries	_rtable[rt_i].ll_next = _rt_empty_head;	_rt_empty_head = rt_i;	// Find an entry covering current prefix/len with the longest prefix.	for (newmask = plen - 1 ; newmask >= 0 ; newmask--)	    if (newmask == 0) {		newent = 0;	// rtable[0] is always the default route		break;	    } else {		newent = find_entry(prefix & (0xffffffff << (32 - newmask)),				    newmask);		if (newent > 0)		    break;	    }	// Replace prefix/plen with newent/mask in lookup tables	start = prefix >> 8;	if (plen >= 24)	    end = start + 1;	else	    end = start + (1 << (24 - plen));	for (i = start; i < end; i++) {	    if (_tbl_0_23[i] & 0x8000) {		sec_i = (_tbl_0_23[i] & 0x7fff) << 8;		if (plen > 24) {		    sec_start = prefix & 0xFF;		    sec_end = sec_start + (1 << (32 - plen));		} else {		    sec_start = 0;		    sec_end = 256;		}		for (j = sec_i + sec_start; j < sec_i + sec_end; j++) {		    if (plen == _tbl_24_31_plen[j]) {			_tbl_24_31[j] = _rtable[newent].vport;			_tbl_24_31_plen[j] = newmask;		    } else if (plen < _tbl_24_31_plen[j]) {			// Skip a sequence of more-specific entries			if (_tbl_24_31_plen[j] > 24) {			    j |= 0x000000ff >> (_tbl_24_31_plen[j] - 24);			} else {			    i |= 0x00ffffff >> _tbl_24_31_plen[j];			    break;			}		    } else {			// plen > _tbl_24_31_plen[j] -> damn!			return			  errh->error("BUG: _tbl_24_31[%08X] inconsistency", j);		    }		}		// Check if we can prune the entire secondary table range?		for (j = sec_i ; j < sec_i + 255; j++)		    if (_tbl_24_31_plen[j] != _tbl_24_31_plen[j+1])			break;		if (j == sec_i + 255) {		    // Yup, adjust entries in primary tables...		    _tbl_0_23[i] = _tbl_24_31[sec_i];		    _tbl_0_23_plen[i] = _tbl_24_31_plen[sec_i];		    // ... and free up the entry (adding it to free space list)		    _tbl_24_31[sec_i] = _tbl_24_31_empty_head;		    _tbl_24_31_empty_head = sec_i >> 8;		}	    } else {		if (plen == _tbl_0_23_plen[i]) {		    _tbl_0_23[i] = _rtable[newent].vport;		    _tbl_0_23_plen[i] = newmask;		} else if (plen < _tbl_0_23_plen[i]) {		    // Skip a sequence of more-specific entries		    i |= 0x00ffffff >> _tbl_0_23_plen[i];		}	    }	}    }    return 0;}// DIRECTIPLOOKUPDirectIPLookup::DirectIPLookup(){}DirectIPLookup::~DirectIPLookup(){}intDirectIPLookup::configure(Vector<String> &conf, ErrorHandler *errh){    int r;    if ((r = _t.initialize()) < 0)	return r;    _t.flush();    return IPRouteTable::configure(conf, errh);}voidDirectIPLookup::cleanup(CleanupStage){    _t.cleanup();}voidDirectIPLookup::push(int, Packet *p){    IPAddress gw;    int port = lookup_route(p->dst_ip_anno(), gw);    if (port >= 0) {        if (gw)            p->set_dst_ip_anno(gw);        output(port).push(p);    } else        p->kill();}intDirectIPLookup::lookup_route(IPAddress dest, IPAddress &gw) const{    uint32_t ip_addr = ntohl(dest.addr());    uint16_t vport_i = _t._tbl_0_23[ip_addr >> 8];    if (vport_i & 0x8000)        vport_i = _t._tbl_24_31[((vport_i & 0x7fff) << 8) | (ip_addr & 0xff)];    gw = _t._vport[vport_i].gw;    return _t._vport[vport_i].port;}intDirectIPLookup::add_route(const IPRoute& route, bool allow_replace, IPRoute* old_route, ErrorHandler *errh){    return _t.add_route(route, allow_replace, old_route, errh);}intDirectIPLookup::remove_route(const IPRoute& route, IPRoute* old_route, ErrorHandler *errh){    return _t.remove_route(route, old_route, errh);}intDirectIPLookup::flush_handler(const String &, Element *e, void *,				ErrorHandler *){    DirectIPLookup *t = static_cast<DirectIPLookup *>(e);    t->_t.flush();    return 0;}StringDirectIPLookup::dump_routes(){    return _t.dump();}voidDirectIPLookup::add_handlers(){    IPRouteTable::add_handlers();    add_write_handler("flush", flush_handler, 0, Handler::BUTTON);}CLICK_ENDDECLSELEMENT_REQUIRES(IPRouteTable userlevel|bsdmodule)EXPORT_ELEMENT(DirectIPLookup)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -