2007年3月20日 星期二

iptables 和 ebtables 的關係與封包流程整理一下

PREROUTING
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_FIRST ip_sabotage_in (INT_MIN)
ip_conntrack_standalone.c ip_conntrack_defrag_ops NF_IP_PRI_CONNTRACK_DEFRAG ip_conntrack_defrag (-400)
iptable_raw.c ipt_ops NF_IP_PRI_RAW ipt_hook (-300)
ip_conntrack_standalone.c ip_conntrack_in_ops NF_IP_PRI_CONNTRACK ip_conntrack_in (-200)
iptable_mangle.c ipt_ops NF_IP_PRI_MANGLE ipt_route_hook (-150)
iptable_tproxy.c ip_tproxy_pre_ops -130 ip_tproxy_fn (-130)
ip_nat_standalone.c ip_nat_in_ops NF_IP_PRI_NAT_DST ip_nat_fn (-100)

INPUT
iptable_mangle.c ipt_ops NF_IP_PRI_MANGLE ipt_route_hook (-150)
iptable_filter.c ipt_ops NF_IP_PRI_FILTER ipt_hook (0)
ip_nat_standalone.c ip_nat_local_in_ops NF_IP_PRI_NAT_SRC ip_nat_fn (100)
ip_conntrack_standalone.c ip_conntrack_local_in_ops NF_IP_PRI_LAST-1 ip_confirm (INT_MAX-1)

FORWARD
net/bridge/br_netfilter.c br_nf_ops NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD ip_sabotage_out (-175)
iptable_mangle.c ipt_ops NF_IP_PRI_MANGLE ipt_route_hook (-150)
iptable_filter.c ipt_ops NF_IP_PRI_FILTER ipt_hook (0)

OUTPUT
ip_conntrack_standalone.c ip_conntrack_defrag_local_out_ops NF_IP_PRI_CONNTRACK_DEFRAG ip_conntrack_defrag (-400)
iptable_raw.c ipt_ops NF_IP_PRI_RAW ipt_hook (-300)
ip_conntrack_standalone.c ip_conntrack_local_out_ops NF_IP_PRI_CONNTRACK ip_conntrack_local (-200)
iptable_mangle.c ipt_ops NF_IP_PRI_MANGLE ipt_local_hook (-150)
iptable_tproxy.c ip_tproxy_local_out_ops -130 ip_tproxy_fn (-130)
ip_nat_standalone.c ip_nat_local_out_ops NF_IP_PRI_NAT_DST ip_nat_local_fn (-100)
net/bridge/br_netfilter.c br_nf_ops NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT ip_sabotage_out (-50)
iptable_filter.c ipt_ops NF_IP_PRI_FILTER ipt_hook (0)

POSTROUTING
net/bridge/br_netfilter.c br_nf_ops NF_IP_PRI_FIRST ip_sabotage_out
iptable_tproxy.c ip_tproxy_post_ops -130 ip_tproxy_fn (-130)
iptable_mangle.c ipt_ops NF_IP_PRI_MANGLE ipt_route_hook (-150)
ip_nat_standalone.c ip_nat_out_ops NF_IP_PRI_NAT_SRC ip_nat_out (100)
ip_conntrack_standalone.c ip_conntrack_out_ops NF_IP_PRI_LAST ip_refrag (INT_MAX)

Please refer to the diagram on the http://l7-filter.sourceforge.net/PacketFlow.png

enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK_DEFRAG = -400,
NF_IP_PRI_RAW = -300,
NF_IP_PRI_SELINUX_FIRST = -225,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_LAST = INT_MAX,
}; 作者: vincent 時間: 2006-8-4 09:17 PM

bridge path ==> [ebtables|iptables]/table-name HOOK-name

net/core/dev.c
netif_receive_skb
net/bridge/br_input.c:
br_handle_frame
net/bridge/netfilter/ebtable_broute.c
ebt_broute
ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, &broute_table); ==> ebtables/BROUTE BROUTING

net/bridge/br_input.c:
br_handle_frame
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish); ==> ebtables/NAT PREROUTING

net/bridge/br_netfilter.c:
br_nf_pre_routing
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/CONNTRACK-DEFRAG PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/RAW PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/CONNTRACK PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/MANGLE PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/TPROXY PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/NAT PREROUTING

net/bridge/br_input.c:
br_flood_forward
net/bridge/br_forward.c:
br_flood_forward
net/bridge/br_forward.c:
br_flood
net/bridge/br_forward.c:
__br_forward
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, br_forward_finish); ==> ebtables/FILTER FORWARD

net/bridge/br_netfilter.c:
br_nf_forward_ip
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), bridge_parent(out), br_nf_forward_finish); ==. iptables/MANGLE FORWARD
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), bridge_parent(out), br_nf_forward_finish); ==. iptables/FILTER FORWARD

NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, skb->dev, br_forward_finish, 1); 作者: vincent 時間: 2006-8-5 10:42 PM


PREROUTING
net/bridge/netfilter/ebtable_nat.c NF_BR_PRI_NAT_DST_BRIDGED ebt_nat_dst (-300)
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_BRNF br_nf_pre_routing (0)


INPUT
net/bridge/netfilter/ebtable_filter.c ebt_ops_filter NF_BR_PRI_FILTER_BRIDGED ebt_hook (-200)
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_BRNF br_nf_local_in (0)


FORWARD
net/bridge/netfilter/ebtable_filter.c ebt_ops_filter NF_BR_PRI_FILTER_BRIDGED ebt_hook (-200)
net/bridge/br_netfilter.c br_nf_ops (NF_BR_PRI_BRN - 1) br_nf_forward_ip (-1)
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_BRN br_nf_forward_arp (0)

OUTPUT
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_FIRST br_nf_local_out (INT_MIN)
net/bridge/netfilter/ebtable_nat.c NF_BR_PRI_NAT_DST_OTHER ebt_nat_dst (100)
net/bridge/netfilter/ebtable_filter.c ebt_ops_filter NF_BR_PRI_FILTER_OTHER ebt_hook (200)

POSTROUTING
net/bridge/netfilter/ebtable_nat.c NF_BR_PRI_NAT_SRC ebt_nat_src (300)
net/bridge/br_netfilter.c br_nf_ops NF_BR_PRI_LAST br_nf_post_routing (INT_MAX)

BROUTING


enum nf_br_hook_priorities {
NF_BR_PRI_FIRST = INT_MIN,
NF_BR_PRI_NAT_DST_BRIDGED = -300,
NF_BR_PRI_FILTER_BRIDGED = -200,
NF_BR_PRI_BRNF = 0,
NF_BR_PRI_NAT_DST_OTHER = 100,
NF_BR_PRI_FILTER_OTHER = 200,
NF_BR_PRI_NAT_SRC = 300,
NF_BR_PRI_LAST = INT_MAX,
}; 作者: vincent 時間: 2006-8-15 10:11 PM

bridge path ==> [ebtables|iptables]/table-name HOOK-name

## BROUTE Chain
net/core/dev.c
netif_receive_skb

net/core/dev.c
handle_bridge

net/core/dev.c
br_handle_frame_hook

/* Here br_handle_frame_hook is a callback function pointer
net/bridge/br.c
br_init
br_handle_frame_hook = br_handle_frame;
include/linux/if_bridge.h:extern int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
*/

net/bridge/br_input.c:
br_handle_frame

# br_handle_frame will return 1 and terminate terminate the packet traversal travel

net/bridge/netfilter/ebtable_broute.c
ebt_broute
ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, &broute_table); ==> ebtables/BROUTE BROUTING

## PREROUTING Chain
net/bridge/br_input.c:
br_handle_frame
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish); ==> ebtables/NAT PREROUTING
ebt_nat_dst
br_nf_pre_routing

ebtables will traversal Netfilter/Prerouting in the ebtables/PREROUTING after traversal (ebtables/NAT PREROUTING) as follows

// Due to ebtables (PF_BRIDGE) prerouting hook function : br_nf_pre_routing
net/bridge/br_netfilter.c:
br_nf_pre_routing
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/CONNTRACK-DEFRAG PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/RAW PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/CONNTRACK PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/MANGLE PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/TPROXY PREROUTING
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish); ==> iptables/NAT PREROUTING

# (br_nf_pre_routing will always return NF_STOLEN, so the br_handle_frame_finish function doesn;t need to run again!)

net/bridge/br_netfilter.c:
br_nf_pre_routing_finish
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish_bridge, 1);
or
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish, 1);
// No hook currently less than thresh 1

So either run
net/bridge/br_netfilter.c:
br_nf_pre_routing_finish_bridge
or
net/bridge/br_input.c:
br_handle_frame_finish

# This is the final(finished) function of the ebtables / PREROUTING chain
# Because the br_nf_pre_routing return the NF_STOLEN verdict, so we will not run the br_handle_frame_finish function again
net/bridge/br_input.c:
br_handle_frame_finish

//FORWARD path


net/bridge/br_forward.c:
br_flood_forward
net/bridge/br_forward.c:
br_flood
br_flood will call callback function (__packet_hook)
net/bridge/br_forward.c:
__br_forward
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, br_forward_finish); ==> ebtables/FILTER FORWARD
ebt_hook
br_nf_forward_ip
br_nf_forward_arp


net/bridge/br_netfilter.c:
br_nf_forward_ip
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), bridge_parent(out), br_nf_forward_finish);
## it will return NF_STOLEN verdict

net/bridge/br_netfilter.c:
br_nf_forward_arp
NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in, (struct net_device *)out, br_nf_forward_finish);
## it will return NF_STOLEN verdict


net/bridge/br_netfilter.c:
br_nf_forward_ip
ip_sabotage_out
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), bridge_parent(out), br_nf_forward_finish); ==> iptables/MANGLE FORWARD
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), bridge_parent(out), br_nf_forward_finish); ==> iptables/FILTER FORWARD

# br_nf_forward_ip will return NF_STOLEN verdict

net/bridge/br_netfilter.c:
br_nf_forward_finish
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, skb->dev, br_forward_finish, 1);
// No hook currently less than thresh 1

net/bridge/br_forward.c:
br_forward_finish
NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, br_dev_queue_push_xmit);

ebt_nat_src
br_nf_post_routing

net/bridge/br_netfilter.c:
br_nf_post_routing
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, br_dev_queue_push_xmit);
## it will return NF_STOLEN verdict

net/bridge/br_netfilter.c:
br_nf_post_routing
ip_sabotage_out
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, br_dev_queue_push_xmit); ==> iptables/TPROXY POSTROUTING
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, br_dev_queue_push_xmit); ==> iptables/MANGLE POSTROUTING
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, br_dev_queue_push_xmit); ==> iptables/NAT POSTROUTING
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, br_dev_queue_push_xmit); ==> iptables/CONNTRACK POSTROUTING

net/bridge/br_forward.c:
br_dev_queue_push_xmit
## return 0

沒有留言: