内核获取网络设备的网桥接口

Linux内核中有两种获取网络设备的桥接口方法,其中一种是在控制路径上;另一种是在数据路径上。


控制路径


用户平面的程序brctl下发控制命令,比如setpathcost和setportprio命令以port number为参数下发到内核,内核使用br_get_port函数遍历网桥上的接口列表,最终找到对应的网桥接口。br_get_port函数需要在获得了网桥spinlock锁后调用,防止对port_list操作的不一致发送。


Usage: brctl [commands]
commands:
        setpathcost     <bridge> <port> <cost>  set path cost
        setportprio     <bridge> <port> <prio>  set port priority


struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no)
{
    struct net_bridge_port *p;

    list_for_each_entry_rcu(p, &br->port_list, list) {
        if (p->port_no == port_no)
            return p;
    }
}


数据路径


在数据路径上,调用函数br_port_get_rcu获取对应网桥接口,效率高于控制路径上的br_get_port函数。首先在添加桥接口时(br_add_if),调用函数(netdev_rx_handler_register)注册rx_handler,将网桥接口赋值给rx_handler_data变量,在数据路径上,比如br_handle_frame_finish中,使用br_port_get_rcu可直接获得网桥接口结构体。


static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
{
    return rcu_dereference(dev->rx_handler_data);
}

int netdev_rx_handler_register(struct net_device *dev,
                   rx_handler_func_t *rx_handler,
                   void *rx_handler_data)
{
    rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
    rcu_assign_pointer(dev->rx_handler, rx_handler);
}
int br_add_if(struct net_bridge *br, struct net_device *dev)
{
	struct net_bridge_port *p;
	
    p = new_nbp(br, dev);
    err = netdev_rx_handler_register(dev, br_handle_frame, p);
}


内核版本

Linux-3.10.0



猜你喜欢

转载自blog.csdn.net/sinat_20184565/article/details/80390514
今日推荐