Chinaunix首页 | 论坛 | 博客
  • 博客访问: 795420
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2012-11-10 11:35:59

L4协议的注册:

位于IPv4之上的L4协议是由net_protocol数据结构定义的

1: struct net_protocol { 2: int (*handler)(struct sk_buff *skb); 3: void (*err_handler)(struct sk_buff *skb, u32 info); 4: int (*gso_send_check)(struct sk_buff *skb); 5: struct sk_buff *(*gso_segment)(struct sk_buff *skb, 6: int features); 7: struct sk_buff **(*gro_receive)(struct sk_buff **head, 8: struct sk_buff *skb); 9: int (*gro_complete)(struct sk_buff *skb); 10: unsigned int no_policy:1, 11: netns_ok:1; 12: };

handler,由此协议注册的函数,来作为送进来的封包的处理函数。

err_handler,由icmp协议处理函数所用的函数,用于通知l4协议有关接收到icmp unreachable消息的时间。

no_policy,此字段在网络协议中的某些关键点都会被查询,用于使协议免于ipsec策略检查:1是指没有必要针对此协议检查ipsec策略。

1: /* 2: * Add a protocol handler to the hash tables 3: */ 4:   5: int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) 6: { 7: int hash, ret; 8:   9: hash = protocol & (MAX_INET_PROTOS - 1); 10:   11: spin_lock_bh(&inet_proto_lock); 12: if (inet_protos[hash]) { 13: ret = -1; 14: } else { 15: inet_protos[hash] = prot; 16: ret = 0; 17: } 18: spin_unlock_bh(&inet_proto_lock); 19:   20: return ret; 21: } 22:   23: /* 24: * Remove a protocol from the hash tables. 25: */ 26:   27: int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) 28: { 29: int hash, ret; 30:   31: hash = protocol & (MAX_INET_PROTOS - 1); 32:   33: spin_lock_bh(&inet_proto_lock); 34: if (inet_protos[hash] == prot) { 35: inet_protos[hash] = NULL; 36: ret = 0; 37: } else { 38: ret = -1; 39: } 40: spin_unlock_bh(&inet_proto_lock); 41:   42: synchronize_net(); 43:   44: return ret; 45: }
 
L3到L4的传递:ip_local_deliver_finish
1: static int ip_local_deliver_finish(struct sk_buff *skb) 2: { 3: struct net *net = dev_net(skb->dev); 4:   5: __skb_pull(skb, ip_hdrlen(skb)); 6:   7: /* Point into the IP datagram, just past the header. */ 8: skb_reset_transport_header(skb); 9:   10: rcu_read_lock(); 11: { 12: int protocol = ip_hdr(skb)->protocol; 13: int hash, raw; 14: const struct net_protocol *ipprot; 15:   16: resubmit: 17: raw = raw_local_deliver(skb, protocol); 18:   19: hash = protocol & (MAX_INET_PROTOS - 1); 20: ipprot = rcu_dereference(inet_protos[hash]); 21: if (ipprot != NULL) { 22: int ret; 23:   24: if (!net_eq(net, &init_net) && !ipprot->netns_ok) { 25: if (net_ratelimit()) 26: printk("%s: proto %d isn't netns-ready\n", 27: __func__, protocol); 28: kfree_skb(skb); 29: goto out; 30: } 31:   32: if (!ipprot->no_policy) { 33: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { 34: kfree_skb(skb); 35: goto out; 36: } 37: nf_reset(skb); 38: } 39: ret = ipprot->handler(skb); 40: if (ret < 0) { 41: protocol = -ret; 42: goto resubmit; 43: } 44: IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); 45: } else { 46: if (!raw) { 47: if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { 48: IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS); 49: icmp_send(skb, ICMP_DEST_UNREACH, 50: ICMP_PROT_UNREACH, 0); 51: } 52: } else 53: IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); 54: kfree_skb(skb); 55: } 56: } 57: out: 58: rcu_read_unlock(); 59:   60: return 0; 61: }
阅读(929) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~