- 浏览: 262743 次
- 性别:
- 来自: 吉林
文章分类
最新评论
-
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
9. IPSEC封装流程
IPSEC
数据包的封装过程是在数据包发出前完成的, 是和路由选择密切相关的, 根据前面的发出分析可知封装是通过对数据设置安全路由链表来实现的, 因此对数据包的IPSEC封装流程可以简单描述如下:
数据包的封装过程是在数据包发出前完成的, 是和路由选择密切相关的, 根据前面的发出分析可知封装是通过对数据设置安全路由链表来实现的, 因此对数据包的IPSEC封装流程可以简单描述如下:
1) 对于进入的数据包, 进行路由选择, 如果是转发的, 进入路由输入, 然后查找安全策略检查是否需要IPSEC封装, 如果需要封装, 就查找和创建相关的安全路由, 进入路由输出处理, 在路由输出时即按照安全路由一层层地封装数据包最后得到IPSEC包发出;
2) 对于自身发出的数据包, 需要进行路由选择, 选定路由后进入路由输入, 查找安全策略进行处理, 以后和转发的数据包IPSEC封装就是完全相同了。
9.1 转发包的封装
数据的转发入口点函数是ip_forward, 进入该函数的数据包还是普通数据包,数据包的路由也是普通路由:
/* net/ipv4/ip_forward.c */
int ip_forward(struct sk_buff *skb)
{
struct iphdr *iph; /* Our header */
struct rtable *rt; /* Route we use */
struct ip_options * opt = &(IPCB(skb)->opt);
// 对转发的数据包进行安全策略检查, 检查失败的话丢包
if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
goto drop;
if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
goto drop;
if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
return NET_RX_SUCCESS;
// 转发包也是到自身的包, 不是的话丢包
if (skb->pkt_type != PACKET_HOST)
goto drop;
return NET_RX_SUCCESS;
// 转发包也是到自身的包, 不是的话丢包
if (skb->pkt_type != PACKET_HOST)
goto drop;
skb->ip_summed = CHECKSUM_NONE;
/*
* According to the RFC, we must first decrease the TTL field. If
* that reaches zero, we must reply an ICMP control message telling
* that the packet's lifetime expired.
*/
// TTL到头了, 丢包
if (skb->nh.iph->ttl <= 1)
goto too_many_hops;
// 进入安全路由选路和转发处理, 在此函数中构造数据包的安全路由
if (!xfrm4_route_forward(skb))
goto drop;
/*
* According to the RFC, we must first decrease the TTL field. If
* that reaches zero, we must reply an ICMP control message telling
* that the packet's lifetime expired.
*/
// TTL到头了, 丢包
if (skb->nh.iph->ttl <= 1)
goto too_many_hops;
// 进入安全路由选路和转发处理, 在此函数中构造数据包的安全路由
if (!xfrm4_route_forward(skb))
goto drop;
// 以下是一些常规的路由和TTL处理
rt = (struct rtable*)skb->dst;
rt = (struct rtable*)skb->dst;
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
goto sr_failed;
goto sr_failed;
/* We are about to mangle packet. Copy it! */
if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len))
goto drop;
iph = skb->nh.iph;
if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len))
goto drop;
iph = skb->nh.iph;
/* Decrease ttl after skb cow done */
ip_decrease_ttl(iph);
ip_decrease_ttl(iph);
/*
* We now generate an ICMP HOST REDIRECT giving the route
* we calculated.
*/
if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
ip_rt_send_redirect(skb);
* We now generate an ICMP HOST REDIRECT giving the route
* we calculated.
*/
if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
ip_rt_send_redirect(skb);
skb->priority = rt_tos2priority(iph->tos);
// 进行FORWARD点过滤, 过滤后进入ip_forward_finish函数
return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
ip_forward_finish);
// 进行FORWARD点过滤, 过滤后进入ip_forward_finish函数
return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
ip_forward_finish);
sr_failed:
/*
* Strict routing permits no gatewaying
*/
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
goto drop;
/*
* Strict routing permits no gatewaying
*/
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
goto drop;
too_many_hops:
/* Tell the sender its packet died... */
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
drop:
kfree_skb(skb);
return NET_RX_DROP;
}
/* Tell the sender its packet died... */
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
drop:
kfree_skb(skb);
return NET_RX_DROP;
}
// ip_forward_finish函数主要就是调用dst_output函数
static inline int ip_forward_finish(struct sk_buff *skb)
{
struct ip_options * opt = &(IPCB(skb)->opt);
static inline int ip_forward_finish(struct sk_buff *skb)
{
struct ip_options * opt = &(IPCB(skb)->opt);
IP_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS);
if (unlikely(opt->optlen))
ip_forward_options(skb);
return dst_output(skb);
}
ip_forward_options(skb);
return dst_output(skb);
}
核心函数是xfrm4_route_forward函数
/* include/net/xfrm.h */
static inline int xfrm4_route_forward(struct sk_buff *skb)
{
return xfrm_route_forward(skb, AF_INET);
}
{
return xfrm_route_forward(skb, AF_INET);
}
static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
// 如果没有发出方向的安全策略的话返回
return !xfrm_policy_count[XFRM_POLICY_OUT] ||
// 如果路由标志专门设置不进行IPSEC封装的话也返回
(skb->dst->flags & DST_NOXFRM) ||
__xfrm_route_forward(skb, family);
}
/* net/xfrm/xfrm_policy.c */
int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
struct flowi fl;
int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
struct flowi fl;
// 路由解码, 填充流结构参数,
// 对IPV4实际调用的是_decode_session4(net/ipv4/xfrm4_policy.c)函数
if (xfrm_decode_session(skb, &fl, family) < 0)
return 0;
// 根据流结构查找安全路由, 没找到的话创建新的安全路由, 最后形成安全路由链表
// 见前几节中的分析
return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
}
// 对IPV4实际调用的是_decode_session4(net/ipv4/xfrm4_policy.c)函数
if (xfrm_decode_session(skb, &fl, family) < 0)
return 0;
// 根据流结构查找安全路由, 没找到的话创建新的安全路由, 最后形成安全路由链表
// 见前几节中的分析
return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
}
因此数据进行转发处理后, 最终进入dst_output函数处理
转发函数流程小结:
ip_forward
-> xfrm4_route_forward (net/xfrm.h, get xfrm_dst)
-> xfrm_route_forward
-> __xfrm_route_forward
-> xfrm_lookup
-> xfrm_find_bundle
-> afinfo->find_bundle == __xfrm4_find_bundle
-> xfrm_bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
tunnel mode
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list: dst->list=policy_bundles, policy->bundles = dst
-> NF_HOOK(NF_FORWARD)
-> ip_forward_finish
-> dst_output
9.2 自身数据发出
对于IPv4包的发出, 通常出口函数是ip_queue_xmit或ip_push_pending_frames, 如果是后者, 数据包是已经经过了路由选择的, 而前者还没有进行路由选择, 两者最后都会调用dst_output()函数进行数据的发出.
/* net/ipv4/ip_output.c */
int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
{
struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
struct ip_options *opt = inet->opt;
struct rtable *rt;
struct iphdr *iph;
/* Skip all of this if the packet is already routed,
* f.e. by something like SCTP.
*/
// 已经路由过的数据跳过路由查找过程
rt = (struct rtable *) skb->dst;
if (rt != NULL)
goto packet_routed;
* f.e. by something like SCTP.
*/
// 已经路由过的数据跳过路由查找过程
rt = (struct rtable *) skb->dst;
if (rt != NULL)
goto packet_routed;
/* Make sure we can route this packet. */
rt = (struct rtable *)__sk_dst_check(sk, 0);
if (rt == NULL) {
__be32 daddr;
rt = (struct rtable *)__sk_dst_check(sk, 0);
if (rt == NULL) {
__be32 daddr;
/* Use correct destination address if we have options. */
daddr = inet->daddr;
if(opt && opt->srr)
daddr = opt->faddr;
daddr = inet->daddr;
if(opt && opt->srr)
daddr = opt->faddr;
{
struct flowi fl = { .oif = sk->sk_bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = inet->saddr,
.tos = RT_CONN_FLAGS(sk) } },
.proto = sk->sk_protocol,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = inet->dport } } };
struct flowi fl = { .oif = sk->sk_bound_dev_if,
.nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = inet->saddr,
.tos = RT_CONN_FLAGS(sk) } },
.proto = sk->sk_protocol,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = inet->dport } } };
/* If this fails, retransmit mechanism of transport layer will
* keep trying until route appears or the connection times
* itself out.
*/
security_sk_classify_flow(sk, &fl);
if (ip_route_output_flow(&rt, &fl, sk, 0))
goto no_route;
}
sk_setup_caps(sk, &rt->u.dst);
}
skb->dst = dst_clone(&rt->u.dst);
* keep trying until route appears or the connection times
* itself out.
*/
security_sk_classify_flow(sk, &fl);
if (ip_route_output_flow(&rt, &fl, sk, 0))
goto no_route;
}
sk_setup_caps(sk, &rt->u.dst);
}
skb->dst = dst_clone(&rt->u.dst);
packet_routed:
if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
goto no_route;
if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
goto no_route;
/* OK, we know where to send it, allocate and build IP header. */
iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
*((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
iph->tot_len = htons(skb->len);
if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->u.dst);
iph->protocol = sk->sk_protocol;
iph->saddr = rt->rt_src;
iph->daddr = rt->rt_dst;
skb->nh.iph = iph;
/* Transport layer set skb->h.foo itself. */
iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
*((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
iph->tot_len = htons(skb->len);
if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->u.dst);
iph->protocol = sk->sk_protocol;
iph->saddr = rt->rt_src;
iph->daddr = rt->rt_dst;
skb->nh.iph = iph;
/* Transport layer set skb->h.foo itself. */
if (opt && opt->optlen) {
iph->ihl += opt->optlen >> 2;
ip_options_build(skb, opt, inet->daddr, rt, 0);
}
iph->ihl += opt->optlen >> 2;
ip_options_build(skb, opt, inet->daddr, rt, 0);
}
ip_select_ident_more(iph, &rt->u.dst, sk,
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
/* Add an IP checksum. */
ip_send_check(iph);
ip_send_check(iph);
skb->priority = sk->sk_priority;
// 进入OUTPUT点进行过滤, 过滤完成后进入dst_output()函数
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
// 进入OUTPUT点进行过滤, 过滤完成后进入dst_output()函数
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
no_route:
IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
return -EHOSTUNREACH;
}
IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
return -EHOSTUNREACH;
}
// 路由查找函数
int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
{
int err;
// 普通的路由查找过程, 此过程不是本文重点, 分析略
if ((err = __ip_route_output_key(rp, flp)) != 0)
return err;
// 如果流结构协议非0(基本是肯定的)进行xfrm路由查找
if (flp->proto) {
// 指定流结构的源地址和目的地址
if (!flp->fl4_src)
flp->fl4_src = (*rp)->rt_src;
if (!flp->fl4_dst)
flp->fl4_dst = (*rp)->rt_dst;
// 根据流结构查找安全路由, 没找到的话创建新的安全路由, 最后形成安全路由链表
// 见前几节中的分析
return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
}
return 0;
}
}
对于不是进入ip_queue_xmit()发送的数据包, 在发送前必然也是经过ip_route_output_flow()函数的路由选择处理, 因此如果需要IPSEC封装的话, 也就设置了相关的安全路由链表.
这样, 对于自身发出的数据包, 最终也是进入dst_output()函数进行发送, 转发和自身发出的数据殊途同归了, 以后的处理过程就都是相同的了
函数流程小结:
ip_queue_xmit
-> ip_route_output_flow
-> xfrm_lookup
-> xfrm_find_bundle
-> bundle_create
-> afinfo->bundle_create == __xfrm4_bundle_create
-> xfrm_dst_lookup
-> afinfo->dst_lookup == xfrm4_dst_lookup
-> __ip_route_output_key
-> dst_list
-> dst->list=policy_bundles, policy->bundles = dst
-> NF_HOOK(NF_OUTPUT)
-> dst_output
-> dst->output
-> dst_output
-> dst->output
9.3 dst_output
/* include/net/dst.h */
/* Output packet to network from transport. */
static inline int dst_output(struct sk_buff *skb)
{
return skb->dst->output(skb);
}
dst_output()函数就是调用路由项的输出函数, 对于安全路由, 该函数是xfrm4_output()函数, 对于普通路由, 是ip_output()函数
对于xfrm4_output()函数的分析见7.6, 执行完所有安全路由的输出函数, 每执行一个安全路由输出函数就是一次IPSEC封装处理过程, 封装结束后的数据包会设置IPSKB_REROUTED标志, 到路由链表的最后一项是普通路由, 进入普通路由的输出函数ip_output:
int ip_output(struct sk_buff *skb)
{
struct net_device *dev = skb->dst->dev;
IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
// 如果是带IPSKB_REROUTED标志的数据包, 不进入POSTROUTING的SNAT处理, 直接执行
// ip_finish_output函数
return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
skb->protocol = htons(ETH_P_IP);
// 如果是带IPSKB_REROUTED标志的数据包, 不进入POSTROUTING的SNAT处理, 直接执行
// ip_finish_output函数
return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
因此对于封装的数据包而言, 在封装过程中可以进行OUTPUT点的过滤和POSTROUTING点的SNAT处理, 但一旦封装完成, 就不会再进行SNAT操作了.
函数调用小结:
xfrm_lookup: find xfrm_dst for the skb, create dst_list
-> xfrm_sk_policy_lookup
-> flow_cache_lookup
-> xfrm_find_bundle
-> xfrm_policy_lookup_bytype
-> xfrm_tmpl_resolve
-> xfrm_tmpl_resolve_one
-> xfrm_get_saddr
-> afinfo->get_saddr == xfrm4_get_saddr
-> xfrm4_dst_lookup
-> xfrm_state_find
-> __xfrm_state_lookup
-> xfrm_state_alloc
-> km_query
-> km->acquire (pfkey_acquire, xfrm_send_acquire)
-> xfrm_state_sort
-> afinfo->state_sort == NULL
-> km_wait_queue
-> xfrm_bundle_create
-> xfrm_sk_policy_lookup
-> flow_cache_lookup
-> xfrm_find_bundle
-> xfrm_policy_lookup_bytype
-> xfrm_tmpl_resolve
-> xfrm_tmpl_resolve_one
-> xfrm_get_saddr
-> afinfo->get_saddr == xfrm4_get_saddr
-> xfrm4_dst_lookup
-> xfrm_state_find
-> __xfrm_state_lookup
-> xfrm_state_alloc
-> km_query
-> km->acquire (pfkey_acquire, xfrm_send_acquire)
-> xfrm_state_sort
-> afinfo->state_sort == NULL
-> km_wait_queue
-> xfrm_bundle_create
dst_output: loop dst_list
-> dst->output == xfrm_dst->output == xfrm4_output == xfrm4_state_afinfo->output
-> NF_HOOK(POSTROUTING)
-> xfrm4_output_finish
-> gso ?
-> xfrm4_output_finish2
-> xfrm4_output_one
-> mode->output
-> type->output
-> skb->dst=dst_pop(skb->dst)
-> nf_hook(NF_OUTPUT)
-> !dst->xfrm
-> dst_output
-> nf_hook(POSTROUTING)
-> dst->output == ip_output
-> NF_HOOK(POSTROUTING)
-> ip_finish_output
-> ip_finish_output2
-> hh_output == dev_queue_xmit
-> dst->output == xfrm_dst->output == xfrm4_output == xfrm4_state_afinfo->output
-> NF_HOOK(POSTROUTING)
-> xfrm4_output_finish
-> gso ?
-> xfrm4_output_finish2
-> xfrm4_output_one
-> mode->output
-> type->output
-> skb->dst=dst_pop(skb->dst)
-> nf_hook(NF_OUTPUT)
-> !dst->xfrm
-> dst_output
-> nf_hook(POSTROUTING)
-> dst->output == ip_output
-> NF_HOOK(POSTROUTING)
-> ip_finish_output
-> ip_finish_output2
-> hh_output == dev_queue_xmit
10. 总结
Linux自带的native ipsec实现xfrm是通过路由来实现IPSEC封装处理的, 这和freeswan是类似的, 只不过freeswan构造了虚拟的ipsec*网卡设备, 这样就可以通过标准的网络工具如iproute2等通过配置路由和ip rule等实现安全策略, 进入该虚拟网卡的数据包就进行IPSEC解封, 从虚拟网卡发出的包就是进行IPSEC封装,因此实现比较独立,除了NAT-T需要修改udp.c源码外,其他基本不需要修改内核源码,对于进入的IPSEC包,在物理网卡上可以抓到原始的IPSEC包,而从虚拟网卡上可以抓到解密后的数据包。而xfrm没有定义虚拟网卡,都是在路由查找过程中自动查找安全策略实现ipsec的解封或封装,因此该实现是必须和内核网络代码耦合在一起的,对于进入的IPSEC包,能在物理网卡抓到两次包,一次是IPSEC原始包,一次是解密后的包。由于还是需要根据路由来进行封装,所以本质还不是基于策略的IPSEC,不过可以通过定义策略路由方式来实现基于策略IPSEC,要是能把IPSEC封装作为一个netfilter的target就好了,这样就可以进行标准的基于策略的IPSEC了。
xfrm和网络代码耦合,这样进行路由或netfilter过滤时都可以通过相关标志进行处理或旁路,如经过IPSEC处理后的数据包是自动不会进行SNAT操作的,而freeswan的实现就不能保证,如果设置SNAT规则不对,是有可能对封装好的包进行SNAT操作而造成错误。但两个实现对于封装前的数据包都是可以进行SNAT操作的,因此那种实现同网段VPN的特殊NAT可以在xfrm下实现。
在RFC2367中只定义了SA相关操作的消息类型,而没有定义SP的操作类型,也没有定义其他扩展的IPSEC功能的相关消息类型,如NAT-T相关的类型,那些SADB_X_*的消息类型就是非标准的,这就造成各种IPSEC实现只能自己定义这些消息类型,因此可能会造成不兼容的现象,应该尽快出新的RFC来更新2367了。
发表评论
-
Linux发送函数dev_queue_xmit分析 --转
2010-12-14 21:44 14806当上层准备好一个包之后,交给下面这个函数处理: int de ... -
内核污染错误
2010-12-12 21:48 1842一些oops报告在程序记数器之后包含字符串'Tainted: ... -
EXPORT_SYMBOL 与 EXPORT_SYMBOL_GPL 转载
2010-12-12 15:04 121601.EXPORT_SYMBOL EXPORT_SYMB ... -
TCP和UDP在网络层实现的不同--基于linux内核 --转
2010-12-11 20:01 1354由于4层协议实 ... -
ipv6 分片
2010-12-07 21:13 5110519 static int ip6_fragment(str ... -
ipv6 处理扩展头
2010-12-06 09:47 3584160 static int ip6_input_finish ... -
IPV6详解 --转
2010-12-02 14:11 1208一、IPv6基本头 IPv6基本头标包含40字节 ... -
Linux内核中的IPSEC实现(6) --转载
2010-11-16 20:09 2206本文档的Copyleft归yfydz所 ... -
Linux内核中的IPSEC实现(5) ---转载
2010-11-15 15:48 4075本文档的Copyleft归yfydz所有,使用GPL发布 ... -
Linux内核中的IPSEC实现(4) ---转载
2010-11-15 15:46 1413本文档的Copyleft归yfydz ... -
Linux内核中的IPSEC实现(3) ---转载
2010-11-15 15:42 1596本文档的Copyleft归yfydz所有,使用GPL发布,可 ... -
Linux内核中的IPSEC实现(2) ---转载
2010-11-15 15:35 2868本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中的IPSEC实现(1) ---转载
2010-11-15 15:31 2734本文档的Copyleft归yfydz所有,使用GPL发布,可以 ...
相关推荐
Linux内核中IPSec网关的设计与实现.pdf
Linux内核中的IPSec协议栈通过XFRM框架实现了对数据包的安全处理。从数据结构到处理流程,再到加解密机制,每一个环节都经过精心设计,以确保网络通信的安全性和可靠性。通过源码分析,我们可以深入了解这一核心网络...
基于Linux2.6内核的IPSec实现研究.pdf
Linux 2.6内核中IPSec支持机制分析.pdf
文件名:linux-5.15.118.tar.xz 文件发布日期: 2023-06-21 说明: 该版本是长期支持版本.
在Petalinux中,内核源码主要由linux-xlnx-xilinx-v2020.1目录下的文件组成。这个版本的内核源码针对Xilinx的FPGA和SoC平台进行了优化,以充分利用硬件特性。 1. **内核配置**:在源码目录下的`arch`和`drivers`子...
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处理的数据包,通过配置条件参数(如地址、端口、协议等)来决定哪些数据包...
Linux内核完全剖析.pdf-----基于0.11内核(修正版3.0)
在Linux系统中,内核扮演着至关重要的角色,它是整个操作系统的基石。当我们提到“升级Linux内核到kernel-ml-aufs-devel-3.10.5-3.el6所需的内核”时,这涉及到对现有Linux内核的更新,以获取最新的功能、性能优化和...
基于Linux2_6内核的IPSec实现研究
Linux 4.4.0-116-generic 内核安装包
[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内核版本相关信息和对文章内容的使用声明...
Xenomai官方做好的内核源码Linux内核
7. **学习资源**:“Linux内核0.11完全注解.pdf”是学习Linux内核的好材料,配合“说明.txt”,读者可以按照指导逐步探索内核的秘密。同时,这也可以作为软件工程师提升技术能力,尤其是对操作系统有深入兴趣者的...