本文主要是介绍bridge-nf-call-iptables,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
static int __init br_init(void)
{
...
/* 网桥HOOK点注册 */
err = br_netfilter_init();
if (err)
goto err_out1;
...
/* 网桥处理接口 */
br_handle_frame_hook = br_handle_frame;
...
}
int __init br_netfilter_init(void)
{
int ret;
ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
...
return 0;
}
static struct nf_hook_ops br_nf_ops[] __read_mostly = {
{ .hook = br_nf_pre_routing,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_PRE_ROUTING,
.priority = NF_BR_PRI_BRNF, },
{ .hook = br_nf_local_in,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_IN,
.priority = NF_BR_PRI_BRNF, },
{ .hook = br_nf_forward_ip,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF - 1, },
{ .hook = br_nf_forward_arp,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF, },
{ .hook = br_nf_local_out,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT,
.priority = NF_BR_PRI_FIRST, },
{ .hook = br_nf_post_routing,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_POST_ROUTING,
.priority = NF_BR_PRI_LAST, },
{ .hook = ip_sabotage_in,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST, },
{ .hook = ip_sabotage_in,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST, },
};
http://blog.csdn.net/matt_mao/article/details/18702455
可以通过以下proc查看kernel是否开启了bridge-nf-call-iptables:
# cat /proc/sys/net/bridge/bridge-nf-call-iptables
1
这个proc是定义在以下位置:
net/bridge/br_netfilter.c
985 static ctl_table brnf_table[] = {...
993 {
994 .procname = "bridge-nf-call-iptables",
995 .data = &brnf_call_iptables,
996 .maxlen = sizeof(int),
997 .mode = 0644,
998 .proc_handler = brnf_sysctl_call_tables,
999 },
在桥的NF_BR_PRE_ROUTING处理函数中,会根据brnf_call_iptables的值判断是否需要去过一下iptables的NF_INET_PRE_ROUTING的hock点
net/bridge/br_netfilter.c
552 static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
553 const struct net_device *in,
554 const struct net_device *out,
555 int (*okfn)(struct sk_buff *))
556 {
...
572 #ifdef CONFIG_SYSCTL
// 在桥的处理中是否需要call iptables
573 if (!brnf_call_iptables)
574 return NF_ACCEPT;
575 #endif
576
// ip头的基本检查和ip_rcv做的动作类似
577 if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) &&
578 !IS_PPPOE_IP(skb))
579 return NF_ACCEPT;
580
581 nf_bridge_pull_encap_header_rcsum(skb);
582
583 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
584 goto inhdr_error;
585
586 iph = ip_hdr(skb);
587 if (iph->ihl < 5 || iph->version != 4)
588 goto inhdr_error;
589
590 if (!pskb_may_pull(skb, 4 * iph->ihl))
591 goto inhdr_error;
592
593 iph = ip_hdr(skb);
594 if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0)
595 goto inhdr_error;
596
597 len = ntohs(iph->tot_len);
598 if (skb->len < len || len < 4 * iph->ihl)
599 goto inhdr_error;
600
601 pskb_trim_rcsum(skb, len);
602
603 /* BUG: Should really parse the IP options here. */
604 memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
605
606 nf_bridge_put(skb->nf_bridge);
607 if (!nf_bridge_alloc(skb))
608 return NF_DROP;
609 if (!setup_pre_routing(skb))
610 return NF_DROP;
611 store_orig_dstaddr(skb);
612
// 进入iptables的NF_INET_PRE_ROUTING
613 NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
614 br_nf_pre_routing_finish);
615
616 return NF_STOLEN;
617
618 inhdr_error:
619 // IP_INC_STATS_BH(IpInHdrErrors);
620 out:
621 return NF_DROP;
622 }
这篇关于bridge-nf-call-iptables的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!