net_generic函数分析

1.函数功能

        获取net->gen->ptr[id]数组中的指针,该指针指向各个模块储存在命名空间中的私有数据结构体,里面存放了各个模块的一些私有信息。

2.函数源码

文件路径:include/net/netns/generic.h

struct net_generic {
    union {
        struct {
            unsigned int len;
            struct rcu_head rcu;
        } s;

        DECLARE_FLEX_ARRAY(void *, ptr);
    };
};

static inline void *net_generic(const struct net *net, unsigned int id)
{
    struct net_generic *ng;
    void *ptr;

    rcu_read_lock();
    ng = rcu_dereference(net->gen);
    ptr = ng->ptr[id];
    rcu_read_unlock();

    return ptr;
}

3.函数分析

文件路径:include/net/net_namespace.h
struct net {
    ...
    struct net_generic __rcu    *gen;
    ...
}

文件路径:include/uapi/linux/stddef.h

/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */
#define __DECLARE_FLEX_ARRAY(T, member) \
    T member[0]

文件路径:include/linux/stddef.h

#define DECLARE_FLEX_ARRAY(TYPE, NAME) \
    __DECLARE_FLEX_ARRAY(TYPE, NAME)

文件路径:include/net/netns/generic.h

struct net_generic {
    union {
        struct {
            unsigned int len;
            struct rcu_head rcu;
        } s;
        //这里我理解为是一个指针数组 void* ptr[];
        //在网络子系统中存储某个模块的私有数据
        DECLARE_FLEX_ARRAY(void *, ptr);
    };
};

static inline void *net_generic(const struct net *net, unsigned int id)
{
    struct net_generic *ng;
    void *ptr;

    rcu_read_lock();
    //将net结构体的gen成员传给ng
    ng = rcu_dereference(net->gen);
    //ng->ptr是一个void* ptr[];通过id获取对应的指针
    ptr = ng->ptr[id];
    rcu_read_unlock();
    
    //返回某个模块在网络命名空间中存储的私有数据的指针
    return ptr;
}

4.函数调用

文件路径:net/mptcp/ctrl.c
static int mptcp_pernet_id;

#ifdef CONFIG_SYSCTL
static int mptcp_pm_type_max = __MPTCP_PM_TYPE_MAX;
#endif

//mptcp存储到net命名空间的私有数据结构
struct mptcp_pernet {
#ifdef CONFIG_SYSCTL
    struct ctl_table_header *ctl_table_hdr;
#endif

    unsigned int add_addr_timeout;
    unsigned int stale_loss_cnt;
    u8 mptcp_enabled;
    u8 checksum_enabled;
    u8 allow_join_initial_addr_port;
    u8 pm_type;
    char scheduler[MPTCP_SCHED_NAME_MAX];
};

static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
{
    //net_generic函数返回的是void *类型的指针
    //这里通过类型转换在mptcp_get_pernet函数返回成mptcp存储到net命名空间的私有数据结构指针
    return net_generic(net, mptcp_pernet_id);
}


//下面这些都是利用了mptcp_get_pernet函数获取到私有数据结构里的信息
int mptcp_is_enabled(const struct net *net)
{
    return mptcp_get_pernet(net)->mptcp_enabled;
}

unsigned int mptcp_get_add_addr_timeout(const struct net *net)
{
    return mptcp_get_pernet(net)->add_addr_timeout;
}

int mptcp_is_checksum_enabled(const struct net *net)
{
    return mptcp_get_pernet(net)->checksum_enabled;
}

int mptcp_allow_join_id0(const struct net *net)
{
    return mptcp_get_pernet(net)->allow_join_initial_addr_port;
}
(net, mptcp_pernet_id);
}

int mptcp_is_enabled(const struct net *net)
{
    return mptcp_get_pernet(net)->mptcp_enabled;
}

unsigned int mptcp_get_add_addr_timeout(const struct net *net)
{
    return mptcp_get_pernet(net)->add_addr_timeout;
}

int mptcp_is_checksum_enabled(const struct net *net)
{
    return mptcp_get_pernet(net)->checksum_enabled;
}

int mptcp_allow_join_id0(const struct net *net)
{
    return mptcp_get_pernet(net)->allow_join_initial_addr_port;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值