透明网桥是一种即插即用设备,只要把网桥接入局域网,不需要改动硬件和软件,无需设置地址开关,无需装入路由表或参数,网桥就能工作。 透明网桥以混杂方式工作,它接收与之连接的所有LAN传送的每一帧。当一帧到达时,网桥必须决定将其丢弃还是转发。如果要转发,则必须决定发往哪个LAN。这需要通过查询网桥中一张大型散列表里的目的地址而作出决定。该表可列出每个可能的目的地,以及它属于哪一条输出线路(LAN)。在插入网桥之初,所有的散列表均为空。这时若网桥受到一个帧,会采用自学习(self-learning)算法处理收到的帧(这样就逐渐建立起转发表),并且按照转发表把帧转发出去。这种自学习算法的原理并不复杂,若从某个站A发出的帧从接口x进入了某网桥,那么从这个接口出发沿相反方向一定可把一个帧传送到A。所以网桥只要每收到一个帧,就记下其源地址和进入网桥的接口,作为转发表中的一个项目。在建立转发表时是把帧首部中的源地址写在“地址”这一栏的下面。在转发帧时,则是根据收到的帧首部中的目的地址来转发的。这时就把在“地址”栏下面已经记下的源地址当作目的地址,而把记下的进入接口当作转发接口。 如果网络上的每一个站都发送过帧,那么每一个帧的地址最终都会记录在两个网桥的转发表上。 实际上,在网桥的转发表中写入的信息除了地址和接口外,还有帧进入该网桥的时间要登记进入网桥的时间是因为以太网的拓扑可能会经常发生变化,站点也会更换适配器。另外,以太网上的工作站并非总是接通电源的。把每个帧到达网桥的时间登记下来,就可以在转发表中只保留网络拓扑的最新状态信息。具体方法是,网桥中的接口管理软件周期性地扫描转发表中的项目。只要在一定时间以前登记的都要删除。这样就使得网桥中的转发表能反映当前网络的最新拓扑状态。 由此可见,网桥中的转发信息表并非总是包含所有站点的信息。只要某个站点从来都不发送数据,那么在网桥的转发表中就没有这个站点的项目。如果站点A在一段时间内不发送数据,那么在转发表中地址为A的项目就被删除了。 下面是网桥的自学习和转发帧的一般步骤。 网桥收到一帧后先进行自学习。查找转发表中与收到帧的源地址有无相匹配的项目。如果没有,就在转发表中增加一个项目。如果有,则把原有的项目进行更新。 转发帧。查找转发表中与收到帧的源地址有无相匹配的项目。如果没有,则通过所有其他接口进行转发。如果有,则按转发表中给出的接口进行转发。但应注意,若转发表中给出的接口就是该帧进入网桥的接口,则应丢弃这个帧。 逆向学习法 透明网桥采用的算法是逆向学习法(backward learning)。网桥按混杂的方式工作,故它能看见所连接的任一LAN上传送的帧。查看源地址即可知道在哪个LAN上可访问哪台机器,于是在散列表中添上一项。 当计算机和网桥加电、断电或迁移时,网络的拓扑结构会随之改变。为了处理动态拓扑问题,每当增加散列表项时,均在该项中注明帧的到达时间。每当目的地已在表中的帧到达时,将以当前时间更新该项。这样,从表中每项的时间即可知道该机器最后帧到来的时间。网桥中有一个进程定期地扫描散列表,清除时间早于当前时间若干分钟的全部表项。于是,如果从LAN上取下一台计算机,并在别处重新连到LAN上的话,那么在几分钟内,它即可重新开始正常工作而无须人工干预。这个算法同时也意味着,如果机器在几分钟内无动作,那么发给它的帧将不得不散发,一直到它自己发送出一帧为止。 到达帧的路由选择过程取决于发送的LAN(源LAN)和目的地所在的LAN(目的LAN),如下所示: 1、如果源LAN和目的LAN相同,则丢弃该帧。 2、如果源LAN和目的LAN不同,则转发该帧。 3、如果目的LAN未知,则进行扩散。 为了提高可靠性,有人在LAN之间设置了并行的两个或多个网桥,但是,这种配置引起了另外一些问题,因为在拓扑结构中产生了回路,可能引发无限循环。 生成树算法 透明网桥还使用了一个生成树(spanning tree)算法,即互连在一起的网桥在进行彼此通信后,就能找出原来的网络拓扑的一个子集。在这个子集里,整个连通的网络中不存在回路,即在任何两个站之间只有一条路径。 为了得能够反映网络拓扑发生变化时的生成树,在生成树上的根网桥每隔一段时间还要对生成树的拓扑进行更新。 透明网桥的路径选择算法归纳 (1)若目的局域网和源局域网一样,则网桥将该帧删除。 (2)若源局域网和目的局域网是不同的网,则将该帧转发到目的局域网。 (3)若目的局域网不知道,则采用扩散法处理。
tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上。 不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包。 例如: shell> tcpdump -nn -i eth0 icmp 下面是详细的tcpdump用法。 1.1 tcpdump选项 它的命令格式为: tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ] [ -w file ] [ expression ]
生成树协议是一种二层管理协议,它通过有选择性地阻塞网络冗余链路来达到消除网络二层环路的目的,同时具备链路的备份功能。 由于生成树协议本身比较小,所以并不像路由协议那样广为人知。但是它却掌管着端口的转发大权—“小树枝抖一抖,上层协议就得另谋生路”。真实情况也确实如此,特别是在和别的协议一起运行的时候,生成树就有可能断了其他协议的报文通路,造成种种奇怪的现象。 生成树协议和其他协议一样,是随着网络的不断发展而不断更新换代的。本文标题中的“生成树协议”是一个广义的概念,并不是特指IEEE 802.1D中定义的STP协议,而是包括STP以及各种在STP基础上经过改进了的生成树协议。 在生成树协议发展过程中,老的缺陷不断被克服,新的特性不断被开发出来。按照大功能点的改进情况,我们可以粗略地把生成树协议的发展过程划分成三代,下面一一道来。 开天辟地的第一代生成树协议: STP/RSTP 在网络发展初期,透明网桥是一个不得不提的重要角色。它比只会放大和广播信号的集线器聪明得多。它会悄悄把发向它的数据帧的源MAC地址和端口号记录下来,下次碰到这个目的MAC地址的报文就只从记录中的端口号发送出去,除非目的MAC地址没有记录在案或者目的MAC地址本身就是多播地址才会向所有端口发送。通过透明网桥,不同的局域网之间可以实现互通,网络可操作的范围得以扩大,而且由于透明网桥具备MAC地址学习功能而不会像Hub那样造成网络报文冲撞泛滥。
NAPI是Linux新的网卡数据处理API,据说是由于找不到更好的名字,所以就叫NAPI(New API),在2.5之后引入。简单来说,NAPI是综合中断方式与轮询方式的技术。中断的好处是响应及时,如果数据量较小,则不会占用太多的CPU事件;缺点是数据量大时,会产生过多中断,而每个中断都要消耗不少的CPU时间,从而导致效率反而不如轮询高。轮询方式与中断方式相反,它更适合处理大量数据,因为每次轮询不需要消耗过多的CPU时间;缺点是即使只接收很少数据或不接收数据时,也要占用CPU时间。 NAPI是两者的结合,数据量低时采用中断,数据量高时采用轮询。平时是中断方式,当有数据到达时,会触发中断 处理函数执行,中断处理函数关闭中断开始处理。如果此时有数据到达,则没必要再触发中断了,因为中断处理函 数中会轮询处理数据,直到没有新数据时才打开中断。 很明显,数据量很低与很高时,NAPI可以发挥中断与轮询方式的优点,性能较好。如果数据量不稳定,且说高不高 说低不低,则NAPI则会在两种方式切换上消耗不少时间,效率反而较低一些。 来看下NAPI和非NAPI的区别: (1) 支持NAPI的网卡驱动必须提供轮询方法poll()。 (2) 非NAPI的内核接口为netif_rx(),NAPI的内核接口为napi_schedule()。 (3) 非NAPI使用共享的CPU队列softnet_data->input_pkt_queue,NAPI使用设备内存(或者 设备驱动程序的接收环)。 (1) NAPI设备结构 /* Structure for NAPI scheduling similar to tasklet but with weighting */
struct napi_struct {
/* The poll_list must only be managed by the entity which changes the
* state of the NAPI_STATE_SCHED bit. This means whoever atomically
* sets that bit can add this napi_struct to the per-cpu poll_list, and
* whoever clears that bit can remove from the list right before clearing the bit.
/
struct list_head poll_list; / 用于加入处于轮询状态的设备队列 /
unsigned long state; / 设备的状态 /
int weight; / 每次处理的最大数量,非NAPI默认为64 /
int (poll) (struct napi_struct , int); / 此设备的轮询方法,非NAPI为process_backlog() /
#ifdef CONFIG_NETPOLL
…
#endif
unsigned int gro_count;
struct net_device *dev;
struct list_head dev_list;
struct sk_buff *gro_list;
struct sk_buff *skb;
};
(2) 初始化
初始napi_struct实例。
void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
int (poll) (struct napi_struct , int), int weight)
{
INIT_LIST_HEAD(&napi->poll_list);
napi->gro_count = 0;
napi->gro_list = NULL;
napi->skb = NULL;
napi->poll = poll; / 设备的poll函数 /
napi->weight = weight; / 设备每次poll能处理的数据包个数上限 */
list_add(&napi->dev_list, &dev->napi_list); /* 加入设备的napi_list */
napi->dev = dev; /* 所属设备 */ #ifdef CONFIG_NETPOLL
spin_lock_init(&napi->poll_lock);
napi->poll_owner = -1; #endif
set_bit(NAPI_STATE_SCHED, &napi->state); /* 设置NAPI标志位 */ } (3) 调度 在网卡驱动的中断处理函数中调用napi_schedule()来使用NAPI。 /** * napi_schedule - schedule NAPI poll * @n: napi context * Schedule NAPI poll routine to be called if it is not already running. */ static inline void napi_schedule(struct napi_struct *n) {
/* 判断是否可以调度NAPI */
if (napi_schedule_prep(n))
__napi_schedule(n); } 判断NAPI是否可以调度。如果NAPI没有被禁止,且不存在已被调度的NAPI, 则允许调度NAPI,因为同一时刻只允许有一个NAPI poll instance。 /** * napi_schedule_prep - check if napi can be scheduled * @n: napi context * Test if NAPI routine is already running, and if not mark it as running. * This is used as a condition variable insure only one NAPI poll instance runs. * We also make sure there is no pending NAPI disable. */
static inline int napi_schedule_prep(struct napi_struct *n)
{
return !napi_disable_pending(n) && !test_and_set_bit(NAPI_STATE_SCHED, &n->state);
}
static inline int napi_disable_pending(struct napi_struct *n)
{
return test_bit(NAPI_STATE_DISABLE, &n->state);
}
enum {
NAPI_STATE_SCHED, /* Poll is scheduled /
NAPI_STATE_DISABLE, / Disable pending /
NAPI_STATE_NPSVC, / Netpoll - don’t dequeue from poll_list */
};
NAPI的调度函数。把设备的napi_struct实例添加到当前CPU的softnet_data的poll_list中,
Ethereal (Ethereal:A Network Packet Sniffing Tool)是当前较为流行的一种计算机网络调试和数据包嗅探软件。Ethereal 基本类似于tcpdump,但Ethereal 还具有设计完美的 GUI 和众多分类信息及过滤选项。用户通过 Ethereal,同时将网卡插入混合模式,可以查看到网络中发送的所有通信流量。 Ethereal 应用于故障修复、分析、软件和协议开发以及教育领域。它具有用户对协议分析器所期望的所有标准特征,并具有其它同类产品所不具备的有关特征。