You are on page 1of 7

netif_receive_skb ()

view plaincopy to clipboardprint?


1. skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);

linux
LAN1LAN2 1.0 2.0 eth0 eth1
Bridge Bridge Bridge

STP
DISABLED
BLOCKING
LISTENING
LEARNING
FORWARDING
br_add_bridge [net\bridge\br_if.c]
SIOCBRADDBR ioctl
br_add_bridge

view plaincopy to clipboardprint?


1. dev = new_bridge_dev(net, name);
dev->dev.type br_type br_type
view plaincopy to clipboardprint?
1. SET_NETDEV_DEVTYPE(dev, &br_type);
2. static struct device_type br_type = {

3. .name = "bridge",
4. };
dev ifconfig

view plaincopy to clipboardprint?


1. ret = register_netdevice(dev);
sysfs
view plaincopy to clipboardprint?
1. ret = br_sysfs_addbr(dev);

br_add_if() [net\bridge\br_if.c]
SIOCBRADDIF ioctl br_add_if
net_bridge_port p br->port_list port_nop->br
brp->state BR_STATE_DISABLED p
view plaincopy to clipboardprint?
1. p = new_nbp(br, dev);
p CAM CAM mac
p

CAM local []CAM


net_bridge hash addr hash net_bridge_fdb_entry

dst
net_bridge_port
view plaincopy to clipboardprint?
1. err = br_fdb_insert(br, p, dev->dev_addr);

br_port pnet_bridge
net_bridge_port
dev

br_port

view plaincopy to clipboardprint?


1. rcu_assign_pointer(dev->br_port, p);
net_bridge_port br port_list net_bridge_port
port_no port_no br->port_list net_bridge_port
port_no [
]
view plaincopy to clipboardprint?
1. list_add_rcu(&p->list, &br->port_list);

ID br->port_list net_bridge_port addr


ID
view plaincopy to clipboardprint?
1. br_stp_recalculate_bridge_id(br);
br_del_bridge() add_del_if()

netif_receive_skb()->handle_bridge()
view plaincopy to clipboardprint?
1. static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
2.
struct packet_type **pt_prev, int *ret,
3.
struct net_device *orig_dev)
4. {
5. struct net_bridge_port *port;
6.
7. if (skb->pkt_type == PACKET_LOOPBACK ||
8.
(port = rcu_dereference(skb->dev->br_port)) == NULL)
9. return skb;
10.
11. if (*pt_prev) {
12. *ret = deliver_skb(skb, *pt_prev, orig_dev);
13. *pt_prev = NULL;
14. }
15.
16. return br_handle_frame_hook(port, skb);
17. }
1.
lo
dev->br_port (skb->dev
dev->br_port p)

2. ptype_all pt_prev ptype_all

3. br_handle_frame_hook br_init() [net\bridge\br.c]


br_handle_frame_hook = br_handle_frame;
br_handle_frame() [net\bridge\br_input.c]
br_handle_frame()
802.1q users
view plaincopy to clipboardprint?

1. skb = skb_share_check(skb, GFP_ATOMIC);


01:80:c2:00:00:0X STP
br_handle_local_finish()
view plaincopy to clipboardprint?
1. if (unlikely(is_link_local(dest))){
2.
3. if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
4.
NULL, br_handle_local_finish))
5. return NULL; /* frame consumed by filter */
6. else
7. return skb;
8. }
br_handle_local_finish()
mac

( CAM )
view plaincopy to clipboardprint?
1. static int br_handle_local_finish(struct sk_buff *skb)
2. {
3. struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
4.
5. if (p)
6. br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
7. return 0; /* process further */
8. }
br_handle_frame()
state= BR_STATE_FORWARDING

br_should_route_hook skb
state=BR_STATE_LEARNING
view plaincopy to clipboardprint?
1. rhook = rcu_dereference(br_should_route_hook);
2. if (rhook != NULL) {
3. if (rhook(skb))
4. return skb;
5. dest = eth_hdr(skb)->h_dest;
6. }
state= BR_STATE_LEARNING pkt_type
PACKET_HOST br_handle_frame_finish
PACKET_HOST
netif_receive_skb()()

view plaincopy to clipboardprint?


1. if (!compare_ether_addr(p->br->dev->dev_addr, dest))
2. skb->pkt_type = PACKET_HOST;
3. NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
4. br_handle_frame_finish);

view plaincopy to clipboardprint?


1. kfree_skb(skb);

br_handle_frame_finish()
mac CAM hub

view plaincopy to clipboardprint?


1. br_fdb_update(br, p, eth_hdr(skb)->h_source);
LEARNING CAM

view plaincopy to clipboardprint?


1. if (p->state == BR_STATE_LEARNING)
2. goto drop;
FORWARDING
1. br_flood_forward(br, skb, skb2);
2. CAM br_flood_forward(br, skb, skb2);
3. CAM br_forward(dst>dst, skb, skb2);
4. CAM
br_pass_frame_upbr_pass_frame_up(skb2);
br_handle_frame_finish()
br_pass_frame_up()
(
802.1q) skb
netif_receive_skb()
view plaincopy to clipboardprint?
1. skb->dev = brdev;
2. return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
3.
netif_receive_skb);

netif_receive_skb()->handle_bridge() skb->dev
dev>br_port br_port

view plaincopy to clipboardprint?


1. if (skb->pkt_type == PACKET_LOOPBACK ||
2.
(port = rcu_dereference(skb->dev->br_port)) == NULL)
3. return skb;

br_dev_xmit()[net\bridge\br_device.c]
br_multicast_deliver() br_flood_deliver() br_deliver() skb>dev brdev dev

You might also like