[ipsec][strongswan] strongswan源码分析--(一)SA整体分析
strongswan SA分析(一)
1 概念
下面主要介绍两个本文将要阐述的核心概念。他们是SA和SP。注意,这不是一篇不需要背景知识的文章。作者认为你适合阅读接下来内容的的前提是,你已经具备了一下三方面的知识:
- a. 什么是VPN。
- b. 什么是IPsec,包括IKE,ESP,strongswan都是什么等。
- c. 一般的linux使用方法和常见概念。
1.1 什么是SAD,SPD
SAD是Security Association Database的缩写。
SPD是Security Policy Database的缩写。
SAD是用来存储SA的数据库。SPD是用来存储SP的数据库。
1.2 什么是SPI
SPI是Security Parameter Index的缩写。是有一组数字(长度?)。被使用在SAD和SPD里作为索引的一部分。是由IKE协商的两侧客户端随机选择的UUID?。0-255是被保留的值,禁止在SPI中使用。
1.3 什么是SA
SA是Security Association的缩写。SA是一组算法和算法参数(包括key)的集合,用来完成单个方向的数据流加密和验证任务。通过SPI加数据包的目的地址可以唯一查找到一个SA。
包含的属性:
- 加密算法
- 属性
- key
- 验证算法
- 属性
- key
- SPI
- 目的地址
1.4 什么是SP
SP是Security Policy的缩写。SP是一条规则,决定一条流(flow)是否需要被IPsec处理。SP的处理有三种方式:
- 丢弃
- 不处理
- 处理
需要被IPsec处理的流,会被指向到一个template。一个template可以理解为指向一个SA,template包含以下属性:
- 协议
- AH或ESP。
- 模式
- transport或tunnel模式。
- pattern
- 源IP加目的IP对。
- NAT的PORT对。
SP有一个方向属性,取值分别为:
- out
- in
- fwd
1.5 总结
在整个IPsec的数据流转逻辑中,SP用来表达What todo。SA用来表达How todo。
2 数据流
简单的说。明文报在通过IPsec VPN设备变成ESP发出去的过程是:
- 查找路由。
- 查找policy决定是否需要被ESP
- 查找SA并加密封装。
- 加密封装后的包再查路由。
IPsec报在通过IPsec VPN设备变成非加密包发出去的过程:
- 查找路由。
- 查找policy决定是否需要要解ESP
- 查找SA并解密解封装。
- 解密解封装后的包再查路由。
2.1 举个栗子
路由
[root@T9 sbin]# ip route
default via 192.168.7.1 dev eth0 proto static metric 100
10.129.0.0/24 dev eth1 proto kernel scope link src 10.129.0.1 metric 100
192.168.7.0/24 dev eth0 proto kernel scope link src 192.168.7.129 metric 100
policy
[root@T9 sbin]# ip xfrm policy
src 10.9.0.0/16 dst 10.129.0.0/16
dir fwd priority 383616 ptype main
tmpl src 192.168.7.9 dst 192.168.7.129
proto esp reqid 1 mode tunnel
src 10.9.0.0/16 dst 10.129.0.0/16
dir in priority 383616 ptype main
tmpl src 192.168.7.9 dst 192.168.7.129
proto esp reqid 1 mode tunnel
src 10.129.0.0/16 dst 10.9.0.0/16
dir out priority 383616 ptype main
tmpl src 192.168.7.129 dst 192.168.7.9
proto esp reqid 1 mode tunnel
sa
[root@T9 sbin]# ip xfrm state
src 192.168.7.129 dst 192.168.7.9
proto esp spi 0xc42ac7f3 reqid 1 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x5f7b99e.....eb20948fb2f8fc713caf2d43b4 128
enc cbc(aes) 0x48144872d5f4f9a6a762b68785e6f265
src 192.168.7.9 dst 192.168.7.129
proto esp spi 0xc1c8ad99 reqid 1 mode tunnel
replay-window 32 flag af-unspec
auth-trunc hmac(sha256) 0x7efc5d2172.....0c0dedf053b0b6ae5aa2f012 128
enc cbc(aes) 0x808efcfaa45a543b69efe08158accaa3
3 理解linux kernel中的sa概念和管理
3.1 提供给用户的sa接口
理解kernel sa对用户展示的形态,可以帮助我们理解linux kernel对于ipsec sa的建模和抽象。对我们在VPN产品的sa模块设计中将提供帮助。
3.1.1 使用racoon配置sa
setkey add 192.168.0.1 192.168.1.2 esp 0x10001
-m tunnel
-E des-cbc 0x3ffe05014819ffff
-A hmac-md5 "authentication!!"
从以上信息可以很容易开始各个参数表达的含义,其中-E代表加密算法和它的key,-A代表验证算法和它的key。0x10001为spi。
3.1.2 使用racoon配置policy
setkey spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any
-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require
第一行代表五元组,any代表协议。第二行代表policy的具体描述:方向,action,template。
3.1.3 总结
通过以上两个小节的描述,读者应该已经很容易的总结出了配置一个SA和一个policy所需要提供的最基本的信息了。作者将在本章的最后,对sa和poliyc所包含的所有必须信息进行一个统一的总结。
另外,通过上文的语法,我们应该能够发现,policy与sa之间的match操作,是需要一个稍负责的匹配逻辑来实现的,而不仅仅是一个简单的匹配关系。
3.2 netlink的SA接口
strongswan是目前使用两种方式与内核进行ipsec的配置交互,分别为netlink和pfkey。如官方文档所述,netlink是strongswan默认启用的,变成stable的接口方式。整个调研工作也是以netlink方式为出发点展开的,现简单介绍如下。
3.2.1 什么是netlink
netlink是复用了socket方式的内核与用户态IPC方法。
这里有一篇写的非常好的文章,讲netlink为什么会产生。由于人家写的实在是太好了,我已经没有什么可写的了,只能做个概要,如下:
因为作者图画是业余的,所以看懂的这个概要图的前提是,你必须懂得BSD socket的api如何使用。
3.2.2 接口方式
用netlink方式配置ipsec的方法。
netlink的一般用法
初始化socket
与常规的socket用法相同,只是传入参数是netlink定义的特有参数。
int socket(int domain, int type, int protocol)
bind(fd, (struct sockaddr*)&nladdr, sizeof(nladdr));
下发配置信息到kernel
使用socket的标准send,write接口将特定格式的参数下发给kernel。
参数格式如下:
struct nlmsghdr
{
__u32 nlmsg_len; /* Length of message */
__u16 nlmsg_type; /* Message type*/
__u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process PID */
};
这个参数结构体是传入参数的头部,紧接着这个头部之后的内存是真正的参数的值。它的解析方法由nlmsg_type的值来确定。它的结尾由nlmsg_len的数值来决定。
添加sa
添加sa的时候,nlmsghdr后面的参数为结构体
struct xfrm_usersa_info
nlmsg_type的值为:XFRM_MSG_NEWSA
这部分内容定义在系统文件下:
/usr/include/linux/xfrm.h
这个结构体后边,还需要追加算法部分的信息,如下:
struct xfrm_algo
struct xfrm_algo_auth
添加policy
添加policy的时候,nlmsghdr后面的参数为结构体
struct xfrm_userpolicy_info
nlmsg_type的值为:XFRM_MSG_NEWPOLICY
这部分内容定义在系统文件下:
/usr/include/linux/xfrm.h
3.3 xfrm的SA接口
3.3.1 什么是xfrm
xfrm(transform)是一个IP包转发框架。主要实现以下三部分功能:
- IPsec protocol suite
- IP Payload Compression Protocol
- Mobile IPv6
3.3.2 内核代码
linux/net/xfrm/
主要函数
Xfrm_lookup() xfrm lookup(SPD and SAD) method
Xfrm_input() xfrm processing for an ingress packet
Xfrm_output() xfrm processing for an egress packet
Xfrm4_rcv() IPv4 specific Rx method
Xfrm6_rcv() IPv6 specific Rx method
Esp_input() ESP processing for an ingress packet
Esp_output() ESP processing for an egress packet
Ah_output() AH processing for an ingress packet
Ah_input() ESP processing for an egress packet
xfrm_policy_alloc() allocates an SPD object
Xfrm_policy_destroy() frees an SPD object
xfrm_ policy_lookup SPD lookup
xfrm_policy_byid() SPD lookup based on id
Xfrm_policy_insert() Add an entry to SPD
Xfrm_Policy_delete() remove an entry from SPD
Xfrm_bundle_create() creates a xfrm bundle
Xfrm_policy_delete() releases the resources of a policy object
Xfrm_state_add() add an entry to SAD
Xfrm_state_delete() free and SAD object
Xfrm_state_alloc() allocate an SAD object
xfrm_state_lookup_byaddr() src address based SAD lookup
xfrm_state_find() SAD look up based on dst
xfrm_state_lookup() SAD lookup based on spi
3.3.3 API
api文件
include/uapi/linux/xfrm.h
主要的API
XFRM_MSG_NEWSA To add a new SA to SAD
XFRM_MSG_DELSA To delete a new SA to SAD
XFRM_MSG_GETSA To get a new SA to SAD
XFRM_MSG_FLUSHSA To flush SAD
XFRM_MSG_NEWPOLICY To add a new policy to SPD
XFRM_MSG_DELPOLICY To delete a new policy to SPD
XFRM_MSG_GETPOLICY To get a new policy to SPD
XFRM_MSG_FLUSHPOLICY To flush SPD
3.3.4 sa的传入参数
struct xfrm_usersa_info {
struct xfrm_selector sel; // 被加密网段?为啥要有这个?
struct xfrm_id id; // 目的ip,spi,协议ah/esp
xfrm_address_t saddr; // 源ip
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
struct xfrm_stats stats;
__u32 seq;
__u32 reqid;
__u16 family;
__u8 mode; // transport / tunnel
__u8 replay_window;
__u8 flags;
};
算法参数是追加在SA结构体之后的内存块,根据不同的类型决定不同的结构。示例:
struct xfrm_algo {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
char alg_key[0];
};
struct xfrm_algo_auth {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
unsigned int alg_trunc_len; /* in bits */
char alg_key[0];
};
3.3.5 policy的传入参数
struct xfrm_userpolicy_info {
struct xfrm_selector sel; //网段:ip,port,协议
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
__u32 priority; //
__u32 index;
__u8 dir; //方向:in out fwd
__u8 action; // allow, block
__u8 flags;
__u8 share;
};
4 xfrm的实现
4.1 用于存储sa的内部数据结构
struct xfrm_state {
#ifdef CONFIG_NET_NS
struct net *xs_net;
#endif
union {
struct hlist_node gclist;
struct hlist_node bydst;
};
struct hlist_node bysrc;
struct hlist_node byspi;
atomic_t refcnt;
spinlock_t lock;
struct xfrm_id id;
struct xfrm_selector sel;
struct xfrm_mark mark;
u32 tfcpad;
u32 genid;
/* Key manager bits */
struct xfrm_state_walk km;
/* Parameters of this state. */
struct {
u32 reqid;
u8 mode;
u8 replay_window;
u8 aalgo, ealgo, calgo;
u8 flags;
u16 family;
xfrm_address_t saddr;
int header_len;
int trailer_len;
u32 extra_flags;
} props;
struct xfrm_lifetime_cfg lft;
/* Data for transformer */
struct xfrm_algo_auth *aalg;
struct xfrm_algo *ealg;
struct xfrm_algo *calg;
struct xfrm_algo_aead *aead;
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap;
/* Data for care-of address */
xfrm_address_t *coaddr;
/* IPComp needs an IPIP tunnel for handling uncompressed packets */
struct xfrm_state *tunnel;
/* If a tunnel, number of users + 1 */
atomic_t tunnel_users;
/* State for replay detection */
struct xfrm_replay_state replay;
struct xfrm_replay_state_esn *replay_esn;
/* Replay detection state at the time we sent the last notification */
struct xfrm_replay_state preplay;
struct xfrm_replay_state_esn *preplay_esn;
/* The functions for replay detection. */
struct xfrm_replay *repl;
/* internal flag that only holds state for delayed aevent at the
* moment
*/
u32 xflags;
/* Replay detection notification settings */
u32 replay_maxage;
u32 replay_maxdiff;
/* Replay detection notification timer */
struct timer_list rtimer;
/* Statistics */
struct xfrm_stats stats;
struct xfrm_lifetime_cur curlft;
struct tasklet_hrtimer mtimer;
/* used to fix curlft->add_time when changing date */
long saved_tmo;
/* Last used time */
unsigned long lastused;
/* Reference to data common to all the instances of this
* transformer. */
const struct xfrm_type *type;
struct xfrm_mode *inner_mode;
struct xfrm_mode *inner_mode_iaf;
struct xfrm_mode *outer_mode;
/* Security context */
struct xfrm_sec_ctx *security;
/* Private data of this transformer, format is opaque,
* interpreted by xfrm_type methods. */
void *data;
};
会被插入两个hash表
1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
2. Hash table by (daddr,family,reqid) to find what SAs exist for given
destination/tunnel endpoint. (output)
4.2 用于存储sa的内部数据结构
struct xfrm_policy {
#ifdef CONFIG_NET_NS
struct net *xp_net;
#endif
struct hlist_node bydst;
struct hlist_node byidx;
/* This lock only affects elements except for entry. */
rwlock_t lock;
atomic_t refcnt;
struct timer_list timer;
struct flow_cache_object flo;
atomic_t genid;
u32 priority;
u32 index;
struct xfrm_mark mark;
struct xfrm_selector selector;
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
struct xfrm_policy_walk_entry walk;
struct xfrm_policy_queue polq;
u8 type;
u8 action;
u8 flags;
u8 xfrm_nr;
u16 family;
struct xfrm_sec_ctx *security;
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
};
4.3 数据结构之间的存储结构
TODO
4.4 关键函数
xfrm_lookup()
xfrm_output()
xfrm4_policy_check() // 在ipv4中被调用。
5 strongswan中的sa
5.1 概述
从IKE协议的角度上,有两个SA,一个叫IKE_SA,一个叫CHILD_SA。本章讨论的sa,特指下图中的CHILD_SA。
本篇文章,通篇讨论的SA指的都是这里的CHILD_SA。
CHILD_SA在strongswan的框架里,主要存在与两个部分。
- IKE协商过程。
CHILD_SA是IKE协商过程中的输出。IKE协商过程结束后,IKE-SA Manager将CHILD_SA交个strongswan框架。 - IPsec隧道建立过程。
CHILD_SA是IKE协商过程中的输入。strongswan框架将CHILD_SA交给libcharon plugin由特定的plugin与kernel通信,在kernel中完成IPsec tunnel的建立过程。 - IPsec在转发过程。
这部分和strongswan的框架没有了关系,由内核完成。
+---------------------------------+ +----------------------------+
| Credentials | | Backends |
+---------------------------------+ +----------------------------+
+------------+ +-----------+ +------+ +----------+
| receiver | | | | | +------+ | CHILD_SA |
+----+-------+ | Scheduler | | IKE- | | IKE- |--+----------+
| | | | SA |--| SA | | CHILD_SA |
+-------+--+ +-----------+ | | +------+ +----------+
<->| socket | | | Man- |
+-------+--+ +-----------+ | ager | +------+ +----------+
| | | | | | IKE- |--| CHILD_SA |
+----+-------+ | Processor |--------| |--| SA | +----------+
| sender | | | | | +------+
+------------+ +-----------+ +------+
+---------------------------------+ +----------------------------+
| Bus | | Kernel Interface |
+---------------------------------+ +----------------------------+
| | |
+-------------+ +-------------+ V
| File-Logger | | Sys-Logger | //////
+-------------+ +-------------+
5.1.1 strongswan中的plugin
上一小节提到了plugin,接下来讲解plugin。
有两类plugins。一类是libstrongswan的plugin,一类是libcharon的plugin。
libstrongswan的plugin主要提供加密,认证,数据库相关的功能。
libcharon的plugin主要提供“specific needs”。。。我们接下来要讨论的与sa下发相关的plugin都在
libcharon这一类里。他们包括:
- kernel-libipsec
用户态的转发平面,目前还处于高实验性阶段。转发性能没有kernel。主要用来满足不能使用kernel转发的场景。 - kernel-netlink
使用netlink接口与linux kernel的xfrm模块交互。目前输出稳定使用阶段,默认首选。 - kernel-iph
windows操作系统的接口。 - kernel-pfkey
使用pkkey接口与linux kernel的xfrm模块进行交互,高实验性阶段。 - kernel-wfp
windows操作系统的接口。
本文,只关心kernel-netlink的plugin。
5.2 启动过程
5.2.1 概述
strongswan的启动方式有多种。可以和各种不同的系统对接,包括systemd,networkmanager等。
- starter
ipsec命令使用的守护进程。用ipsec start命令,就会启动这个进程。 - charon-nm
networkmanager的plugin。什么是nm的plugin? - charon-systemd
按照systemd的daemon style实现的一个进程。由systemd启动。 - charon-svc
windows的服务。
各种启动方式的最终目的都是启动最终目的都是启动charon进程。所以,最简的启动方法就是:
- 直接运行charon进程
当然,这种方式没有daemon守护,但是功能完整。
5.2.2 调试方法
如上一小节所述。charon进程可以直接运行。所以调试的时候直接使用gdb运行charon就可以了。
# gdb `which charon`
5.2.3 starter的启动过程
starter的启动方法是通过ipsec脚本执行start命令,这样便启动了strongswan服务。
# ipsec start
ipsec脚本
源码位置
strongswan-5.7.1/src/ipsec/_ipsec
ipsec脚本解析start参数后,会执行如下命令,启动daemon进程starter
${IPSEC_DIR}/starter --daemon charon
starter进程
源码位置
strongswan-5.7.1/src/starter/starter.c
starter的主要功能是启动charon进程,并进行守护。
- daemon的初始工作
重定向输出,signal响应等。 - 启动charon
- 加载ipsec.conf中的配置。
流程图
charon进程
charon进程运行启动成功后,启动16个子线程执行不同的job。
整个charon中的任务调度围绕着task和job两个核心概念进行。
流程图
实线代表流程图;虚线代表调用栈。
5.2.4 systemd的启动过程
systemd的启动过程首先使用systemd的service配置脚本。然后启动systemd的charon守护进程。
最后通过守护进程启动charon进程。
systemd脚本
源码位置
strongswan-5.7.1/init/systemd-swanctl/strongswan-swanctl.service.in
service脚本在启动过程执行两个操作。
- 启动charon-systemd进程。
- 执行swanctl --load-all --noprompt命令
charon-systemd进程
源码位置
strongswan-5.7.1/src/charon-systemd/charon-systemd.c
charon-systemd进程是charon进程的另一个入口。charon-systemd进程不会在启动新的进程,charon-systemed进程就是处理业务的主进程,有systemd进行守护。
所以,charon-systemd只有main函数中的少量内容与charon不同。其他逻辑与charon进程完全相同。
流程图
5.3 调用过程
运行过程中,与SA相关的两个部分主要就是add_sa与add_policy两个地方。
当charon进程收到一个message的时候,会以job的形式分发给standby的业务线程进行处理。
最后通过kernel对象调用kernel_interface接口中的add_sa和add_policy两个函数。接口会根据
具体注册的plugin调用各plugin的相应,add_as, add_policy函数。
例如,netlink的plugin。
在该plugin的这两个函数中,会通过netlink的接口最终调用内核的xfrm接口完成sa和policy的下发和更新等操作。
详见3.2和3.3两个章节。
5.4 数据结构
strongswan中的sa数据结构
定义在文件 kernel_ipsec.h 中,由id和data两个结构共同组成。
struct kernel_ipsec_sa_id_t {
/** Source address */
host_t *src;
/** Destination address */
host_t *dst;
/** SPI */
uint32_t spi;
/** Protocol (ESP/AH) */
uint8_t proto;
/** Optional mark */
mark_t mark;
};
/**
* Data required to add an SA to the kernel
*/
struct kernel_ipsec_add_sa_t {
/** Reqid */
uint32_t reqid;
/** Mode (tunnel, transport...) */
ipsec_mode_t mode;
/** List of source traffic selectors */
linked_list_t *src_ts;
/** List of destination traffic selectors */
linked_list_t *dst_ts;
/** Network interface restricting policy */
char *interface;
/** Lifetime configuration */
lifetime_cfg_t *lifetime;
/** Encryption algorithm */
uint16_t enc_alg;
/** Encryption key */
chunk_t enc_key;
/** Integrity protection algorithm */
uint16_t int_alg;
/** Integrity protection key */
chunk_t int_key;
/** Anti-replay window size */
uint32_t replay_window;
/** Traffic Flow Confidentiality padding */
uint32_t tfc;
/** IPComp transform */
uint16_t ipcomp;
/** CPI for IPComp */
uint16_t cpi;
/** TRUE to enable UDP encapsulation for NAT traversal */
bool encap;
/** no (disabled), yes (enabled), auto (enabled if supported) */
hw_offload_t hw_offload;
/** Mark the SA should apply to packets after processing */
mark_t mark;
/** TRUE to use Extended Sequence Numbers */
bool esn;
/** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */
bool copy_df;
/** TRUE to copy the ECN header field to/from the outer header */
bool copy_ecn;
/** Whether to copy the DSCP header field to/from the outer header */
dscp_copy_t copy_dscp;
/** TRUE if initiator of the exchange creating the SA */
bool initiator;
/** TRUE if this is an inbound SA */
bool inbound;
/** TRUE if an SPI has already been allocated for this SA */
bool update;
};
strongswan中的policy数据结构
定义在文件 kernel_ipsec.h 和 ipsec_types.h 中。
struct kernel_ipsec_policy_id_t {
/** Direction of traffic */
policy_dir_t dir;
/** Source traffic selector */
traffic_selector_t *src_ts;
/** Destination traffic selector */
traffic_selector_t *dst_ts;
/** Optional mark */
mark_t mark;
/** Network interface restricting policy */
char *interface;
};
/**
* Data required to add/delete a policy to/from the kernel
*/
struct kernel_ipsec_manage_policy_t {
/** Type of policy */
policy_type_t type;
/** Priority class */
policy_priority_t prio;
/** Manually-set priority (automatic if set to 0) */
uint32_t manual_prio;
/** Source address of the SA(s) tied to this policy */
host_t *src;
/** Destination address of the SA(s) tied to this policy */
host_t *dst;
/** Details about the SA(s) tied to this policy */
ipsec_sa_cfg_t *sa;
};
struct ipsec_sa_cfg_t {
/** mode of SA (tunnel, transport) */
ipsec_mode_t mode;
/** unique ID */
uint32_t reqid;
/** number of policies of the same kind (in/out/fwd) attached to SA */
uint32_t policy_count;
/** details about ESP/AH */
struct {
/** TRUE if this protocol is used */
bool use;
/** SPI for ESP/AH */
uint32_t spi;
} esp, ah;
/** details about IPComp */
struct {
/** the IPComp transform used */
uint16_t transform;
/** CPI for IPComp */
uint16_t cpi;
} ipcomp;
};
6 sa的抽象模型
6.1 实现sa管理的思路
略。
6.2 sa
目的地址(dip)加 spi 唯一确定一个sa条目。
属性 | 取值 | 说明 |
---|---|---|
id | ||
spi | 协商过程带过来的 | |
mode | transport/tunnel | |
protocol | esp/ah/ipcom | 加密协议的方式 |
sip | 另一条隧道是sip和dip互换的,故两个sa | |
dip | ||
life | 生存时间 | |
enc_alg | ||
enc_key | ||
integrity_alg | 完整性验证 | |
integrity_key | ||
nat | 是否做nat |
6.3 policy
属性 | 取值 | 说明 |
---|---|---|
id | ||
action | drop/pass/ipsec | 命中此策略后的行为 |
priority | 优先级 | |
dir | in/out/fwd | 方向 |
s_ts | source traffic selector | |
d_ts | destination traffic selector |
6.4 traffic selector
ts就是五元组,ip使用掩码掩起来的一个段。port也可以掩,具体跟kernel学一下。
属性 | 说明 |
---|---|
source ip | |
sip_prefixlen | |
dest ip | |
dip_prefixlen | |
sport | |
sport_mask | |
dport | |
dport_mask | |
protocol |
7 问题
7.1 policy与路由的关系
在我的测试虚机环境里,删掉了策略路由之后,功能正常。
目前还不清楚为什么。路由与policy之间的关系,以及路由和policy在内核包转发过程中的逻辑关系,
都需要进一步的调研。
7.2 policy与sa之间的关联逻辑
参考
http://man7.org/linux/man-pages/man8/ip-xfrm.8.html
[ipsec][strongswan] strongswan源码分析--(一)SA整体分析的更多相关文章
- dubbo源码分析一:整体分析
本文作为dubbo源码分析的第一章,先从总体上来分析一下dubbo的代码架构.功能及优缺点,注意,本文只分析说明开源版本提供的代码及功能. 1.dubbo的代码架构: spring适配层:常规的sp ...
- [dev][ipsec][dpdk] strongswan/dpdk源码分析之ipsec算法配置过程
1 简述 storngswan的配置里用一种固定格式的字符串设置了用于协商的预定义算法.在包协商过程中strongswan将字符串转换为固定的枚举值封在数据包里用于传输. 协商成功之后,这组被协商选中 ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看
catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...
- [软件测试]网站压测工具Webbench源码分析
一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...
- SDL2源码分析2:窗体(SDL_Window)
===================================================== SDL源码分析系列文章列表: SDL2源码分析1:初始化(SDL_Init()) SDL2源 ...
- 网站(Web)压测工具Webbench源码分析
一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...
- ifconfig源码分析之与内核交互数据
<ifconfig源码分析之与内核交互数据>本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝.转载,转载时请保持文档的完整性.参考资料:<Linux设备驱动 ...
- 并发-ConcurrentHashMap源码分析
ConcurrentHashMap 参考: http://www.cnblogs.com/chengxiao/p/6842045.html https://my.oschina.net/hosee/b ...
随机推荐
- docker安装并运行ngnix
拉取nginx最新版本的镜像: [mall@VM_0_7_centos ~]$ sudo docker pull nginx:latest [sudo] password for mall: late ...
- Ubuntu安装sysv-rc-conf配置开机启动服务
ubuntu下chkconfig的替代方案: 第一步:在终端键入sudo apt-get install sysv-rc-conf安装sysv-rc-conf服务. 第二步:检查设置系统开机自启动服务 ...
- easyui datagrid 中序列化后的日期格式化
1.在easyui datagrid 中序列化后的日期显示为:/Date(1433377800000)/ 2.格式化后的显示为: 2015-06-04 08:30:00 3.使用代码如下: 3.1. ...
- LeetCode:复原IP地址【93】
LeetCode:复原IP地址[93] 题目描述 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 示例: 输入: "25525511135" 输出: [&qu ...
- sql多列值一行显示
select stuff(( select ',' + UserNM from tblSysUser for xml path('')), 1,1,'')
- nodepad++格式化html代码
如果没有安装插件
- 永久解决Sublime包管理package control 打开install package报错 There are no packages available for installation
很多用户在使用sumblime安装插件的时候,打开package control的install package会出现报错:There are no packages available for in ...
- 【vim小记】vim的高效移动
我还是推荐所有刚入门vim的朋友先去用vimtutor练习,然后去看vim的帮助文档,写的十分仔细,而且可以马上实战,见效很快,以下的很多示意图都是vim帮助文档里的例子,我觉得很好,就拿出来了. v ...
- LeetCode 503. 下一个更大元素 II(Next Greater Element II)
503. 下一个更大元素 II 503. Next Greater Element II 题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 ...
- LeetCode 201. 数字范围按位与(Bitwise AND of Numbers Range)
201. 数字范围按位与 201. Bitwise AND of Numbers Range 题目描述 给定范围 [m, n],其中 0 <= m <= n <= 214748364 ...