ipsec 加密流程(一):ipsec策略匹配
《openswan》专栏系列文章主要是记录openswan源码学习过程中的笔记。
- Author : Toney
- Email : [email protected]
- Date : 2020.11.22
- Copyright : 未经同意不得转载!!!
- Version : openswan-2.6.51.5
- Reference:https://download.openswan.org/openswan/
目录
1. ipsec策略匹配流程(ipsec_tunnel_start_xmit)
1. ipsec策略匹配流程(ipsec_tunnel_start_xmit)
注:openswan源码中的ipsec是在内核中实现的,因此代码中很多时大多是内核相关的接口。
1.1 创建ipsec发送状态:ixs
函数名 | ipsec_xmit_state_new() |
作用 | 创建ipsec发送状态结构 |
- openswan源码中使用了内存池方式来申请内存
- openswan实现是在内核空间中,可以通过此接口实现流控功能。当ixs申请数量超过阈值时,关闭发送队列:netif_stop_queue(); 等队列中的报文发送后再开启队列上层可以继续往队列中发送数据包。
1.2 ipsec出接口正确性检查
函数名 | ipsec_xmit_sanity_check_ipsec_dev() |
作用 | 检查ixs出接口相关参数 |
在ipsec_xmit_state_new()成功创建完毕ixs后,会将dev结构存储到ixs上。而ipsec_xmit_sanity_check_ipsec_dev()则是检查此出接口dev是否已经确定:如果未确定则返回失败,停止ipsec加密操作;如果出接口已经确定,则将出接口MTU值存储在ixs上。
ixs->physmtu = ixs->physdev->mtu; |
ixs->cur_mtu = ixs->physdev->mtu; |
1.3 网络数据包skb正确性检查
函数名 | ipsec_xmit_sanity_check_skb() |
作用 | 检查skb报文相关参数 |
- 检查是否支持IPv6
- 检查是否支持IP头部选项字段
1.4 检查报文中是否封装了二层头
函数名 | ipsec_tunnel_strip_hard_header() |
作用 | 检查报文中是否包含二层头 |
Sk_buf结构:
|-------------|-------------------------|---------------|
Head data tail end
如果ixs->iph - ixs->skb->data > 0, 则说明已经封装了二层头。
- 如果报文中没有包含二层头,则:
ixs->hard_header_stripped = 1; |
ixs->hard_header_len = ixs->physdev->hard_header_len; |
1.5 根据报文五元组查询IPSec SA
函数名 | ipsec_tunnel_SAlookup() |
作用 | 报文五元组查询eroute、IPSEC SA |
- 从报文中提取:源IP、目的IP、Proto、源端口、目的端口、以及协议族构成matcher结构
- 根据matcher查询eroute路由表
- 将报文中的端口号存储到ixs结构上
- ixs->sport
- ixs->dport
- 构建ixs->outgoing_said
-
设置outgoing_said默认值
- ixs->outgoing_said.proto = IPPROTO_INT; /*内部使用的协议类型*/
- ixs->outgoing_said.spi = htonl(SPI_DROP);
- ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
-
略过本地外发的IKE协商报文
- ixs->outgoing_said.spi = htonl(SPI_PASS);
- bypass = TRUE;
-
处理未被略过的报文(bypass==FALSE && ixs->eroute)
- Outgoing_said从eroute上的said获取到ipsec sa信息
- 填充ixs->ips.ips_ident_d
- 填充ixs->ips.ips_ident_s
至此,ipsec报文匹配ipsec策略流程基本完成,后续便是根据匹配的ipsecsa进行报文封装。后面介绍使用状态机实现的ipsec加密流程。