网卡中的netfilter如何生效

./net/netfilter/ipvs/ip_vs_xmit.c:574:        NF_HOOK(pf, NF_INET_LOCAL_OUT, cp->ipvs->net, NULL, skb,
./net/netfilter/ipvs/ip_vs_xmit.c:594:        NF_HOOK(pf, NF_INET_LOCAL_OUT, cp->ipvs->net, NULL, skb,
./net/ipv4/xfrm4_input.c:56:    NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
./net/ipv4/ip_forward.c:147:    return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
./net/ipv4/xfrm4_output.c:101:    return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
./net/ipv4/ip_input.c:257:    return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,
./net/ipv4/ip_input.c:488:    return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
./net/ipv4/raw.c:418:    err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
./net/ipv4/ip_output.c:337:                NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
./net/ipv4/ip_output.c:353:            NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
./net/ipv4/ip_output.c:358:    return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
./net/ipv4/ip_output.c:373:    return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,

所以说,总共有五个矛点:PRE_ROUTING/LOCAL_IN/FORWARDING/LOCAL_OUT/POST_ROUTING

local_in是路由后发现本地数据包,在路由之后做处理;

local_out是路由之后,要朝外走,是路由之前做处理;

设置函数:nf_nat_setup_info

nf_nat_setup_info

 iptable_nat_table_init --> ipt_register_table --> nf_nat_ipv4_ops中注册函数

nf_nat_alloc_null_bonding --> __nf_nat_alloc_null_bonding --> nf_nat_setup_info

./net/netfilter/nf_conntrack_proto_udplite.c:280:    .invert_tuple        = udplite_invert_tuple,
./net/netfilter/nf_conntrack_proto_udplite.c:313:    .invert_tuple        = udplite_invert_tuple,
./net/netfilter/nf_conntrack_proto_sctp.c:756:    .invert_tuple         = sctp_invert_tuple,
./net/netfilter/nf_conntrack_proto_sctp.c:790:    .invert_tuple         = sctp_invert_tuple,
./net/netfilter/nf_conntrack_proto_udp.c:267:    .invert_tuple        = udp_invert_tuple,
./net/netfilter/nf_conntrack_proto_udp.c:300:    .invert_tuple        = udp_invert_tuple,
./net/netfilter/nf_conntrack_proto_gre.c:369:    .invert_tuple     = gre_invert_tuple,
./net/netfilter/nf_conntrack_proto_dccp.c:876:    .invert_tuple        = dccp_invert_tuple,
./net/netfilter/nf_conntrack_proto_dccp.c:910:    .invert_tuple        = dccp_invert_tuple,
./net/netfilter/nf_conntrack_proto_generic.c:192:    .invert_tuple        = generic_invert_tuple,
./net/netfilter/nf_conntrack_proto_tcp.c:1546:    .invert_tuple         = tcp_invert_tuple,
./net/netfilter/nf_conntrack_proto_tcp.c:1583:    .invert_tuple         = tcp_invert_tuple,
./net/netfilter/nf_conntrack_l3proto_generic.c:69:    .invert_tuple     = generic_invert_tuple,
./net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c:319:    .invert_tuple     = ipv4_invert_tuple,
./net/ipv4/netfilter/nf_conntrack_proto_icmp.c:368:    .invert_tuple        = icmp_invert_tuple,
./net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c:375:    .invert_tuple        = icmpv6_invert_tuple,
./net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c:315:    .invert_tuple        = ipv6_invert_tuple,

每一种协议都是

细看这些函数,ipv4_invert_tuple是把ip地址给转换掉,tcp_invert_tuple是把端口给转换掉!

转换的调用栈是:

[151995.117224] ----- (qemu-system-x86  :  22) -------
[151995.117225]  0000000000000000 000000002623b6df ffff88013e203940 ffffffffc0aba053
[151995.117230]  ffffffffc0abc000 ffff88013e203980 ffffffff810608c3 ffffffffc08da005
[151995.117235]  0000000000000400 ffff880035b86040 ffffffffc08dc300 ffff88013e203c28
[151995.117239] Call Trace:
[151995.117241]  <IRQ>  [<ffffffffc0aba053>] handler_pre+0x43/0x54 [fslook]
[151995.117250]  [<ffffffff810608c3>] kprobe_ftrace_handler+0xb3/0x110
[151995.117255]  [<ffffffffc08da005>] ? ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.117262]  [<ffffffff81140160>] ftrace_ops_recurs_func+0x60/0xc0
[151995.117265]  [<ffffffffc00910d5>] 0xffffffffc00910d5
[151995.117271]  [<ffffffffc08da001>] ? ipv4_invert_tuple+0x1/0x20 [nf_conntrack_ipv4]
[151995.117276]  [<ffffffffc08da005>] ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.117286]  [<ffffffffc0a14749>] nf_ct_invert_tuple+0x49/0x80 [nf_conntrack]
[151995.117291]  [<ffffffffc08da005>] ? ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.117301]  [<ffffffffc0a14749>] ? nf_ct_invert_tuple+0x49/0x80 [nf_conntrack]
[151995.117310]  [<ffffffffc0a147c6>] nf_ct_invert_tuplepr+0x46/0x50 [nf_conntrack]
[151995.117316]  [<ffffffffc079d26f>] nf_nat_packet+0x7f/0xe0 [nf_nat]
[151995.117321]  [<ffffffffc08d0840>] nf_nat_ipv4_fn+0x1e0/0x220 [nf_nat_ipv4]
[151995.117326]  [<ffffffffc0a4e020>] ? iptable_nat_ipv4_fn+0x20/0x20 [iptable_nat]
[151995.117331]  [<ffffffffc08d094a>] nf_nat_ipv4_out+0x4a/0xf0 [nf_nat_ipv4]
[151995.117336]  [<ffffffffc0a4e085>] iptable_nat_ipv4_out+0x15/0x20 [iptable_nat]
[151995.117342]  [<ffffffff81751862>] nf_iterate+0x62/0x80
[151995.117348]  [<ffffffff817518f3>] nf_hook_slow+0x73/0xd0
[151995.117353]  [<ffffffff8175eacf>] ip_output+0xcf/0xe0   ------ postrouting
[151995.117359]  [<ffffffff8175df40>] ? __ip_flush_pending_frames.isra.39+0x90/0x90
[151995.117364]  [<ffffffff8175a70d>] ip_forward_finish+0x4d/0x70
[151995.117368]  [<ffffffff8175aac9>] ip_forward+0x399/0x480
[151995.117373]  [<ffffffff8175a6c0>] ? ip_frag_mem+0x50/0x50
[151995.117378]  [<ffffffff817587b2>] ip_rcv_finish+0x92/0x320
[151995.117382]  [<ffffffff817590e1>] ip_rcv+0x291/0x3a0
[151995.117388]  [<ffffffff810ec402>] ? call_timer_fn+0xf2/0x120
[151995.117393]  [<ffffffff81758720>] ? inet_del_offload+0x40/0x40
[151995.117397]  [<ffffffff8171a7b4>] __netif_receive_skb_core+0x704/0xa60
[151995.117401]  [<ffffffff810b5400>] ? update_blocked_averages+0x310/0x520
[151995.117405]  [<ffffffff8171ab28>] __netif_receive_skb+0x18/0x60
[151995.117410]  [<ffffffff8171b928>] process_backlog+0xa8/0x150
[151995.117414]  [<ffffffff8171b06e>] net_rx_action+0x21e/0x360
[151995.117420]  [<ffffffff810859a1>] __do_softirq+0x101/0x290
[151995.117424]  [<ffffffff8182620c>] do_softirq_own_stack+0x1c/0x30
[151995.117426]  <EOI>  [<ffffffff810853e8>] do_softirq.part.19+0x38/0x40
[151995.117435]  [<ffffffff81085b9d>] do_softirq+0x1d/0x20
[151995.117439]  [<ffffffff81719723>] netif_rx_ni+0x33/0x80
[151995.117445]  [<ffffffff815ef199>] tun_get_user+0x509/0x890
[151995.117451]  [<ffffffff815ef5e7>] tun_chr_write_iter+0x57/0x70
[151995.117456]  [<ffffffff8120bfcc>] do_iter_readv_writev+0x6c/0xa0
[151995.117461]  [<ffffffff8120cb4f>] do_readv_writev+0x18f/0x230
[151995.117466]  [<ffffffff8181fd36>] ? __schedule+0x386/0xa10
[151995.117472]  [<ffffffff8120cc79>] vfs_writev+0x39/0x50
[151995.117477]  [<ffffffff8120d9a9>] SyS_writev+0x59/0xf0
[151995.117482]  [<ffffffff818244f2>] entry_SYSCALL_64_fastpath+0x16/0x71
[151995.117485] _________________
[151995.152238] ----- (irq/33-iwlwifi  :  23) -------
[151995.152244]  0000000000000000 000000003f6779b0 ffff8800a8d3b5b0 ffffffffc0aba053
[151995.152249]  ffffffffc0abc000 ffff8800a8d3b5f0 ffffffff810608c3 ffffffffc08da005
[151995.152253]  0000000000000400 ffff880137771b80 ffffffffc08dc300 ffff8800a8d3b890
[151995.152257] Call Trace:
[151995.152268]  [<ffffffffc0aba053>] handler_pre+0x43/0x54 [fslook]
[151995.152277]  [<ffffffff810608c3>] kprobe_ftrace_handler+0xb3/0x110
[151995.152283]  [<ffffffffc08da005>] ? ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.152291]  [<ffffffff81140160>] ftrace_ops_recurs_func+0x60/0xc0
[151995.152295]  [<ffffffffc00910d5>] 0xffffffffc00910d5
[151995.152300]  [<ffffffff817ac430>] ? nf_ip_checksum+0xd0/0x100
[151995.152304]  [<ffffffffc08da001>] ? ipv4_invert_tuple+0x1/0x20 [nf_conntrack_ipv4]
[151995.152309]  [<ffffffffc08da005>] ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.152319]  [<ffffffffc0a14749>] nf_ct_invert_tuple+0x49/0x80 [nf_conntrack]
[151995.152323]  [<ffffffffc08da005>] ? ipv4_invert_tuple+0x5/0x20 [nf_conntrack_ipv4]
[151995.152331]  [<ffffffffc0a14749>] ? nf_ct_invert_tuple+0x49/0x80 [nf_conntrack]
[151995.152338]  [<ffffffffc0a147c6>] nf_ct_invert_tuplepr+0x46/0x50 [nf_conntrack]
[151995.152344]  [<ffffffffc079d26f>] nf_nat_packet+0x7f/0xe0 [nf_nat]
[151995.152349]  [<ffffffffc08d0840>] nf_nat_ipv4_fn+0x1e0/0x220 [nf_nat_ipv4]
[151995.152354]  [<ffffffffc0a4e020>] ? iptable_nat_ipv4_fn+0x20/0x20 [iptable_nat]
[151995.152358]  [<ffffffffc08d08ae>] nf_nat_ipv4_in+0x2e/0x80 [nf_nat_ipv4]
[151995.152362]  [<ffffffffc0a4e0a5>] iptable_nat_ipv4_in+0x15/0x20 [iptable_nat]
[151995.152367]  [<ffffffff81751862>] nf_iterate+0x62/0x80
[151995.152372]  [<ffffffff817518f3>] nf_hook_slow+0x73/0xd0
[151995.152376]  [<ffffffff8175914f>] ip_rcv+0x2ff/0x3a0
[151995.152380]  [<ffffffff81758720>] ? inet_del_offload+0x40/0x40
[151995.152384]  [<ffffffff8171a7b4>] __netif_receive_skb_core+0x704/0xa60
[151995.152397]  [<ffffffffc087496d>] ? iwl_mvm_send_cmd+0x3d/0xb0 [iwlmvm]
[151995.152402]  [<ffffffff8171ab28>] __netif_receive_skb+0x18/0x60
[151995.152405]  [<ffffffff8171aba2>] netif_receive_skb_internal+0x32/0xa0
[151995.152408]  [<ffffffff8171b823>] napi_gro_receive+0xc3/0x120
[151995.152438]  [<ffffffffc092f502>] ieee80211_deliver_skb+0xb2/0x1a0 [mac80211]
[151995.152462]  [<ffffffffc0931809>] ieee80211_rx_handlers+0xd89/0x2550 [mac80211]
[151995.152476]  [<ffffffffc088538c>] ? iwl_mvm_rs_tx_status+0x65c/0xa30 [iwlmvm]
[151995.152481]  [<ffffffff81705f97>] ? skb_release_data+0xa7/0xd0
[151995.152504]  [<ffffffffc0933193>] ieee80211_prepare_and_rx_handle+0x1c3/0xab0 [mac80211]
[151995.152524]  [<ffffffffc0933d6d>] ieee80211_rx_napi+0x2ed/0x930 [mac80211]
[151995.152536]  [<ffffffffc0876766>] iwl_mvm_rx_rx_mpdu+0x406/0x710 [iwlmvm]
[151995.152546]  [<ffffffffc0871338>] iwl_mvm_rx+0x58/0x240 [iwlmvm]
[151995.152557]  [<ffffffffc06c534f>] iwl_pcie_rx_handle+0x69f/0x960 [iwlwifi]
[151995.152563]  [<ffffffff8102d8b0>] ? __switch_to+0x420/0x5a0
[151995.152572]  [<ffffffffc06c6717>] iwl_pcie_irq_handler+0x5b7/0x8d0 [iwlwifi]
[151995.152577]  [<ffffffff810dbac0>] ? irq_finalize_oneshot.part.35+0xe0/0xe0
[151995.152580]  [<ffffffff810dbae0>] irq_thread_fn+0x20/0x50
[151995.152584]  [<ffffffff810dbe28>] irq_thread+0x138/0x1c0
[151995.152587]  [<ffffffff810dbb80>] ? irq_forced_thread_fn+0x70/0x70
[151995.152590]  [<ffffffff810dbcf0>] ? irq_thread_check_affinity+0xc0/0xc0
[151995.152594]  [<ffffffff810a0528>] kthread+0xd8/0xf0
[151995.152597]  [<ffffffff810a0450>] ? kthread_create_on_node+0x1e0/0x1e0
[151995.152603]  [<ffffffff8182488f>] ret_from_fork+0x3f/0x70
[151995.152606]  [<ffffffff810a0450>] ? kthread_create_on_node+0x1e0/0x1e0
[151995.152608] _________________

