中联绿盟信息技术公司成立于2000年3月,是国内专业从事网络安全服务的高科技企业,其前身为国内最著名的网络安全组织“绿色兵团”。网站内容涉及安全技术的方方面面,其绿盟月刊是质量很高的免费安全信息资源
COAST小组是美国Purdue大学一个专门从事于网络安全的研究小组,他们的主页收集了全世界各地的安全资源,其Hotlist是全世界最全的安全链接资源之一
国家信息中心信息安全处的官方主页,提供安全杂志《网络安全》。这里有非常全面的安全法规的资源,包括国家法规、地方法规、中国信息安全技术标准以及信息技术安全标准目录
参考此文:
(1)
http://tech.ccidnet.com/art/302/20070225/1024733_1.html
网卡驱动--->netif_rx()--->netif_receive_skb()->deliver_skb()->packet_type.func
在函数
int netif_receive_skb(struct sk_buff *skb)
中会执行网桥部分功能:
handle_bridge的代码如下
#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
int (*br_handle_frame_hook)(struct net_bridge_port *p, struct
sk_buff **pskb);
struct net_bridge;
struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge
*br,
void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
static __inline__ int handle_bridge(struct sk_buff **pskb,
本来以为网桥上大多数应该是forward的报文,但是发现网桥启动后,会首先Deliver报文,而且
报文的dev->name是br0,至今还未想通是怎么回事,混沌之中。。。。
今晚跟踪了下报文的dev->name在br_netfilter中的变化过程,发现:
(1)在网络还没有通之前,处理顺序是
br_nf_pre_routing======>br_handle_frame_finish
这个过程,报文的dev->name一直是它的来源名称,不变,为Eth0或者eth1
(2)网络通了之后
br_nf_pre_routing(eth1)==>setup_pre_routing(eth1->br0)==>br_nf_pre_routing_finish(br0->eth1)==>br_handle_frame_finish
不理解的有两点:
第一:一开始那个deliver的报文是谁发的,有什么用?
第二:现在flood基本上不管用。。。跟预期不一致。。。
需要继续阅读br_netfilter的代码
看样子我理解的有问题,eth1,eth2和eth0都加入br0网桥中,eth0连接到笔记本,直连线连接。
eth2和eth1连接到hub,开启stp,否则会死机环路。
从本子ping www.126.com时
一开始网络未通时,一直delivering....应该是代码中的广播发送。
网络通了后,就是single forward.
回头看看代码,再次修正下理解。
刚才又试了下,不开启stp确实很严重啊,立马死机 eth1->eth2狂发,不停止
从功能上说,网桥就是一个智能的HUB,具有地址学习功能。
用最普通的话语来说,它就是一个信使,能跟各个网段或者网口(这里,我们把隶属于某个网桥的所有接口叫port或者网桥的接口)通讯。
这样说,有N个网口eth0, eth1,eth2。。。ethN组成了个网桥叫br0,这个时候br0就拥有了跟这N个网口直接通讯的能力,而且br0又被独立抽象出来为一个网络设备,它的名字就叫br0.
当然,对于每个隶属于br0的网口,此时就具有了特殊的功能,不是普通的网口,不具有IP地址了,因为网桥是在二层工作的一个模块,但是该网口上的所有操作函数,在二层还是有效的。
网桥虽然绑定了一个虚拟的网络设备br0,但是在实际意义上却没有完全的驱动程序,不过有一点还是需要记住的,就是每个网桥在发送数据包时,网桥代码为它专门开发了一个发送接口br_dev_xmit.这个函数赋值给了网卡驱动程序中的hard_start_xmit接口,完成数据的发送。这里有一点,我的理解可能不对,就是:
网桥在实际中发送数据的操作是很少的,它大多数是转发数据,因为网桥是一个类似HUB的咚咚,HUB的工作原理是,来一个报文,就把它复制多份,发送到每个接口上去。而网桥比HUB
以后方便翻阅。
//cme_hook.c
#include
<linux/module.h>
#include <linux/kernel.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netfilter_arp.h>
#include <linux/in_route.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/route.h>
#define STR_IP(str, n) sprintf((str), '%u.%u.%u.%u', (n)
static unsigned int cme_hook(unsign
前几天很傻乎乎的每次修改完bridge的代码,总是删掉map和img文件,然后重新编译内核。浪费了太多时间。
今天发现bridge是编译成模块的,也就是说它不是编译进内核的img文件中的,因此bridge的修改与map和文件是无关的。这样修改桥代码就不需要重新编译内核,而只需要重新编译bridge那部分代码生成新的ko文件就行。
方法如下:
首先在原来的系统上编译一遍内核源码2.6.18.8,在/lib/modules目录下就生成了2.6.18.8的内核模块,包括驱动等好多咚咚。重启进入2.6.18.8的内核环境。
这个时候如果你发现bridge的功能不是你想要的或者想做一些修改,那么这是一件很easy的事情了。
假设你的源代码在编译的时候放在/usr/src/linux-2.6.18.8下
首先,进入net/bridge目录下修改你要改变的功能代码。
然后执行
make -C /lib/modules/2.6.18.8/build/ M=/usr/src/linux/net/bridge
命令,就会自动编译了,因为在bridge目录下,Makefile都已经生成好了。
然后把bridge.ko拷贝到/lib/modules/2.6.18.8/kernel/net/bridge/目录下,就OK了
这时,你就可以调用brctl命令来测试你的bridge功能了。
l
上篇文章中提到的问题始终没解决,只好怀疑是不是内核版本太高引起的,于是换了2.6.10的试试,发现还是不行,又发现编译出来的不是SMP的内核,我却用的是SMP的config文件,正好在网上看到一篇编译成功的帖子,就照着实践了下,成功了!不过网桥的修改2.6.29的代码直接拿到2.61.8编译不过去,还得对应修改过来,具体编译过程如下:
我的系统环境为AS4 2.6.9-5EL.
1):首先需要的软件包和内核源码如下:
module-init-tools-3.2.tar.bz2
下载地址:http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2
2.6.18的内核源码
虚拟机出问题时查找资料添加 enforcing =0解决掉了。
真实的系统编译后之后,重启报错:
mount :error 2 mounting ext3
mount:error 2 mounting none
switchroot:mount failed:22
umount/initird/dev failed:2
kernel panic-not syncing: atlempted to kill init!
在http://linux.chinaunix.net/bbs/viewthread.php?tid=777152
看到说要把ext3编译进内核,而不是模块方式或者不编译,这样试了,但是还是不行。
还没检查SCSI驱动是否编译进去了。晚上回去试试这个:
Device Drivers ---> SCSI device support --->
<*> SCSI device support
<*> SCSI disk support SCSI low-level drivers --->
(1):数据结构添加:
br_private.h中
1):网桥接口 net_bridge_port修改,添加成员
2):网桥结构体 struct net_bridge添加成员
函数修改
修改函数
int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
添加流量统计代码:
int br_dev_xmit(struct sk_buff *skb, struct net_device
*dev)
{