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: }
阅读(999) | 评论(0) | 转发(0) |