net/core/dev.c
2151 static inline struct sk_buff *handle_bridge(struct sk_buff *skb, 2152 struct packet_type **pt_prev, int *ret, 2153 struct net_device *orig_dev) 2154 { 2155 struct net_bridge_port *port; 2156 2157 if (skb->pkt_type == PACKET_LOOPBACK || 2158 (port = rcu_dereference(skb->dev->br_port)) == NULL) 2159 return skb; 2160 2161 if (*pt_prev) { 2162 *ret = deliver_skb(skb, *pt_prev, orig_dev); 2163 *pt_prev = NULL; 2164 } 2165 2166 return br_handle_frame_hook(port, skb); 2167 }
35 static int __init br_init(void) 36 { 37 int err; 38 39 err = stp_proto_register(&br_stp_proto); 40 if (err < 0) { 41 printk(KERN_ERR "bridge: can't register sap for STP\n"); 42 return err; 43 } 44 // 使用SLAB,初始化fdb 45 err = br_fdb_init(); 46 if (err) 47 goto err_out; 48 49 err = register_pernet_subsys(&br_net_ops); 50 if (err) 51 goto err_out1; 52 // 初始化桥的netfilter 53 err = br_netfilter_init(); 54 if (err) 55 goto err_out2; 56 // 注册通知链 57 err = register_netdevice_notifier(&br_device_notifier); 58 if (err) 59 goto err_out3; 60 // netlink初始化 61 err = br_netlink_init(); 62 if (err) 63 goto err_out4; 64 65 brioctl_set(br_ioctl_deviceless_stub); // 初始化br_handle_frame_hook 66 br_handle_frame_hook = br_handle_frame; 67 68 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) 69 br_fdb_test_addr_hook = br_fdb_test_addr; 70 #endif 71 72 return 0; 73 err_out4: 74 unregister_netdevice_notifier(&br_device_notifier); 75 err_out3: 76 br_netfilter_fini(); 77 err_out2: 78 unregister_pernet_subsys(&br_net_ops); 79 err_out1: 80 br_fdb_fini(); 81 err_out: 82 stp_proto_unregister(&br_stp_proto); 83 return err; 84 }
120 struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) 121 { 122 const unsigned char *dest = eth_hdr(skb)->h_dest; 123 int (*rhook)(struct sk_buff *skb); 124 125 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 126 goto drop; 127 128 skb = skb_share_check(skb, GFP_ATOMIC); 129 if (!skb) 130 return NULL; 131 132 if (unlikely(is_link_local(dest))) { 133 /* Pause frames shouldn't be passed up by driver anyway */ 134 if (skb->protocol == htons(ETH_P_PAUSE)) 135 goto drop; 136 137 /* If STP is turned off, then forward */ 138 if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) 139 goto forward; 140 141 if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, 142 NULL, br_handle_local_finish)) 143 return NULL; /* frame consumed by filter */ 144 else 145 return skb; /* continue processing */ 146 } 147 148 forward: 149 switch (p->state) { 150 case BR_STATE_FORWARDING: 151 rhook = rcu_dereference(br_should_route_hook); 152 if (rhook != NULL) { 153 if (rhook(skb)) 154 return skb; 155 dest = eth_hdr(skb)->h_dest; 156 } // 注意此处没有break 157 /* fall through */ 158 case BR_STATE_LEARNING: 159 if (!compare_ether_addr(p->br->dev->dev_addr, dest)) 160 skb->pkt_type = PACKET_HOST; 161 162 NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 163 br_handle_frame_finish); 164 break; 165 default: 166 drop: 167 kfree_skb(skb); 168 } 169 return NULL; 170 }
38 int br_handle_frame_finish(struct sk_buff *skb) 39 { 40 const unsigned char *dest = eth_hdr(skb)->h_dest; 41 struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); 42 struct net_bridge *br; 43 struct net_bridge_fdb_entry *dst; 44 struct sk_buff *skb2; 45 46 if (!p || p->state == BR_STATE_DISABLED) 47 goto drop; 48 49 /* insert into forwarding database after filtering to avoid spoofing */ 50 br = p->br; // 更新fdb 51 br_fdb_update(br, p, eth_hdr(skb)->h_source); 52 53 if (p->state == BR_STATE_LEARNING) 54 goto drop; 55 56 /* The packet skb2 goes to the local host (NULL to skip). */ 57 skb2 = NULL; 58 59 if (br->dev->flags & IFF_PROMISC) 60 skb2 = skb; 61 62 dst = NULL; 63 64 if (is_multicast_ether_addr(dest)) { 65 br->dev->stats.multicast++; 66 skb2 = skb; 67 } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { 68 skb2 = skb; 69 /* Do not forward the packet since it's local. */ 70 skb = NULL; 71 } 72 73 if (skb2 == skb) 74 skb2 = skb_clone(skb, GFP_ATOMIC); 75 76 if (skb2) // 将dev改为桥,发往netif_receive_skb 77 br_pass_frame_up(br, skb2); 78 79 if (skb) { 80 if (dst) // 转发到学习到的对应端口 81 br_forward(dst->dst, skb); 82 else // flood转发 83 br_flood_forward(br, skb); 84 } 85 86 out: 87 return 0; 88 drop: 89 kfree_skb(skb); 90 goto out; 91 }