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发出去的过程是:

  1. 查找路由。
  2. 查找policy决定是否需要被ESP
  3. 查找SA并加密封装。
  4. 加密封装后的包再查路由。

IPsec报在通过IPsec VPN设备变成非加密包发出去的过程:

  1. 查找路由。
  2. 查找policy决定是否需要要解ESP
  3. 查找SA并解密解封装。
  4. 解密解封装后的包再查路由。

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的框架里,主要存在与两个部分。

  1. IKE协商过程。

    CHILD_SA是IKE协商过程中的输出。IKE协商过程结束后,IKE-SA Manager将CHILD_SA交个strongswan框架。
  2. IPsec隧道建立过程。

    CHILD_SA是IKE协商过程中的输入。strongswan框架将CHILD_SA交给libcharon plugin由特定的plugin与kernel通信,在kernel中完成IPsec tunnel的建立过程。
  3. 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脚本在启动过程执行两个操作。

  1. 启动charon-systemd进程。
  2. 执行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整体分析的更多相关文章

  1. dubbo源码分析一:整体分析

    本文作为dubbo源码分析的第一章,先从总体上来分析一下dubbo的代码架构.功能及优缺点,注意,本文只分析说明开源版本提供的代码及功能. 1.dubbo的代码架构:  spring适配层:常规的sp ...

  2. [dev][ipsec][dpdk] strongswan/dpdk源码分析之ipsec算法配置过程

    1 简述 storngswan的配置里用一种固定格式的字符串设置了用于协商的预定义算法.在包协商过程中strongswan将字符串转换为固定的枚举值封在数据包里用于传输. 协商成功之后,这组被协商选中 ...

  3. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  4. PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看

    catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...

  5. [软件测试]网站压测工具Webbench源码分析

    一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...

  6. SDL2源码分析2:窗体(SDL_Window)

    ===================================================== SDL源码分析系列文章列表: SDL2源码分析1:初始化(SDL_Init()) SDL2源 ...

  7. 网站(Web)压测工具Webbench源码分析

    一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...

  8. ifconfig源码分析之与内核交互数据

    <ifconfig源码分析之与内核交互数据>本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝.转载,转载时请保持文档的完整性.参考资料:<Linux设备驱动 ...

  9. 并发-ConcurrentHashMap源码分析

    ConcurrentHashMap 参考: http://www.cnblogs.com/chengxiao/p/6842045.html https://my.oschina.net/hosee/b ...

随机推荐

  1. docker安装并运行ngnix

    拉取nginx最新版本的镜像: [mall@VM_0_7_centos ~]$ sudo docker pull nginx:latest [sudo] password for mall: late ...

  2. Ubuntu安装sysv-rc-conf配置开机启动服务

    ubuntu下chkconfig的替代方案: 第一步:在终端键入sudo apt-get install sysv-rc-conf安装sysv-rc-conf服务. 第二步:检查设置系统开机自启动服务 ...

  3. easyui datagrid 中序列化后的日期格式化

    1.在easyui datagrid 中序列化后的日期显示为:/Date(1433377800000)/ 2.格式化后的显示为: 2015-06-04 08:30:00 3.使用代码如下: 3.1. ...

  4. LeetCode:复原IP地址【93】

    LeetCode:复原IP地址[93] 题目描述 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 示例: 输入: "25525511135" 输出: [&qu ...

  5. sql多列值一行显示

    select stuff(( select ',' + UserNM from tblSysUser for xml path('')), 1,1,'')

  6. nodepad++格式化html代码

    如果没有安装插件

  7. 永久解决Sublime包管理package control 打开install package报错 There are no packages available for installation

    很多用户在使用sumblime安装插件的时候,打开package control的install package会出现报错:There are no packages available for in ...

  8. 【vim小记】vim的高效移动

    我还是推荐所有刚入门vim的朋友先去用vimtutor练习,然后去看vim的帮助文档,写的十分仔细,而且可以马上实战,见效很快,以下的很多示意图都是vim帮助文档里的例子,我觉得很好,就拿出来了. v ...

  9. LeetCode 503. 下一个更大元素 II(Next Greater Element II)

    503. 下一个更大元素 II 503. Next Greater Element II 题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 ...

  10. LeetCode 201. 数字范围按位与(Bitwise AND of Numbers Range)

    201. 数字范围按位与 201. Bitwise AND of Numbers Range 题目描述 给定范围 [m, n],其中 0 <= m <= n <= 214748364 ...