- 浏览: 262224 次
- 性别:
- 来自: 吉林
文章分类
最新评论
-
hhb19900618:
你好 请问怎么处理 客户端 socket发送数据超时后的崩溃问 ...
c socket 编程(TCP服务器端代码) -
gar_odie:
挺好的,谢谢露珠
jquery table分页插件 -
a545807638:
...
jquery table分页插件 -
a06062125:
挺好!值得学习
二叉查找树 --c代码 -
a06062125:
只有代码没有讲解 这也算日志
kmp 算法 --转
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
1. 前言
在Linux2.6内核中自带了IPSEC的实现,这样就不用象2.4那样打补丁来实现了。该实现包括以下几个部分: PF_KEY类型套接口, 用来提供和用户层空间进行PF_KEY通信,代码在net/key目录下,前面已经介绍过;安全联盟SA和安全策略SP管理,是使用xfrm库来实现的,代码在net/xfrm/目录下定义;ESP,AH等协议实现,在net/ipv4(6)下定义;加密认证算法库,在crypto目录下定义,这些算法都是标准代码了。本系列文章主要描述XFRM库的实现以及在IPV4下相关协议的处理部分, IPV6的忽略。
本文Linux内核代码版本为2.6.19.2。xfrm是内核中变化比较大的部分,每个版本中都有不小的差异, 同时也说明了该模块的不成熟性。
在net/xfrm目录下的各文件大致功能说明如下:
xfrm_state.c: xfrm状态管理
xfrm_policy.c: xfrm策略管理
xfrm_algo.c: 算法管理
xfrm_hash.c: HASH计算函数
xfrm_input.c: 安全路径(sec_path)处理,用于进入的ipsec包
xfrm_user.c: netlink接口的SA和SP管理
xfrm_policy.c: xfrm策略管理
xfrm_algo.c: 算法管理
xfrm_hash.c: HASH计算函数
xfrm_input.c: 安全路径(sec_path)处理,用于进入的ipsec包
xfrm_user.c: netlink接口的SA和SP管理
在net/ipv4目录下的和ipsec相关各文件大致功能说明如下:
ah4.c: IPV4的AH协议处理
esp4.c: IPV4的ESP协议处理
ipcomp.c: IP压缩协议处理
xfrm4_input: 接收的IPV4的IPSEC包处理
xfrm4_output: 发出的IPV4的IPSEC包处理
xfrm4_state: IPV4的SA处理
xfrm4_policy: IPV4的策略处理
xfrm4_tunnel: IPV4的通道处理
xfrm4_mode_transport: 传输模式
xfrm4_mode_tunnel: 通道模式
xfrm4_mode_beet: BEET模式
esp4.c: IPV4的ESP协议处理
ipcomp.c: IP压缩协议处理
xfrm4_input: 接收的IPV4的IPSEC包处理
xfrm4_output: 发出的IPV4的IPSEC包处理
xfrm4_state: IPV4的SA处理
xfrm4_policy: IPV4的策略处理
xfrm4_tunnel: IPV4的通道处理
xfrm4_mode_transport: 传输模式
xfrm4_mode_tunnel: 通道模式
xfrm4_mode_beet: BEET模式
2. 数据结构
内核SA的定义用xfrm_state结构定义,SP用xfrm_policy结构定义,在include/net/xfrm.h中定义。
2.1 状态(SA)
xfrm_state状态结构用来描述SA在内核中的具体实现:
struct xfrm_state
{
/* Note: bydst is re-used during gc */
// 每个状态结构挂接到三个HASH链表中
struct hlist_node bydst; // 按目的地址HASH
struct hlist_node bysrc; // 按源地址HASH
struct hlist_node byspi; // 按SPI值HASH
{
/* Note: bydst is re-used during gc */
// 每个状态结构挂接到三个HASH链表中
struct hlist_node bydst; // 按目的地址HASH
struct hlist_node bysrc; // 按源地址HASH
struct hlist_node byspi; // 按SPI值HASH
atomic_t refcnt; // 所有使用计数
spinlock_t lock; // 状态锁
spinlock_t lock; // 状态锁
struct xfrm_id id; // ID结构, 即目的地址,SPI,协议三元组
struct xfrm_selector sel; // 状态选择子
struct xfrm_selector sel; // 状态选择子
u32 genid; // 状态的标志值, 防止发生碰撞
/* Key manger bits */
struct {
u8 state;
u8 dying;
u32 seq;
} km; // KEY回调管理处理结构参数
struct {
u8 state;
u8 dying;
u32 seq;
} km; // KEY回调管理处理结构参数
/* Parameters of this state. */
struct {
u32 reqid; // 请求ID
u8 mode; // 模式: 传输/通道
u8 replay_window; // 回放窗口
u8 aalgo, ealgo, calgo; // 认证,加密,压缩算法ID值
u8 flags; // 一些标准
u16 family; // 协议族
xfrm_address_t saddr; // 源地址
int header_len; // 添加的协议头长度
int trailer_len; //
} props; // SA相关参数结构
struct {
u32 reqid; // 请求ID
u8 mode; // 模式: 传输/通道
u8 replay_window; // 回放窗口
u8 aalgo, ealgo, calgo; // 认证,加密,压缩算法ID值
u8 flags; // 一些标准
u16 family; // 协议族
xfrm_address_t saddr; // 源地址
int header_len; // 添加的协议头长度
int trailer_len; //
} props; // SA相关参数结构
struct xfrm_lifetime_cfg lft; // 生存时间配置
/* Data for transformer */
struct xfrm_algo *aalg; // hash算法
struct xfrm_algo *ealg; // 加密算法
struct xfrm_algo *calg; // 压缩算法
struct xfrm_algo *aalg; // hash算法
struct xfrm_algo *ealg; // 加密算法
struct xfrm_algo *calg; // 压缩算法
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap; // NAT-T封装信息
struct xfrm_encap_tmpl *encap; // NAT-T封装信息
/* Data for care-of address */
xfrm_address_t *coaddr;
xfrm_address_t *coaddr;
/* IPComp needs an IPIP tunnel for handling uncompressed packets */
struct xfrm_state *tunnel; // 通道, 实际是另一个SA
struct xfrm_state *tunnel; // 通道, 实际是另一个SA
/* If a tunnel, number of users + 1 */
atomic_t tunnel_users; // 通道的使用数
atomic_t tunnel_users; // 通道的使用数
/* State for replay detection */
struct xfrm_replay_state replay; // 回放检测结构,包含各种序列号掩码等信息
struct xfrm_replay_state replay; // 回放检测结构,包含各种序列号掩码等信息
/* Replay detection state at the time we sent the last notification */
struct xfrm_replay_state preplay; // 上次的回放记录值
struct xfrm_replay_state preplay; // 上次的回放记录值
/* internal flag that only holds state for delayed aevent at the
* moment
*/
u32 xflags; // 标志
* moment
*/
u32 xflags; // 标志
/* Replay detection notification settings */
u32 replay_maxage; // 回放最大时间间隔
u32 replay_maxdiff; // 回放最大差值
u32 replay_maxage; // 回放最大时间间隔
u32 replay_maxdiff; // 回放最大差值
/* Replay detection notification timer */
struct timer_list rtimer; // 回放检测定时器
struct timer_list rtimer; // 回放检测定时器
/* Statistics */
struct xfrm_stats stats; // 统计值
struct xfrm_stats stats; // 统计值
struct xfrm_lifetime_cur curlft; // 当前时间计数器
struct timer_list timer; // SA定时器
struct timer_list timer; // SA定时器
/* Last used time */
u64 lastused; // 上次使用时间
u64 lastused; // 上次使用时间
/* Reference to data common to all the instances of this
* transformer. */
struct xfrm_type *type; // 协议, ESP/AH/IPCOMP
struct xfrm_mode *mode; // 模式, 通道或传输
* transformer. */
struct xfrm_type *type; // 协议, ESP/AH/IPCOMP
struct xfrm_mode *mode; // 模式, 通道或传输
/* Security context */
struct xfrm_sec_ctx *security; // 安全上下文, 加密时使用
struct xfrm_sec_ctx *security; // 安全上下文, 加密时使用
/* Private data of this transformer, format is opaque,
* interpreted by xfrm_type methods. */
void *data; // 内部数据
};
* interpreted by xfrm_type methods. */
void *data; // 内部数据
};
2.2 安全策略(SP)
xfrm_policy结构用于描述SP在内核内部的具体实现:
struct xfrm_policy
{
struct xfrm_policy *next; // 下一个策略
struct hlist_node bydst; // 按目的地址HASH的链表
struct hlist_node byidx; // 按索引号HASH的链表
{
struct xfrm_policy *next; // 下一个策略
struct hlist_node bydst; // 按目的地址HASH的链表
struct hlist_node byidx; // 按索引号HASH的链表
/* This lock only affects elements except for entry. */
rwlock_t lock; // 策略结构锁
atomic_t refcnt; // 引用次数
struct timer_list timer; // 策略定时器
rwlock_t lock; // 策略结构锁
atomic_t refcnt; // 引用次数
struct timer_list timer; // 策略定时器
u8 type; // 类型
u32 priority; // 策略优先级
u32 index; // 策略索引号
struct xfrm_selector selector; // 选择子
struct xfrm_lifetime_cfg lft; // 策略生命期
struct xfrm_lifetime_cur curlft; // 当前的生命期数据
struct dst_entry *bundles; // 路由链表
__u16 family; // 协议族
__u8 action; // 策略动作, 接受/加密/阻塞...
__u8 flags; // 标志
__u8 dead; // 策略死亡标志
__u8 xfrm_nr; // 使用的xfrm_vec的数量
struct xfrm_sec_ctx *security; // 安全上下文
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; // 状态模板
};
u32 priority; // 策略优先级
u32 index; // 策略索引号
struct xfrm_selector selector; // 选择子
struct xfrm_lifetime_cfg lft; // 策略生命期
struct xfrm_lifetime_cur curlft; // 当前的生命期数据
struct dst_entry *bundles; // 路由链表
__u16 family; // 协议族
__u8 action; // 策略动作, 接受/加密/阻塞...
__u8 flags; // 标志
__u8 dead; // 策略死亡标志
__u8 xfrm_nr; // 使用的xfrm_vec的数量
struct xfrm_sec_ctx *security; // 安全上下文
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; // 状态模板
};
xfrm模板结构, 用于状态和策略的查询:
struct xfrm_tmpl
{
/* id in template is interpreted as:
* daddr - destination of tunnel, may be zero for transport mode.
* spi - zero to acquire spi. Not zero if spi is static, then
* daddr must be fixed too.
* proto - AH/ESP/IPCOMP
*/
// SA三元组, 目的地址, 协议, SOI
struct xfrm_id id;
{
/* id in template is interpreted as:
* daddr - destination of tunnel, may be zero for transport mode.
* spi - zero to acquire spi. Not zero if spi is static, then
* daddr must be fixed too.
* proto - AH/ESP/IPCOMP
*/
// SA三元组, 目的地址, 协议, SOI
struct xfrm_id id;
/* Source address of tunnel. Ignored, if it is not a tunnel. */
// 源地址
xfrm_address_t saddr;
// 源地址
xfrm_address_t saddr;
// 请求ID
__u32 reqid;
__u32 reqid;
/* Mode: transport, tunnel etc. */
__u8 mode;
__u8 mode;
/* Sharing mode: unique, this session only, this user only etc. */
__u8 share;
__u8 share;
/* May skip this transfomration if no SA is found */
__u8 optional;
__u8 optional;
/* Bit mask of algos allowed for acquisition */
__u32 aalgos;
__u32 ealgos;
__u32 calgos;
};
__u32 aalgos;
__u32 ealgos;
__u32 calgos;
};
2.3 协议结构
对ESP, AH, IPCOMP等协议的描述是通过xfrm_type结构来描述的, 多个协议的封装就是靠多个协议结构形成的链表来实现:
struct xfrm_type
{
char *description; // 描述字符串
struct module *owner; // 协议模块
__u8 proto; // 协议值
__u8 flags; // 标志
#define XFRM_TYPE_NON_FRAGMENT 1
// 初始化状态
int (*init_state)(struct xfrm_state *x);
// 析构函数
void (*destructor)(struct xfrm_state *);
// 数据输入函数
int (*input)(struct xfrm_state *, struct sk_buff *skb);
// 数据输出函数
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
// 拒绝函数
int (*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
// 头部偏移
int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
// 本地地址
xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
// 远程地址
xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
/* Estimate maximal size of result of transformation of a dgram */
// 最大数据报长度
u32 (*get_max_size)(struct xfrm_state *, int size);
};
{
char *description; // 描述字符串
struct module *owner; // 协议模块
__u8 proto; // 协议值
__u8 flags; // 标志
#define XFRM_TYPE_NON_FRAGMENT 1
// 初始化状态
int (*init_state)(struct xfrm_state *x);
// 析构函数
void (*destructor)(struct xfrm_state *);
// 数据输入函数
int (*input)(struct xfrm_state *, struct sk_buff *skb);
// 数据输出函数
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
// 拒绝函数
int (*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
// 头部偏移
int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
// 本地地址
xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
// 远程地址
xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
/* Estimate maximal size of result of transformation of a dgram */
// 最大数据报长度
u32 (*get_max_size)(struct xfrm_state *, int size);
};
具体的协议结构定义如下, 通常只定义初始化,析构,输入和输出四个成员函数:
AH协议定义
/* net/ipv4/ah4.c */
static struct xfrm_type ah_type =
{
.description = "AH4",
.owner = THIS_MODULE,
.proto = IPPROTO_AH,
.init_state = ah_init_state,
.destructor = ah_destroy,
.input = ah_input,
.output = ah_output
};
AH协议定义
/* net/ipv4/ah4.c */
static struct xfrm_type ah_type =
{
.description = "AH4",
.owner = THIS_MODULE,
.proto = IPPROTO_AH,
.init_state = ah_init_state,
.destructor = ah_destroy,
.input = ah_input,
.output = ah_output
};
ESP协议定义:
/* net/ipv4/esp4.c */
static struct xfrm_type esp_type =
{
.description = "ESP4",
.owner = THIS_MODULE,
.proto = IPPROTO_ESP,
.init_state = esp_init_state,
.destructor = esp_destroy,
.get_max_size = esp4_get_max_size,
.input = esp_input,
.output = esp_output
};
/* net/ipv4/esp4.c */
static struct xfrm_type esp_type =
{
.description = "ESP4",
.owner = THIS_MODULE,
.proto = IPPROTO_ESP,
.init_state = esp_init_state,
.destructor = esp_destroy,
.get_max_size = esp4_get_max_size,
.input = esp_input,
.output = esp_output
};
IP压缩协议定义:
/* net/ipv4/ipcomp.c */
static struct xfrm_type ipcomp_type = {
.description = "IPCOMP4",
.owner = THIS_MODULE,
.proto = IPPROTO_COMP,
.init_state = ipcomp_init_state,
.destructor = ipcomp_destroy,
.input = ipcomp_input,
.output = ipcomp_output
};
/* net/ipv4/ipcomp.c */
static struct xfrm_type ipcomp_type = {
.description = "IPCOMP4",
.owner = THIS_MODULE,
.proto = IPPROTO_COMP,
.init_state = ipcomp_init_state,
.destructor = ipcomp_destroy,
.input = ipcomp_input,
.output = ipcomp_output
};
IPIP协议定义:
/* net/ipv4/xfrm4_tunnel.c */
static struct xfrm_type ipip_type = {
.description = "IPIP",
.owner = THIS_MODULE,
.proto = IPPROTO_IPIP,
.init_state = ipip_init_state,
.destructor = ipip_destroy,
.input = ipip_xfrm_rcv,
.output = ipip_output
};
/* net/ipv4/xfrm4_tunnel.c */
static struct xfrm_type ipip_type = {
.description = "IPIP",
.owner = THIS_MODULE,
.proto = IPPROTO_IPIP,
.init_state = ipip_init_state,
.destructor = ipip_destroy,
.input = ipip_xfrm_rcv,
.output = ipip_output
};
2.4 模式结构
模式结构用于描述IPSEC连接描述, 可为通道模式或传输模式两种:
struct xfrm_mode {
// 数据输入函数
int (*input)(struct xfrm_state *x, struct sk_buff *skb);
// 数据输出函数
int (*output)(struct xfrm_state *x,struct sk_buff *skb);
// 模块指针
struct module *owner;
// 封装
unsigned int encap;
};
// 数据输入函数
int (*input)(struct xfrm_state *x, struct sk_buff *skb);
// 数据输出函数
int (*output)(struct xfrm_state *x,struct sk_buff *skb);
// 模块指针
struct module *owner;
// 封装
unsigned int encap;
};
通道模式结构定义:
/* net/ipv4/xfrm4_mode_tunnel.c */
static struct xfrm_mode xfrm4_tunnel_mode = {
.input = xfrm4_tunnel_input,
.output = xfrm4_tunnel_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TUNNEL,
};
/* net/ipv4/xfrm4_mode_tunnel.c */
static struct xfrm_mode xfrm4_tunnel_mode = {
.input = xfrm4_tunnel_input,
.output = xfrm4_tunnel_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TUNNEL,
};
传输模式结构定义:
/* net/ipv4/xfrm4_mode_transport.c */
static struct xfrm_mode xfrm4_transport_mode = {
.input = xfrm4_transport_input,
.output = xfrm4_transport_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TRANSPORT,
};
/* net/ipv4/xfrm4_mode_transport.c */
static struct xfrm_mode xfrm4_transport_mode = {
.input = xfrm4_transport_input,
.output = xfrm4_transport_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TRANSPORT,
};
beet模式, 不知道在哪用
/* net/ipv4/xfrm4_mode_beet.c */
static struct xfrm_mode xfrm4_beet_mode = {
.input = xfrm4_beet_input,
.output = xfrm4_beet_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_BEET,
};
/* net/ipv4/xfrm4_mode_beet.c */
static struct xfrm_mode xfrm4_beet_mode = {
.input = xfrm4_beet_input,
.output = xfrm4_beet_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_BEET,
};
2.5 策略的相关协议处理结构
以下结构用于描述具体协议族下的的策略处理:
struct xfrm_policy_afinfo {
// 协议族
unsigned short family;
// 协议类型
struct xfrm_type *type_map[IPPROTO_MAX];
// 模式
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
// 目的操作结构
struct dst_ops *dst_ops;
// 垃圾搜集
void (*garbage_collect)(void);
// 路由选择
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
// 获取源地址
int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
// 查找路由项
struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
// 创建新路由项
int (*bundle_create)(struct xfrm_policy *policy,
struct xfrm_state **xfrm,
int nx,
struct flowi *fl,
struct dst_entry **dst_p);
// 解码会话
void (*decode_session)(struct sk_buff *skb,
struct flowi *fl);
};
// 协议族
unsigned short family;
// 协议类型
struct xfrm_type *type_map[IPPROTO_MAX];
// 模式
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
// 目的操作结构
struct dst_ops *dst_ops;
// 垃圾搜集
void (*garbage_collect)(void);
// 路由选择
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
// 获取源地址
int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
// 查找路由项
struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
// 创建新路由项
int (*bundle_create)(struct xfrm_policy *policy,
struct xfrm_state **xfrm,
int nx,
struct flowi *fl,
struct dst_entry **dst_p);
// 解码会话
void (*decode_session)(struct sk_buff *skb,
struct flowi *fl);
};
IPV4的策略协议相关处理结构定义如下:
/* net/ipv4/xfrm4_policy.c */
static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
.family = AF_INET,
.dst_ops = &xfrm4_dst_ops,
.dst_lookup = xfrm4_dst_lookup,
.get_saddr = xfrm4_get_saddr,
.find_bundle = __xfrm4_find_bundle,
.bundle_create = __xfrm4_bundle_create,
.decode_session = _decode_session4,
static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
.family = AF_INET,
.dst_ops = &xfrm4_dst_ops,
.dst_lookup = xfrm4_dst_lookup,
.get_saddr = xfrm4_get_saddr,
.find_bundle = __xfrm4_find_bundle,
.bundle_create = __xfrm4_bundle_create,
.decode_session = _decode_session4,
2.5 状态的相关协议处理结构
以下结构用于描述具体协议族下的的状态处理:
struct xfrm_state_afinfo {
// 协议族
unsigned short family;
// 初始化标志
int (*init_flags)(struct xfrm_state *x);
// 初始化模板选择
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
xfrm_address_t *daddr, xfrm_address_t *saddr);
// 模板排序
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
// 状态排序
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
};
// 协议族
unsigned short family;
// 初始化标志
int (*init_flags)(struct xfrm_state *x);
// 初始化模板选择
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
xfrm_address_t *daddr, xfrm_address_t *saddr);
// 模板排序
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
// 状态排序
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
};
IPV4的状态相关协议处理结构
/* net/ipv4/xfrm4_state.c */
static struct xfrm_state_afinfo xfrm4_state_afinfo = {
.family = AF_INET,
.init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
};
.family = AF_INET,
.init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
};
2.6 回调通知信息结构
struct xfrm_mgr
{
struct list_head list;
char *id;
// 状态通知
int (*notify)(struct xfrm_state *x, struct km_event *c);
// 获取, 如获取SA
int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
// 编译策略
struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
// 映射
int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
// 策略通知
int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
// 报告
int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
};
{
struct list_head list;
char *id;
// 状态通知
int (*notify)(struct xfrm_state *x, struct km_event *c);
// 获取, 如获取SA
int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
// 编译策略
struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
// 映射
int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
// 策略通知
int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
// 报告
int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
};
在net/key/pf_key.c中定义了pkeyv2_mgr结构:
static struct xfrm_mgr pfkeyv2_mgr =
{
.id = "pfkeyv2",
.notify = pfkey_send_notify,
.acquire = pfkey_send_acquire,
.compile_policy = pfkey_compile_policy,
.new_mapping = pfkey_send_new_mapping,
.notify_policy = pfkey_send_policy_notify,
};
{
.id = "pfkeyv2",
.notify = pfkey_send_notify,
.acquire = pfkey_send_acquire,
.compile_policy = pfkey_compile_policy,
.new_mapping = pfkey_send_new_mapping,
.notify_policy = pfkey_send_policy_notify,
};
3. 初始化
/* net/xfrm/xfrm_policy.c */
// xfrm初始化函数包括状态, 策略和输入处理的三初始化函数
// xfrm是不支持模块方式的
void __init xfrm_init(void)
{
xfrm_state_init();
xfrm_policy_init();
xfrm_input_init();
}
3.1 xfrm状态初始化
/* net/xfrm/xfrm_state.c */
void __init xfrm_state_init(void)
{
unsigned int sz;
// 初始HASH表不大, 每个HASH中初始化为8个链表, 但随着状态数量的增加
// 会动态增加HASH表数量
sz = sizeof(struct hlist_head) * 8;
void __init xfrm_state_init(void)
{
unsigned int sz;
// 初始HASH表不大, 每个HASH中初始化为8个链表, 但随着状态数量的增加
// 会动态增加HASH表数量
sz = sizeof(struct hlist_head) * 8;
// 建立3组HASH, 分别按SA的源地址, 目的地址和SPI值
xfrm_state_bydst = xfrm_hash_alloc(sz);
xfrm_state_bysrc = xfrm_hash_alloc(sz);
xfrm_state_byspi = xfrm_hash_alloc(sz);
if (!xfrm_state_bydst || !xfrm_state_bysrc || !xfrm_state_byspi)
panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes.");
xfrm_state_bydst = xfrm_hash_alloc(sz);
xfrm_state_bysrc = xfrm_hash_alloc(sz);
xfrm_state_byspi = xfrm_hash_alloc(sz);
if (!xfrm_state_bydst || !xfrm_state_bysrc || !xfrm_state_byspi)
panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes.");
// xfrm_state_hmask初始值为=7, 计算出的HASH值与该值与来得到链表号
xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
// 初始化工作队列work_queue, 完成对状态垃圾的搜集和释放
INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL);
}
xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
// 初始化工作队列work_queue, 完成对状态垃圾的搜集和释放
INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL);
}
3.2 策略初始化
static void __init xfrm_policy_init(void)
{
unsigned int hmask, sz;
int dir;
// 建立一个内核cache, 用于分配xfrm_dst结构()
xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
sizeof(struct xfrm_dst),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL, NULL);
// 分配状态HASH表, 初始是8个HASH链表,以后随着策略数量的增加
// 会动态增加HASH表的数量
hmask = 8 - 1;
sz = (hmask+1) * sizeof(struct hlist_head);
// 该HASH表是按策略的index参数进行索引的
xfrm_policy_byidx = xfrm_hash_alloc(sz);
xfrm_idx_hmask = hmask;
if (!xfrm_policy_byidx)
panic("XFRM: failed to allocate byidx hash\n");
xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
sizeof(struct xfrm_dst),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL, NULL);
// 分配状态HASH表, 初始是8个HASH链表,以后随着策略数量的增加
// 会动态增加HASH表的数量
hmask = 8 - 1;
sz = (hmask+1) * sizeof(struct hlist_head);
// 该HASH表是按策略的index参数进行索引的
xfrm_policy_byidx = xfrm_hash_alloc(sz);
xfrm_idx_hmask = hmask;
if (!xfrm_policy_byidx)
panic("XFRM: failed to allocate byidx hash\n");
// 输入, 输出, 转发三个处理点, 双向
for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
struct xfrm_policy_hash *htab;
for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
struct xfrm_policy_hash *htab;
// 初始化inexact链表头, inexact处理选择子相关长度不是标准值的一些特别策略
INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]);
INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]);
// 分配按地址HASH的HASH表
htab = &xfrm_policy_bydst[dir];
htab->table = xfrm_hash_alloc(sz);
htab->hmask = hmask;
if (!htab->table)
panic("XFRM: failed to allocate bydst hash\n");
}
// 初始化策略垃圾搜集的工作队列, 完成对策略垃圾的搜集和释放
INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task, NULL);
// 登记网卡通知
register_netdevice_notifier(&xfrm_dev_notifier);
}
htab = &xfrm_policy_bydst[dir];
htab->table = xfrm_hash_alloc(sz);
htab->hmask = hmask;
if (!htab->table)
panic("XFRM: failed to allocate bydst hash\n");
}
// 初始化策略垃圾搜集的工作队列, 完成对策略垃圾的搜集和释放
INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task, NULL);
// 登记网卡通知
register_netdevice_notifier(&xfrm_dev_notifier);
}
xfrm的网卡通知回调结构
static struct notifier_block xfrm_dev_notifier = {
xfrm_dev_event,
NULL,
0
};
static struct notifier_block xfrm_dev_notifier = {
xfrm_dev_event,
NULL,
0
};
// 网卡通知回调函数
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
switch (event) {
// 如果网卡down掉的话, 清除相关的所有的xfrm路由项
case NETDEV_DOWN:
xfrm_flush_bundles();
}
return NOTIFY_DONE;
}
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
switch (event) {
// 如果网卡down掉的话, 清除相关的所有的xfrm路由项
case NETDEV_DOWN:
xfrm_flush_bundles();
}
return NOTIFY_DONE;
}
// 清除相关的所有的xfrm路由项
static int xfrm_flush_bundles(void)
{
// 将不用的路由项删除
xfrm_prune_bundles(stale_bundle);
return 0;
}
static int xfrm_flush_bundles(void)
{
// 将不用的路由项删除
xfrm_prune_bundles(stale_bundle);
return 0;
}
3.3 输入初始化
/* net/xfrm/xfrm_input.c */
void __init xfrm_input_init(void)
{
// 建立一个内核cache, 用于分配sec_path结构(安全路径)
secpath_cachep = kmem_cache_create("secpath_cache",
sizeof(struct sec_path),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL, NULL);
}
void __init xfrm_input_init(void)
{
// 建立一个内核cache, 用于分配sec_path结构(安全路径)
secpath_cachep = kmem_cache_create("secpath_cache",
sizeof(struct sec_path),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL, NULL);
}
struct sec_path结构是对输入的加密包进行层层解包的处理, 在sk_buff中有该结构的指针sp, 如果sp非空表示这是个IPSEC解密后的包。
...... 待续 ......
发表评论
-
Linux发送函数dev_queue_xmit分析 --转
2010-12-14 21:44 14777当上层准备好一个包之后,交给下面这个函数处理: int de ... -
内核污染错误
2010-12-12 21:48 1836一些oops报告在程序记数器之后包含字符串'Tainted: ... -
EXPORT_SYMBOL 与 EXPORT_SYMBOL_GPL 转载
2010-12-12 15:04 121541.EXPORT_SYMBOL EXPORT_SYMB ... -
TCP和UDP在网络层实现的不同--基于linux内核 --转
2010-12-11 20:01 1350由于4层协议实 ... -
ipv6 分片
2010-12-07 21:13 5108519 static int ip6_fragment(str ... -
ipv6 处理扩展头
2010-12-06 09:47 3581160 static int ip6_input_finish ... -
IPV6详解 --转
2010-12-02 14:11 1203一、IPv6基本头 IPv6基本头标包含40字节 ... -
Linux内核中的IPSEC实现(7) ---转载
2010-11-16 20:19 4055本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中的IPSEC实现(6) --转载
2010-11-16 20:09 2193本文档的Copyleft归yfydz所 ... -
Linux内核中的IPSEC实现(5) ---转载
2010-11-15 15:48 4069本文档的Copyleft归yfydz所有,使用GPL发布 ... -
Linux内核中的IPSEC实现(4) ---转载
2010-11-15 15:46 1411本文档的Copyleft归yfydz ... -
Linux内核中的IPSEC实现(3) ---转载
2010-11-15 15:42 1588本文档的Copyleft归yfydz所有,使用GPL发布,可 ... -
Linux内核中的IPSEC实现(2) ---转载
2010-11-15 15:35 2851本文档的Copyleft归yfydz所有,使用GPL发布,可以 ...
相关推荐
Linux内核中IPSec网关的设计与实现.pdf
文件名:linux-5.15.118.tar.xz 文件发布日期: 2023-06-21 说明: 该版本是长期支持版本.
Linux内核中的IPSec协议栈通过XFRM框架实现了对数据包的安全处理。从数据结构到处理流程,再到加解密机制,每一个环节都经过精心设计,以确保网络通信的安全性和可靠性。通过源码分析,我们可以深入了解这一核心网络...
基于Linux2.6内核的IPSec实现研究.pdf
在Petalinux中,内核源码主要由linux-xlnx-xilinx-v2020.1目录下的文件组成。这个版本的内核源码针对Xilinx的FPGA和SoC平台进行了优化,以充分利用硬件特性。 1. **内核配置**:在源码目录下的`arch`和`drivers`子...
Linux 2.6内核中IPSec支持机制分析.pdf
7. **套接字缓冲区(sk_buff)支持**:在Linux中,sk_buff数据结构是处理网络数据的关键。在IPSec的实现中,它被扩展以支持添加或删除安全头,适应安全处理的需要。 8. **路由处理支持**:dst_entry结构用于记录IP...
在本文中,我们将详细讨论 Linux 内核的初始化过程,包括 CPU 的初始化、BIOS 的引导、内核的自解压和初始化等步骤。 一、CPU 初始化 在 CPU 初始化过程中,CPU 首先会执行一条指令,这条指令将跳转到 BIOS 中。...
Linux内核设计与实现,终于找到中文版了,共享出来给大家
[Linux内核源码].linux-2.6.16.18.tar.bz2.part3.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part3.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part3.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part3.rar
xfrm模块是Linux内核中实现IPsec功能的核心部分,它包含了安全策略(SP)和安全联盟(SA)两个核心概念。安全策略是用于匹配需要进行IPsec处理的数据包,通过配置条件参数(如地址、端口、协议等)来决定哪些数据包...
Xenomai官方做好的内核源码Linux内核
Linux内核完全剖析.pdf-----基于0.11内核(修正版3.0)
基于Linux2_6内核的IPSec实现研究
在Linux系统中,内核扮演着至关重要的角色,它是整个操作系统的基石。当我们提到“升级Linux内核到kernel-ml-aufs-devel-3.10.5-3.el6所需的内核”时,这涉及到对现有Linux内核的更新,以获取最新的功能、性能优化和...
[Linux内核源码].linux-2.6.16.18.tar.bz2.part1.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part1.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part1.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part1.rar
[Linux内核源码].linux-2.6.16.18.tar.bz2.part2.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part2.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part2.rar [Linux内核源码].linux-2.6.16.18.tar.bz2.part2.rar
总结以上知识点,本文对Linux内核加密框架从理论和实践两个层面进行了深入探讨,尤其重点介绍了算法模版的概念、使用方法,以及IPSec协议中的应用实例。此外,还提到了Linux内核版本相关信息和对文章内容的使用声明...