上面两个代码都是在module中设置的,也就是说在postrouting和postrouting中都

那么现在的问题是,我通过sudo iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -j MASQUERADE 都设置了啥东西,看下系统调用吧

系统调用

最有可能的插入函数:__nf_conntrack_hash_insert:

static void __nf_conntrack_hash_insert(struct nf_conn *ct, 
                       unsigned int hash,
                       unsigned int reply_hash)
{
    hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
               &nf_conntrack_hash[hash]);
    hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
               &nf_conntrack_hash[reply_hash]);
}

为啥普通ping从虚机中ping

__nf_conntrack_confirm

nf_hook_slow --> nf_iterate --> nf_conntrack_confirm --> __nf_conntrack_confirm

ipv4_conntrack_in ---> nf_conntrack_in --> resolve_normal_ct --> init_conntrack --> __nf_conntrack_alloc --> nf_ct_invert_tuple 中会生成reply_tuple,并且将这个tuple 初始化到 ct->tuplehash[IP_CT_DIR_REPLY].tuple 中去;

在init_conntrack中会初始化relay反向的tuple,然后这个 tuple 中还有nf_nat_packet中会调用manip_pkt去修改数据包;这个

iptable_nat_ipv4_in --> nf_nat_ipv4_in ---> nf_nat_ipv4_fn ---> nf_nat_packet ---> nf_ct_invert_tuple 中应该如何去设置,这个就是在nat postrouting的钩子函数里面;

从流程图可以看出,牵扯到的几个关键函数都土黄色标注出来了。ip_nat_setup_info()函数主要是完成对数据包的连接跟踪记录ip_conntrack对象中相应成员的修改和替换,而manip_pkt()中才是真正对skb里面源/目的地址,端口以及数据包的校验和字段修改的地方。

ipt_register_table

nf_register_hooks

原文地址:https://www.cnblogs.com/honpey/p/8455026.html