上一篇提到ip_local_out函数最终会调用ip_output完成报文发送,本篇分析ip_output的处理过程。
1、ip_output函数
int ip_output(struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;
IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
skb->dev = dev;
skb->protocol = htons(ETH_P_IP); //设置报文协议为IPV4
return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, skb,
NULL, dev,
ip_finish_output, //报文发送netfilter处理,如果允许则调用ip_finish_output
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
2、ip_finish_output函数
static int ip_finish_output(struct sock *sk, struct sk_buff *skb)
{
#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
/* Policy lookup after SNAT yielded a new policy */
if (skb_dst(skb)->xfrm) { //仅经过ip_forward流程处理的报文携带该对象
IPCB(skb)->flags |= IPSKB_REROUTED