- 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管理
- 在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模式
- 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
- atomic_t refcnt; // 所有使用计数
- spinlock_t lock; // 状态锁
- struct xfrm_id id; // ID结构, 即目的地址,SPI,协议三元组
- struct xfrm_selector sel; // 状态选择子
- u32 genid; // 状态的标志值, 防止发生碰撞
- /* Key manger bits */
- 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 xfrm_lifetime_cfg lft; // 生存时间配置
- /* Data for transformer */
- struct xfrm_algo *aalg; // hash算法
- struct xfrm_algo *ealg; // 加密算法
- struct xfrm_algo *calg; // 压缩算法
- /* Data for encapsulator */
- struct xfrm_encap_tmpl *encap; // NAT-T封装信息
- /* Data for care-of address */
- xfrm_address_t *coaddr;
- /* IPComp needs an IPIP tunnel for handling uncompressed packets */
- struct xfrm_state *tunnel; // 通道, 实际是另一个SA
- /* If a tunnel, number of users + 1 */
- atomic_t tunnel_users; // 通道的使用数
- /* State for replay detection */
- struct xfrm_replay_state replay; // 回放检测结构,包含各种序列号掩码等信息
- /* Replay detection state at the time we sent the last notification */
- struct xfrm_replay_state preplay; // 上次的回放记录值
- /* 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 timer_list timer; // SA定时器
- /* Last used time */
- u64 lastused; // 上次使用时间
- /* Reference to data common to all the instances of this
- * transformer. */
- struct xfrm_type *type; // 协议, ESP/AH/IPCOMP
- struct xfrm_mode *mode; // 模式, 通道或传输
- /* Security context */
- struct xfrm_sec_ctx *security; // 安全上下文, 加密时使用
- /* Private data of this transformer, format is opaque,
- * 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的链表
- /* This lock only affects elements except for entry. */
- 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]; // 状态模板
- };
- 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;
- /* Source address of tunnel. Ignored, if it is not a tunnel. */
- // 源地址
- xfrm_address_t saddr;
- // 请求ID
- __u32 reqid;
- /* Mode: transport, tunnel etc. */
- __u8 mode;
- /* Sharing mode: unique, this session only, this user only etc. */
- __u8 share;
- /* May skip this transfomration if no SA is found */
- __u8 optional;
- /* Bit mask of algos allowed for acquisition */
- __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);
- };
- 具体的协议结构定义如下, 通常只定义初始化,析构,输入和输出四个成员函数:
- 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
- };
- 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
- };
- 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
- };
- 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;
- };
- 通道模式结构定义:
- /* 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,
- };
- 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);
- };
- 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,
- 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);
- };
- 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,
- };
- 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);
- };
- 在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,
- };
- 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;
- // 建立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_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);
- }
- 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");
- // 输入, 输出, 转发三个处理点, 双向
- for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
- struct xfrm_policy_hash *htab;
- // 初始化inexact链表头, inexact处理选择子相关长度不是标准值的一些特别策略
- 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);
- }
- xfrm的网卡通知回调结构
- 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;
- }
- // 清除相关的所有的xfrm路由项
- 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);
- }
- struct sec_path结构是对输入的加密包进行层层解包的处理, 在sk_buff中有该结构的指针sp, 如果sp非空表示这是个IPSEC解密后的包。
- ...... 待续 ......
- 发表于: 2007-06-03,修改于: 2007-06-03 00:27,已浏览6239次,有评论23条 推荐 投诉
- 网友: 本站网友 时间:2007-10-12 15:19:10 IP地址:222.64.17.★
- 强烈的顶顶顶!!!
- 15G空间=5个网站=500元/年 可免费试用
- www.abcnic.com QQ:1012727
- 5GB 独立WEB空间、5GB 企业邮箱空间、5GB MSSQL数据库
- IIS连接数据 500 个、500GB/月流量、共享日志文件空间
- 数据库功能
- 支持5GB MSSQL数据库空间,5个用户数据库、Access
- 主机功能支持
- 采用安全稳定的Win2003 .net2.0 架构
- 支持ASP、PHP、ASP.NET、PERL等脚本、支持自定义CGI
- 全面支持.net2.0版本,独立的Application应用池,
- 支持SSI(Shtml),支持FrontPage扩展
- 可免费自行绑定5个域名、500个解析、500个子域名
- 企业邮箱功能
- 赠送5GB 超大企业邮箱,500个Email企业邮箱用户
- 自动回复、自动转发、POP3、SMTP收发信、SMTP发信认证
- 邮件过滤、邮件拒收、邮件夹管理、邮件域管理、定制邮件数
- 网友: zetalog 时间:2007-11-19 10:57:41 IP地址:218.81.225.★
- 为什么bundle是路由?!!
- 根据RFC2401,对于外出处理SPD entry直接指向SA Bundle,是这SA束吧!
- 看看注释也知道了:
- dst -. xfrm .-> xfrm_state #1
- |---. child .-> dst -. xfrm .-> xfrm_state #2
- |---. child .-> dst -. xfrm .-> xfrm_state #3
- |---. child .-> NULL
- dst_entry和xfrm_dst都是包含xfrm_state的,而且通过.child连接为SA束。
- 网友: yfydz 时间:2007-11-19 12:36:03 IP地址:218.247.216.★
- 那你觉得这SA束又是什么东西?
- 网友: yfydz 时间:2007-11-19 12:36:56 IP地址:218.247.216.★
- 或者说dst_entry/xfrm_dst又是什么东西?
- 网友: zetalog 时间:2007-11-20 11:27:13 IP地址:218.81.225.★
- 安全关联束(Security Association Bundle)是一个SA序列,传输必须通过它处理以满足一个安全策略。组成束的SA可以终止于不同端点。
- 网友: Zetalog 时间:2007-11-20 11:29:39 IP地址:218.81.225.★
- 我再来提个小意见。
- struct xfrm_policy
- {
- struct xfrm_policy *next; // 下一个策略
- next是不要的,我保证你去掉它可以编译通过,策略存储是通过byidx和bydst还有inexact哈希表完成的。这些哈希表都是动态哈希表,会根据节点数量的多少自动增加。
- next留在那里一定是改造不彻底,我打算发个patch去。
- 网友: Zetalog 时间:2007-11-20 11:33:17 IP地址:218.81.225.★
- 我再来补充一下SA bundle。
- RFC2401定义了组成SA bundle的几种方式:
- 传输邻接(transport adjacency),只能是AH应用于ESP输出,其他方式没有意义。
- 迭代隧道(iterated tunneling):允许多重迭代,仅road warrior和VPN两种情况需要支持。
- 隧道模式和传输模式两种方式也可以被任意组合。
- 网友: Zetalog 时间:2007-11-20 11:44:44 IP地址:218.81.225.★
- 根据RFC2401定义,策略必须有一个参数用来表示报文的流向。
- 为什么xfrm_policy里面没有呢?其实index的第三位就是方向。
- 网友: yfydz 时间:2007-11-20 12:34:14 IP地址:218.247.216.★
- 你说的没错,但RFC只定义了SA bundle的形式,却没限制这个bundle是如何实现的. xfrm的实现就是扩展了路由dst_entry为xfrm_dst,这个xfrm_dst的in/output函数就是IPSEC的解封/加封操作,通过dst链表实现bundle的处理.不要一提路由就立即为就是发送数据包,我在该系列后面文章也详细分析了这个路由链的处理,这里直接称其为路由是透过现象说本质的说法,当然如果是其他方式的实现,当然就不会称其为路由
- 网友: Zetalog 时间:2007-11-20 12:41:17 IP地址:218.81.225.★
- 这么说可以理解了,呵呵。
- 网友: yfydz 时间:2007-11-20 13:23:22 IP地址:218.247.216.★
- 由此就可以把xfrm和klips归为一类,都是靠路由来实现安全策略的,如果从FW+VPN角度说,FW的访问控制策略和VPN连接就需要分开定义的,VPN只处理点到点。而以前用过checkpoint的FW,可以在访问控制策略的动作中定义加密,也就是IPSEC封装,这说明其SA bundle应该和路由没关系,所以强调这点也是在区分不同的IPSEC的实现流派.
- 网友: Zetalog 时间:2007-11-20 16:25:57 IP地址:218.81.225.★
- 我这样理解不知道是否可以:
- 在报文进行路由处理的时候,xfrm_lookup会被调用。在xfrm_lookup处理中,如果对当前的传输流有对应的policy(可能是sk_policy也可能是一般的policy),则查找dst_entry中是否缓存过IPsec处理的表项。如果没有,则根据policy的xfrm_tmpl解析出一个SA bundle,并且将它创建为dst_entry并缓存在bundle成员中,这个新创建或者查找到的dst_entry挂载在插入点中(xfrm_lookup)传入的dst_p。这样当报文发送的时候外出处理的回调就会被调用到。不知道是不是这样的?好像您在该系列的第三篇里面有描述,不过跟我现在看的git_kernel的代码有些不同。
- 网友: Zetalog 时间:2007-11-20 16:34:40 IP地址:218.81.225.★
- 如果我的理解正确,bundle里面只是缓存了跟IPsec处理相关的处理项,其它路由项还是在__xfrm_lookup函数的传入参数的dst_p所关联的另一个链表中中。所以xfrm_policy的成员bundle就是RFC2401描述的那个SPD表项必然实现的SA bundle缓存。
- 网友: Zetalog 时间:2007-11-20 16:46:19 IP地址:218.81.225.★
- 我是对着RFC2401在看xfrm_policy。RFC描述SPD表项必须要有以下参数:
- 流向:linux的dir应该在index里面了
- 动作:linux应该就是action
- 有序:linux应该是priority
- 由选择符索引:linux中应该是family和selector,因为xfrm_address_t没有协议族,所以xfrm里面到处都要family
- 有一个外出处理SA bundle缓存:linux就是bundle
- 有一个管理接口(xfrm_mgr)
- 主机端允许、用户对单独的流修改策略(sk_policy)
- 允许SA选择继承SPD表项还是传输流的选择子,好像linux实现在试验这个功能,在XFRM_SUB_POLICY有效时能看到相关代码。
- 。。。。。。
- 网友: Zetalog 时间:2007-11-20 17:04:46 IP地址:218.81.225.★
- 呵呵,我有点追求名字了。
- 本质上说Linux就是路由型的IPsec处理。
- 网友: yfydz 时间:2007-11-21 12:40:58 IP地址:218.247.216.★
- 基本就是这样吧
- 网友: zetalog 时间:2007-11-21 20:53:31 IP地址:58.33.88.★
- 楼主,你好。
- 我这两天一直在分析xfrm代码,今天的总体感觉xfrm里面dst_entry好像还是用来实现PMTUD对应的功能。
- 在xfrm_state里面有一个genid参数,当新的SA加入时候会调用__xfrm_state_bump_genids把所有目标源地址相同的SA(他们的路由也应该一样)的genid改成一样。xfrm_dst里面也有genid。看到注释中说好像也和PMTUD相关的。不过实在没看明白是干吗的。不知道楼主对genid了解吗?
- 网友: yfydz 时间:2007-11-23 11:06:37 IP地址:218.247.216.★
- xfrm_dst里的genid和xfrm_state的没关系,前者只是flow的ID,因为是路由,xfrm_dst也是flow的一种
- 网友: 本站网友 时间:2008-03-22 12:07:41 IP地址:202.198.16.★
- 斑竹你好,想把red算法的平均队列,瞬时队列,以及时间作为日志输出到一文件中,却不知怎么下手,请指点....
- 网友: _Lightsky_ 时间:2008-04-01 10:27:31 IP地址:222.88.1.★
- 这些天一直在阅读XFRM里的源代码,却发现里面全是.h和.C,找不到调用的源头在那里?指点一下!谢谢了!
- 网友: _Lightsky_ 时间:2008-04-01 10:30:52 IP地址:222.88.1.★
- XFRM里面有一个USER,好像是调用的接口,但不知道编程的时候该怎么调用,不知道楼主有没有相关的文档?
- 网友: _Lightsky_ 时间:2008-04-01 11:05:18 IP地址:222.88.1.★
- 我的邮箱是yangzhongxiqq@163.com,谢谢帮助啊!你的邮箱呢?
- 网友: yfydz 时间:2008-04-02 13:11:39 IP地址:218.247.216.★
- 看最新的iproute2代码,就是用户层接口
Linux内核中的IPSEC实现(1)
最新推荐文章于 2024-08-20 10:23:26 发布