博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
L4协议和raw ip处理
阅读量:6861 次
发布时间:2019-06-26

本文共 4068 字,大约阅读时间需要 13 分钟。

hot3.png

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:  }

转载于:https://my.oschina.net/longscu/blog/60642

你可能感兴趣的文章
Enterprise Solution 管理软件开发框架流程实战
查看>>
hibernate缓存机制详细分析
查看>>
Android 动画效果 及 自定义动画
查看>>
基于Servlet、JSP、JDBC、MySQL登录模块(包括使用的过滤器和配置)
查看>>
Python将文本生成二维码
查看>>
统计学习那些事
查看>>
XLT架构图(自己 画的)
查看>>
GitHub Top 100 简介
查看>>
C语言中链表任意位置怎么插入数据?然后写入文件中?
查看>>
文档对象模型DOM(二)
查看>>
loading.io一个loading图标网站,跟大家分享
查看>>
ACM-凸多边形的计算几何——hrbust1429
查看>>
UICollectionView设置item(cell)之间间距为0(紧挨在一起的效果)
查看>>
Atitit.html css 浏览器原理理论概论导论attilax总结
查看>>
求解圆圈中最后剩下的数字
查看>>
jQuery入门第二天
查看>>
boost中的智能指针
查看>>
Windows下Php安装mongodb扩展失败
查看>>
IntelliJ IDEA修改Output输出缓存区大小【应对:too much output to process】
查看>>
html标签的target属性应用
查看>>