Linux2.6中xfrm框架的dst_output的处理步骤
发布时间:2021-11-25 20:05:02 所属栏目:教程 来源:互联网
导读:Linux内核中ipsec的dst_output处理过程,当执行第一个dst_output时,这时会进入 xfrm4_outpot,下面是这个函数的代码: int xfrm4_output(struct sk_buff *skb) { return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb-dst-dev, xfrm4_output_fi
Linux内核中ipsec的dst_output处理过程,当执行第一个dst_output时,这时会进入 xfrm4_outpot,下面是这个函数的代码: int xfrm4_output(struct sk_buff *skb) { return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, xfrm4_output_finish, !(IPCB(skb)->flags & IPSKB_REROUTED)); } static int xfrm4_output_finish(struct sk_buff *skb) { int err; #ifdef CONFIG_NETFILTER if (!skb->dst->xfrm) { IPCB(skb)->flags |= IPSKB_REROUTED; return dst_output(skb); } #endif while (likely((err = xfrm4_output_one(skb)) == 0)) { nf_reset(skb); err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, &skb, NULL, skb->dst->dev, dst_output); if (unlikely(err != 1)) break; if (!skb->dst->xfrm) return dst_output(skb); err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL, skb->dst->dev, xfrm4_output_finish); if (unlikely(err != 1)) break; } return err; } static int xfrm4_output_one(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; struct xfrm_state *x = dst->xfrm; int err; if (skb->ip_summed == CHECKSUM_HW) { err = skb_checksum_help(skb, 0); if (err) goto error_nolock; } if (x->props.mode) { err = xfrm4_tunnel_check_size(skb); if (err) goto error_nolock; } do { spin_lock_bh(&x->lock); err = xfrm_state_check(x, skb); if (err) goto error; xfrm4_encap(skb); err = x->type->output(x, skb); if (err) goto error; x->curlft.bytes += skb->len; x->curlft.packets++; spin_unlock_bh(&x->lock); if (!(skb->dst = dst_pop(dst))) { err = -EHOSTUNREACH; goto error_nolock; } dst = skb->dst; x = dst->xfrm; } while (x && !x->props.mode); IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; err = 0; out_exit: return err; error: spin_unlock_bh(&x->lock); error_nolock: kfree_skb(skb); goto out_exit; } 这段代码中嵌套调用了很多NF_HOOK_COND nf_hook函数,他最终是怎么推出循环调用到最后的ip_output的呢?在xfrm4_output_finish首先运行 xfrm4_output_one执行了esp_output和ah_output进行了完整性认证,为什么后面还可以调用 nf_hook(PF_INET, NF_IP_LOCAL_OUT, &skb, NULL, skb->dst->dev, dst_output);和nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL, skb->dst->dev, xfrm4_output_finish);进行NAT操作?我觉得在这里没必要调用nf_hook函数去走重新遍历hook链表。 -------------------------- NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, xfrm4_output_finish, !(IPCB(skb)->flags & IPSKB_REROUTED)); 如果设置了IPSKB_REROUTED标记,直接执行xfrm4_output_finish不去走hook链表,要是没有设置IPSKB_REROUTED.肯定是遍历完了整个hook链表. (编辑:东莞站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |