2007年5月20日 星期日

bridge packet traversal

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

沒有留言: