Add the br_add_if function to the bridge device

Source: Internet
Author: User

The following figure shows the flowchart of the br_add_if function in understanding Linux Network internals.

As shown in the figure, the function processing process is roughly as follows:
1. sanity check.
The physical device must not be a loopback device or an Ethernet device. The physical device must not be a bridge device. The physical device must not be a port of another bridge;

2. Allocate and initialize the port description structure net_bridge_port. It is the link between a bridge device and a physical device. here we can see its definition:
Struct net_bridge_port
{
Struct net_bridge * BR; // the bridge device where the port is located
Struct net_device * dev; // physical device corresponding to the port
Struct list_head list; // use this field to link all ports to the port_list linked list of the bridge device.
/* The following are STP protocol fields */
U8 priority; // The priority specified by the user. The default value is 0x8000> br_port_bits (10). Only 6 bits are used.
U8 state; // port status, including blocking and forwarding
2010port_no;
Unsigned char topology_change_ack; // TPA flag
Unsigned char config_pending; // This field is set when the BPDU is received and the hold timer is not reached. When the hold is received, the BPDU is sent.
Port_id; // port ID, including the port number (10 bits) and priority (6 bits ).
Port_id designated_port;
Bridge_id designated_root; // root bridge ID
Bridge_id designated_bridge;
U32 path_cost;
U32 designated_cost;

Struct timer_list forward_delay_timer;
Struct timer_list hold_timer;
Struct timer_list message_age_timer;
Struct kobject kobj;
Struct rcu_head RCU;
};
In the new_nbp function, almost all net_bridge_port fields are initialized. Note: to find a method that does not use a port number, first set a bitmap to traverse the port numbers of all ports and set the bits corresponding to the port number on the in-place map, the first 0 bit is the new port_no. You can also see that the br_init_port function initializes the port to the specified port (designated port) and sets the status to blocking (br_state_blocking ). Initialize three timers, delay and forward (note that the bridge timer and port timer are different. The bridge timer includes hello, TCN and TC, and the garbage collection timer used by the kernel)

3. Set the physical device to the hybrid mode because the bridge must be able to accept all frames;

4. Call br_fdb_insert to add the ethernet address of the port to the forwarding information library. This function will be analyzed later.

5. Add port information to sysfs

6. link the port list field to the port_list linked list of the bridge device.

7. Call br_stp_recalculate_bridge_id to recalculate the bridge ID. Because the bridge ID is related to the MAC address, priority, and link overhead of the port, you must recalculate the bridge ID for each port added or deleted. Let's take a look at how to calculate it.
First, traverse all ports, find the minimum MAC address, and then compare it with the current MAC address of the bridge (the MAC address of the bridge is the MAC address of the smallest port). If the MAC address of the bridge is the same, return, otherwise, call br_stp_change_bridge_id to change the bridge ID.
Void br_stp_change_bridge_id (struct net_bridge * Br, const unsigned char * ADDR)
{
/* Shoshould be aligned on 2 bytes for compare_ether_addr ()*/
Unsigned short oldaddr_aligned [eth_alen> 1];
Unsigned char * oldaddr = (unsigned char *) oldaddr_aligned;
Struct net_bridge_port * P;
Int wasroot;

Wasroot = br_is_root_bridge (BR); // compare bridge_id and designated_root to determine whether the bridge is a root bridge.

Memcpy (oldaddr, Br-> bridge_id.addr, eth_alen); // save the old ID
Memcpy (Br-> bridge_id.addr, ADDR, eth_alen); // set the new ID
Memcpy (Br-> Dev-> dev_addr, ADDR, eth_alen); // the MAC address of the bridge device must be changed.

List_for_each_entry (p, & Br-> port_list, list ){
If (! Compare_ether_addr (p-> designated_bridge.addr, oldaddr ))
Memcpy (p-> designated_bridge.addr, ADDR, eth_alen );

// Change the root bridge ID of all ports (can the root bridge be different for all ports? Why not put them in the bridge ?)
If (! Compare_ether_addr (p-> designated_root.addr, oldaddr ))
Memcpy (p-> designated_root.addr, ADDR, eth_alen );
}

// Re-elect the root port and the specified port because the root port may change after the port is added

// These two functions will be detailed later. The function is to elect the root port and the specified port and set a new status.

Br_configuration_update (BR );

Br_port_state_selection (BR );

If (br_is_root_bridge (BR )&&! Wasroot)

Br_become_root_bridge (BR );

}

 

8. Start the new bridge port. Set the port status when starting.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.