ImageVerifierCode 换一换
格式:DOCX , 页数:9 ,大小:17.95KB ,
资源ID:5918796      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5918796.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(linux协议栈之网桥实现之一.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

linux协议栈之网桥实现之一.docx

1、linux协议栈之网桥实现之一linux协议栈之网桥实现之一 网卡驱动最个函数netif_receive_skb.就从说起。 简单起见,去掉里面预编译代码int netif_receive_skb(struct sk_buff *skb)(net/core/dev.c) struct packet_type *ptype, *pt_prev; int ret = NET_RX_DROP; unsigned short type; /打接收时间戳 if (!skb->stamp.tv_sec) net_timestamp(&skb->stamp); /如果存dev->m

2、aster。则更新相应指针 skb_bond(skb); /更新CPU接收统计数据 _get_cpu_var(netdev_rx_stat).total+; skb->h.raw = skb->nh.raw = skb->data; skb->mac_len = skb->nh.raw - skb->mac.raw; pt_prev = NULL; rcu_read_lock(); /处理所有协议模块 list_for_each_entry_rcu(ptype, &ptype_all, list) if (!ptype->dev | ptype

3、->dev = skb->dev) if (pt_prev) ret = deliver_skb(skb, pt_prev);pt_prev = ptype; /分片处理 handle_diverter(skb); /网桥处理 if (handle_bridge(&skb, &pt_prev, &ret) goto out; type = skb->protocol; /协议调相应模块处理。 list_for_each_entry_rcu(ptype, &ptype_basentohs(type)&15, list) if (ptype

4、->type = type && (!ptype->dev | ptype->dev = skb->dev) if (pt_prev) ret = deliver_skb(skb, pt_prev);pt_prev = ptype; if (pt_prev) ret = pt_prev->func(skb, skb->dev, pt_prev); else kfree_skb(skb); /* Jamal, now you will not able to escape explaining * me how you were going t

5、o use this. :-) */ ret = NET_RX_DROP; out: rcu_read_unlock(); return ret;此函数主完成分片重组,网桥处理,根据不同协议调不同传输层处理模块。本节重点概述linux网桥实现处理。传输层协议分层续章节陆续给出。进入网桥处理代码:#if defined(CONFIG_BRIDGE) | defined (CONFIG_BRIDGE_MODULE) (net/core/dev.c)int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff *pskb)

6、;static _inline_ int handle_bridge(struct sk_buff *pskb, struct packet_type *pt_prev, int *ret) struct net_bridge_port *port; /回环接口?非以太网接口? if (*pskb)->pkt_type = PACKET_LOOPBACK | (port = rcu_dereference(*pskb)->dev->br_port) = NULL) return 0; if (*pt_prev) *ret = deliver_skb(*pskb, *pt_pr

7、ev); *pt_prev = NULL; / br_handle_frame_hook个全局函数指针 return br_handle_frame_hook(port, pskb);#else#define handle_bridge(skb, pt_prev, ret) (0)#endif从此以看出。如果编译时候选择网桥模式,则进入网桥处理模块,否则,只个空函数,直接返回。br_handle_frame_hook代表函数什么呢?网桥数据处理框架又什么样呢?关于网桥:网桥个二层设备,深入以当成个二层交换机。二层协议转发数据。网桥转发数据,维持个端口MAC应表,通常通CAM表。根据这张表以数据

8、送往相应端口进行发送.网桥转发过程:1:接收个包。判断自己CAM表否含包此包源地址.如果没有,则源地址端口更新至于CAM表.2:判断包否送给本机,如果,则送往本机层协议栈处理。如果不,则查寻CAM表。找相应出口。3:如果找出口,则此包送至出口。如果不存,各端口发送。4:如果CAM表应表项规定时间没有得更新,则除此项。网桥配置:Brctl个比较好配置网桥工具。源代码配置极其简单。们从网桥配置流程说起,看linux核怎样步步管理。首先,创建个网桥: brctl addbr br0 (建立个br0网桥)然,接口添加进网桥:brctl addifbr0 eth0 (eth0eth1添加进网桥br0)

9、brctl addif bro eth1OK,网桥现就配置好。这台linux主机以当作交换机使,从eth0包都以转发eth1。现,们看代码进行处理首先 brctl addbr 。查看brctl代码调:ioctl(br_socket_fd, SIOCBRADDBR, brname);然 brctl addifbrctl代码调:ioctl(br_socket_fd, SIOCBRADDIF, &ifr);呵呵。Brctl代码简单吧,只调户空间配置工具ioctl.Linux网桥分析:好,现就以进入核分析网桥模式:static int _init br_init(void)(net/brige

10、/br.c) /分配slab缓冲区 br_fdb_init();/网桥netfiter处理,以章节分析#ifdef CONFIG_BRIDGE_NETFILTER if (br_netfilter_init() return 1;#endif /户空间ioctl调函数 brioctl_set(br_ioctl_deviceless_stub); /接收数据包处理,就们面netif_receive_skb函数看br_handle_frame_hook br_handle_frame_hook = br_handle_frame;#if defined(CONFIG_ATM_LANE) | def

11、ined(CONFIG_ATM_LANE_MODULE) br_fdb_get_hook = br_fdb_get; br_fdb_put_hook = br_fdb_put;#endif /netdev_chain通知链表注册。关于通知链表,面已经介绍过,这里不再讨论 register_netdevice_notifier(&br_device_notifier); return 0;新建网桥:从面分析以知道,户空间调ioctl(br_socket_fd, SIOCBRADDBR, brname).进入br_ioctl_deviceless_stub,以看相关处理:int br_io

12、ctl_deviceless_stub(unsigned int cmd, void _user *uarg) switch (cmd) case SIOCGIFBR: case SIOCSIFBR: return old_deviceless(uarg); /新建网桥 case SIOCBRADDBR: /除网桥 case SIOCBRDELBR: char bufIFNAMSIZ; if (!capable(CAP_NET_ADMIN)return -EPERM; /copy_from_user:户空间数据拷入核空间 if (copy_from_user(buf, uarg, IFNAMS

13、IZ)return -EFAULT; bufIFNAMSIZ-1 = 0; if (cmd = SIOCBRADDBR)return br_add_bridge(buf); return br_del_bridge(buf); return -EOPNOTSUPP; 这里,们传入cmdSIOCBRADDBR.转入br_add_bridge(buf)进行:int br_add_bridge(const char *name) struct net_device *dev; int ret; /虚拟桥新建个net_device /面“网络设备管理”经讲述此结构 dev = new_bridge_d

14、ev(name); if (!dev) return -ENOMEM;/sysfs建立相关信息 ret = br_sysfs_addbr(dev); dev_put(dev); if (ret) unregister_netdev(dev);out: return ret;err2: free_netdev(dev);err1: rtnl_unlock(); goto out;网桥注册跟们以看物理网络设备注册样。们关心网桥应net_device结构什么样,继续跟踪进new_bridge_dev:static struct net_device *new_bridge_dev(const cha

15、r *name) struct net_bridge *br; struct net_device *dev; /分配net_device dev = alloc_netdev(sizeof(struct net_bridge), name, br_dev_setup); if (!dev) return NULL; 网桥私区结构net_bridge br = netdev_priv(dev); /私区结构dev字段指向本身 br->dev = dev; br->lock = SPIN_LOCK_UNLOCKED; /队列始化。port_list保存这个桥端口列表 INIT_LIS

16、T_HEAD(&br->port_list); br->hash_lock = SPIN_LOCK_UNLOCKED; /面这部份代码跟stp协议相关,们暂不关心 br->bridge_id.prio0 = 0x80; br->bridge_id.prio1 = 0x00; memset(br->bridge_id.addr, 0, ETH_ALEN); dev->open = br_dev_open; dev->set_multicast_list = br_dev_set_multicast_list; dev->change_mtu

17、 = br_change_mtu; dev->destructor = free_netdev; SET_MODULE_OWNER(dev); dev->stop = br_dev_stop; dev->accept_fastpath = br_dev_accept_fastpath; dev->tx_queue_len = 0; dev->set_mac_address = NULL; dev->priv_flags = IFF_EBRIDGE;这部份,桥设备私区空间进行始化。这里,有必给桥net_device应私区结构:struct net_bridge

18、 /读锁 spinlock_tlock; /端口列表 struct list_head port_list; /网桥应虚拟设备 struct net_device*dev; /网桥应虚拟网卡统计数据 struct net_device_stats statistics; /hash表锁 spinlock_thash_lock; /MAC PORT应表,即CAM struct hlist_head hashBR_HASH_SIZE; struct list_head age_list;/* STP */u16 root_port;rtnl_lock();br->stp_enabled =

19、0;br_stp_timer_init(br);return dev;/stp 协议应数据unsigned char stp_enabled;/由核确定接口名字,例如eth0 eth1等br->designated_root = br->bridge_id;bridge_id designated_root;unsigned char topology_change;if (strchr(dev->name, %) br->root_path_cost = 0;br_dev_setup还做些另函数指针始化:bridge_idbridge_id;ret = dev_all

20、oc_name(dev, dev->name);br->root_port = 0;void br_dev_setup(struct net_device *dev)u32 root_path_cost;if (ret < 0)br->bridge_max_age = br->max_age = 20 * HZ;unsigned long max_age;goto err1;br->bridge_hello_time = br->hello_time = 2 * HZ;/桥MAC地址设零unsigned long hello_time;br->b

21、ridge_forward_delay = br->forward_delay = 15 * HZ;memset(dev->dev_addr, 0, ETH_ALEN);unsigned long forward_delay;/向核注册此网络设备br->topology_change = 0;/以太网结构始化unsigned long bridge_max_age;ret = register_netdevice(dev);br->topology_change_detected = 0;ether_setup(dev);unsigned long ageing_tim

22、e;if (ret)br->ageing_time = 300 * HZ;/系列函数指针始化unsigned long bridge_hello_time;goto err2;INIT_LIST_HEAD(&br->age_list);dev->do_ioctl = br_dev_ioctl;unsigned long bridge_forward_delay;dev_hold(dev);dev->get_stats = br_dev_get_stats; rtnl_unlock(); dev->hard_start_xmit = br_dev_xmit; unsigned char topology_change_detected;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1