[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在內核包轉發過程中的邏輯關系,
都需要進一步的調研。
浙公網安備 33010602011771號