net/mptcp/mib.c文件源码分析

1.概述       

        MIBManagement Information Base(管理信息库)的缩写。MIB 是一个标准化的数据库,用于存储与网络设备(如路由器、交换机、服务器等)相关的管理信息。它定义了设备上可被监控和管理的各种信息的结构,这些信息通常通过 SNMP(简单网络管理协议,Simple Network Management Protocol)进行访问和管理。

        SNMPSimple Network Management Protocol,简单网络管理协议)是一种用于管理和监控网络设备(如路由器、交换机、服务器、打印机等)状态的标准协议

        查看mib的相关信息,可以看到是很多协议的一些统计信息,转发、丢包等数据。

2.源代码

文件路径:net/mptcp/mib.c
// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/seq_file.h>
#include <net/ip.h>
#include <net/mptcp.h>
#include <net/snmp.h>
#include <net/net_namespace.h>

#include "mib.h"

static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE),
        SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE),
        SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK),
        SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
        SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
        SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
        SNMP_MIB_ITEM("MPFallbackTokenInit", MPTCP_MIB_TOKENFALLBACKINIT),
        SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
        SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
        SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX),
        SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX),
        SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
        SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
        SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
        SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
        SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
        SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
        SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
        SNMP_MIB_ITEM("DataCsumErr", MPTCP_MIB_DATACSUMERR),
        SNMP_MIB_ITEM("OFOQueueTail", MPTCP_MIB_OFOQUEUETAIL),
        SNMP_MIB_ITEM("OFOQueue", MPTCP_MIB_OFOQUEUE),
        SNMP_MIB_ITEM("OFOMerge", MPTCP_MIB_OFOMERGE),
        SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW),
        SNMP_MIB_ITEM("DuplicateData", MPTCP_MIB_DUPDATA),
        SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR),
        SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX),
        SNMP_MIB_ITEM("AddAddrTxDrop", MPTCP_MIB_ADDADDRTXDROP),
        SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD),
        SNMP_MIB_ITEM("EchoAddTx", MPTCP_MIB_ECHOADDTX),
        SNMP_MIB_ITEM("EchoAddTxDrop", MPTCP_MIB_ECHOADDTXDROP),
        SNMP_MIB_ITEM("PortAdd", MPTCP_MIB_PORTADD),
        SNMP_MIB_ITEM("AddAddrDrop", MPTCP_MIB_ADDADDRDROP),
        SNMP_MIB_ITEM("MPJoinPortSynRx", MPTCP_MIB_JOINPORTSYNRX),
        SNMP_MIB_ITEM("MPJoinPortSynAckRx", MPTCP_MIB_JOINPORTSYNACKRX),
        SNMP_MIB_ITEM("MPJoinPortAckRx", MPTCP_MIB_JOINPORTACKRX),
        SNMP_MIB_ITEM("MismatchPortSynRx", MPTCP_MIB_MISMATCHPORTSYNRX),
        SNMP_MIB_ITEM("MismatchPortAckRx", MPTCP_MIB_MISMATCHPORTACKRX),
        SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR),
        SNMP_MIB_ITEM("RmAddrDrop", MPTCP_MIB_RMADDRDROP),
        SNMP_MIB_ITEM("RmAddrTx", MPTCP_MIB_RMADDRTX),
        SNMP_MIB_ITEM("RmAddrTxDrop", MPTCP_MIB_RMADDRTXDROP),
        SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
        SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
        SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
        SNMP_MIB_ITEM("MPFailTx", MPTCP_MIB_MPFAILTX),
        SNMP_MIB_ITEM("MPFailRx", MPTCP_MIB_MPFAILRX),
        SNMP_MIB_ITEM("MPFastcloseTx", MPTCP_MIB_MPFASTCLOSETX),
        SNMP_MIB_ITEM("MPFastcloseRx", MPTCP_MIB_MPFASTCLOSERX),
        SNMP_MIB_ITEM("MPRstTx", MPTCP_MIB_MPRSTTX),
        SNMP_MIB_ITEM("MPRstRx", MPTCP_MIB_MPRSTRX),
        SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED),
        SNMP_MIB_ITEM("SubflowStale", MPTCP_MIB_SUBFLOWSTALE),
        SNMP_MIB_ITEM("SubflowRecover", MPTCP_MIB_SUBFLOWRECOVER),
        SNMP_MIB_ITEM("SndWndShared", MPTCP_MIB_SNDWNDSHARED),
        SNMP_MIB_ITEM("RcvWndShared", MPTCP_MIB_RCVWNDSHARED),
        SNMP_MIB_ITEM("RcvWndConflictUpdate", MPTCP_MIB_RCVWNDCONFLICTUPDATE),
        SNMP_MIB_ITEM("RcvWndConflict", MPTCP_MIB_RCVWNDCONFLICT),
        SNMP_MIB_SENTINEL
};

/* mptcp_mib_alloc - allocate percpu mib counters
 *
 * These are allocated when the first mptcp socket is created so
 * we do not waste percpu memory if mptcp isn't in use.
 */
bool mptcp_mib_alloc(struct net *net)
{
        struct mptcp_mib __percpu *mib = alloc_percpu(struct mptcp_mib);

        if (!mib)
                return false;

        if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib))
                free_percpu(mib);

        return true;
}

void mptcp_seq_show(struct seq_file *seq)
{
        unsigned long sum[ARRAY_SIZE(mptcp_snmp_list) - 1];
        struct net *net = seq->private;
        int i;

        seq_puts(seq, "MPTcpExt:");
        for (i = 0; mptcp_snmp_list[i].name; i++)
                seq_printf(seq, " %s", mptcp_snmp_list[i].name);

        seq_puts(seq, "\nMPTcpExt:");

        memset(sum, 0, sizeof(sum));
        if (net->mib.mptcp_statistics)
                snmp_get_cpu_field_batch(sum, mptcp_snmp_list,
                                         net->mib.mptcp_statistics);

        for (i = 0; mptcp_snmp_list[i].name; i++)
                seq_printf(seq, " %lu", sum[i]);

        seq_putc(seq, '\n');
}

3.代码分析

文件路径:include/net/snmp.h
//这个宏只是定义了一个指针类型的变量
//如:struct mptcp_mib __percpu *mptcp_statistics
/*
struct mptcp_mib {
    unsigned long mibs[LINUX_MIB_MPTCP_MAX];
};
*/
#define DEFINE_SNMP_STAT(type, name)    \
    __typeof__(type) __percpu *name

文件路径:include/net/netns/mib.h
//可以看到这个结构存放了很多协议的mib信息
struct netns_mib {
    DEFINE_SNMP_STAT(struct ipstats_mib, ip_statistics);
#if IS_ENABLED(CONFIG_IPV6)
    DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
#endif

    DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics);
    DEFINE_SNMP_STAT(struct linux_mib, net_statistics);

    DEFINE_SNMP_STAT(struct udp_mib, udp_statistics);
#if IS_ENABLED(CONFIG_IPV6)
    DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
#endif

#ifdef CONFIG_XFRM_STATISTICS
    DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
#endif
#if IS_ENABLED(CONFIG_TLS)
    DEFINE_SNMP_STAT(struct linux_tls_mib, tls_statistics);
#endif
#ifdef CONFIG_MPTCP
    DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);    //这是我们关注的mptcp相关的
#endif

    DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics);
#if IS_ENABLED(CONFIG_IPV6)
    DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
#endif

    DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics);
    DEFINE_SNMP_STAT_ATOMIC(struct icmpmsg_mib, icmpmsg_statistics);
#if IS_ENABLED(CONFIG_IPV6)
    DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
    DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib, icmpv6msg_statistics);
    struct proc_dir_entry *proc_net_devsnmp6;
#endif
};


文件路径:include/net/net_namespace.h
struct net {
    ...
    struct netns_mib    mib;    //每个网络命名空间都有一个
    ...
    struct netns_ipv4   ipv4;
    ...
}

文件路径:net/mptcp/mib.h
/* SPDX-License-Identifier: GPL-2.0-or-later */

enum linux_mptcp_mib_field {
        MPTCP_MIB_NUM = 0,
        MPTCP_MIB_MPCAPABLEPASSIVE,     /* Received SYN with MP_CAPABLE */
        MPTCP_MIB_MPCAPABLEACTIVE,      /* Sent SYN with MP_CAPABLE */
        MPTCP_MIB_MPCAPABLEACTIVEACK,   /* Received SYN/ACK with MP_CAPABLE */
        MPTCP_MIB_MPCAPABLEPASSIVEACK,  /* Received third ACK with MP_CAPABLE */
        MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */
        MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
        MPTCP_MIB_TOKENFALLBACKINIT,    /* Could not init/allocate token */
        MPTCP_MIB_RETRANSSEGS,          /* Segments retransmitted at the MPTCP-level */
        MPTCP_MIB_JOINNOTOKEN,          /* Received MP_JOIN but the token was not found */
        MPTCP_MIB_JOINSYNRX,            /* Received a SYN + MP_JOIN */
        MPTCP_MIB_JOINSYNACKRX,         /* Received a SYN/ACK + MP_JOIN */
        MPTCP_MIB_JOINSYNACKMAC,        /* HMAC was wrong on SYN/ACK + MP_JOIN */
        MPTCP_MIB_JOINACKRX,            /* Received an ACK + MP_JOIN */
        MPTCP_MIB_JOINACKMAC,           /* HMAC was wrong on ACK + MP_JOIN */
        MPTCP_MIB_DSSNOMATCH,           /* Received a new mapping that did not match the previous one */
        MPTCP_MIB_INFINITEMAPTX,        /* Sent an infinite mapping */
        MPTCP_MIB_INFINITEMAPRX,        /* Received an infinite mapping */
        MPTCP_MIB_DSSTCPMISMATCH,       /* DSS-mapping did not map with TCP's sequence numbers */
        MPTCP_MIB_DATACSUMERR,          /* The data checksum fail */
        MPTCP_MIB_OFOQUEUETAIL, /* Segments inserted into OoO queue tail */
        MPTCP_MIB_OFOQUEUE,             /* Segments inserted into OoO queue */
        MPTCP_MIB_OFOMERGE,             /* Segments merged in OoO queue */
        MPTCP_MIB_NODSSWINDOW,          /* Segments not in MPTCP windows */
        MPTCP_MIB_DUPDATA,              /* Segments discarded due to duplicate DSS */
        MPTCP_MIB_ADDADDR,              /* Received ADD_ADDR with echo-flag=0 */
        MPTCP_MIB_ADDADDRTX,            /* Sent ADD_ADDR with echo-flag=0 */
        MPTCP_MIB_ADDADDRTXDROP,        /* ADD_ADDR with echo-flag=0 not send due to
                                         * resource exhaustion
                                         */
        MPTCP_MIB_ECHOADD,              /* Received ADD_ADDR with echo-flag=1 */
        MPTCP_MIB_ECHOADDTX,            /* Send ADD_ADDR with echo-flag=1 */
        MPTCP_MIB_ECHOADDTXDROP,        /* ADD_ADDR with echo-flag=1 not send due
                                         * to resource exhaustion
                                         */
        MPTCP_MIB_PORTADD,              /* Received ADD_ADDR with a port-number */
        MPTCP_MIB_ADDADDRDROP,          /* Dropped incoming ADD_ADDR */
        MPTCP_MIB_JOINPORTSYNRX,        /* Received a SYN MP_JOIN with a different port-number */
        MPTCP_MIB_JOINPORTSYNACKRX,     /* Received a SYNACK MP_JOIN with a different port-number */
        MPTCP_MIB_JOINPORTACKRX,        /* Received an ACK MP_JOIN with a different port-number */
        MPTCP_MIB_MISMATCHPORTSYNRX,    /* Received a SYN MP_JOIN with a mismatched port-number */
        MPTCP_MIB_MISMATCHPORTACKRX,    /* Received an ACK MP_JOIN with a mismatched port-number */
        MPTCP_MIB_RMADDR,               /* Received RM_ADDR */
        MPTCP_MIB_RMADDRDROP,           /* Dropped incoming RM_ADDR */
        MPTCP_MIB_RMADDRTX,             /* Sent RM_ADDR */
        MPTCP_MIB_RMADDRTXDROP,         /* RM_ADDR not sent due to resource exhaustion */
        MPTCP_MIB_RMSUBFLOW,            /* Remove a subflow */
        MPTCP_MIB_MPPRIOTX,             /* Transmit a MP_PRIO */
        MPTCP_MIB_MPPRIORX,             /* Received a MP_PRIO */
        MPTCP_MIB_MPFAILTX,             /* Transmit a MP_FAIL */
        MPTCP_MIB_MPFAILRX,             /* Received a MP_FAIL */
        MPTCP_MIB_MPFASTCLOSETX,        /* Transmit a MP_FASTCLOSE */
        MPTCP_MIB_MPFASTCLOSERX,        /* Received a MP_FASTCLOSE */
        MPTCP_MIB_MPRSTTX,              /* Transmit a MP_RST */
        MPTCP_MIB_MPRSTRX,              /* Received a MP_RST */
        MPTCP_MIB_RCVPRUNED,            /* Incoming packet dropped due to memory limit */
        MPTCP_MIB_SUBFLOWSTALE,         /* Subflows entered 'stale' status */
        MPTCP_MIB_SUBFLOWRECOVER,       /* Subflows returned to active status after being stale */
        MPTCP_MIB_SNDWNDSHARED,         /* Subflow snd wnd is overridden by msk's one */
        MPTCP_MIB_RCVWNDSHARED,         /* Subflow rcv wnd is overridden by msk's one */
        MPTCP_MIB_RCVWNDCONFLICTUPDATE, /* subflow rcv wnd is overridden by msk's one due to
                                         * conflict with another subflow while updating msk rcv wnd
                                         */
        MPTCP_MIB_RCVWNDCONFLICT,       /* Conflict with while updating msk rcv wnd */
        __MPTCP_MIB_MAX
};

#define LINUX_MIB_MPTCP_MAX     __MPTCP_MIB_MAX
//可以看到mptcp_mib里面就是一个数组,用来存放mptcp协议相关的mib信息
struct mptcp_mib {
        unsigned long mibs[LINUX_MIB_MPTCP_MAX];
};

static inline void MPTCP_ADD_STATS(struct net *net,
                                   enum linux_mptcp_mib_field field,
                                   int val)
{
        if (likely(net->mib.mptcp_statistics))
                SNMP_ADD_STATS(net->mib.mptcp_statistics, field, val);
}

static inline void MPTCP_INC_STATS(struct net *net,
                                   enum linux_mptcp_mib_field field)
{
        if (likely(net->mib.mptcp_statistics))
                SNMP_INC_STATS(net->mib.mptcp_statistics, field);
}

static inline void __MPTCP_INC_STATS(struct net *net,
                                     enum linux_mptcp_mib_field field)
{
        if (likely(net->mib.mptcp_statistics))
                __SNMP_INC_STATS(net->mib.mptcp_statistics, field);
}

文件路径:include/net/snmp.h

struct snmp_mib {
    const char *name;
    int entry;
};
//填充struct snmp_mib结构
#define SNMP_MIB_ITEM(_name,_entry) {   \
    .name = _name,              \
    .entry = _entry,            \
}

文件路径:net/mptcp/mib.c
// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/seq_file.h>
#include <net/ip.h>
#include <net/mptcp.h>
#include <net/snmp.h>
#include <net/net_namespace.h>

#include "mib.h"

static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE),
        SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE),
        SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK),
        SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
        SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
        SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
        SNMP_MIB_ITEM("MPFallbackTokenInit", MPTCP_MIB_TOKENFALLBACKINIT),
        SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
        SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
        SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX),
        SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX),
        SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
        SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
        SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
        SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
        SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
        SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
        SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
        SNMP_MIB_ITEM("DataCsumErr", MPTCP_MIB_DATACSUMERR),
        SNMP_MIB_ITEM("OFOQueueTail", MPTCP_MIB_OFOQUEUETAIL),
        SNMP_MIB_ITEM("OFOQueue", MPTCP_MIB_OFOQUEUE),
        SNMP_MIB_ITEM("OFOMerge", MPTCP_MIB_OFOMERGE),
        SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW),
        SNMP_MIB_ITEM("DuplicateData", MPTCP_MIB_DUPDATA),
        SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR),
        SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX),
        SNMP_MIB_ITEM("AddAddrTxDrop", MPTCP_MIB_ADDADDRTXDROP),
        SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD),
        SNMP_MIB_ITEM("EchoAddTx", MPTCP_MIB_ECHOADDTX),
        SNMP_MIB_ITEM("EchoAddTxDrop", MPTCP_MIB_ECHOADDTXDROP),
        SNMP_MIB_ITEM("PortAdd", MPTCP_MIB_PORTADD),
        SNMP_MIB_ITEM("AddAddrDrop", MPTCP_MIB_ADDADDRDROP),
        SNMP_MIB_ITEM("MPJoinPortSynRx", MPTCP_MIB_JOINPORTSYNRX),
        SNMP_MIB_ITEM("MPJoinPortSynAckRx", MPTCP_MIB_JOINPORTSYNACKRX),
        SNMP_MIB_ITEM("MPJoinPortAckRx", MPTCP_MIB_JOINPORTACKRX),
        SNMP_MIB_ITEM("MismatchPortSynRx", MPTCP_MIB_MISMATCHPORTSYNRX),
        SNMP_MIB_ITEM("MismatchPortAckRx", MPTCP_MIB_MISMATCHPORTACKRX),
        SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR),
        SNMP_MIB_ITEM("RmAddrDrop", MPTCP_MIB_RMADDRDROP),
        SNMP_MIB_ITEM("RmAddrTx", MPTCP_MIB_RMADDRTX),
        SNMP_MIB_ITEM("RmAddrTxDrop", MPTCP_MIB_RMADDRTXDROP),
        SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
        SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
        SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
        SNMP_MIB_ITEM("MPFailTx", MPTCP_MIB_MPFAILTX),
        SNMP_MIB_ITEM("MPFailRx", MPTCP_MIB_MPFAILRX),
        SNMP_MIB_ITEM("MPFastcloseTx", MPTCP_MIB_MPFASTCLOSETX),
        SNMP_MIB_ITEM("MPFastcloseRx", MPTCP_MIB_MPFASTCLOSERX),
        SNMP_MIB_ITEM("MPRstTx", MPTCP_MIB_MPRSTTX),
        SNMP_MIB_ITEM("MPRstRx", MPTCP_MIB_MPRSTRX),
        SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED),
        SNMP_MIB_ITEM("SubflowStale", MPTCP_MIB_SUBFLOWSTALE),
        SNMP_MIB_ITEM("SubflowRecover", MPTCP_MIB_SUBFLOWRECOVER),
        SNMP_MIB_ITEM("SndWndShared", MPTCP_MIB_SNDWNDSHARED),
        SNMP_MIB_ITEM("RcvWndShared", MPTCP_MIB_RCVWNDSHARED),
        SNMP_MIB_ITEM("RcvWndConflictUpdate", MPTCP_MIB_RCVWNDCONFLICTUPDATE),
        SNMP_MIB_ITEM("RcvWndConflict", MPTCP_MIB_RCVWNDCONFLICT),
        SNMP_MIB_SENTINEL
};

/* mptcp_mib_alloc - allocate percpu mib counters
 *
 * These are allocated when the first mptcp socket is created so
 * we do not waste percpu memory if mptcp isn't in use.
 */
bool mptcp_mib_alloc(struct net *net)
{
        //为每个cpu申请一份struct mptcp_mib内存
        struct mptcp_mib __percpu *mib = alloc_percpu(struct mptcp_mib);

        if (!mib)
                return false;

        //struct mptcp_mib __percpu *mptcp_statistics
        /*
            struct mptcp_mib {
            unsigned long mibs[LINUX_MIB_MPTCP_MAX];
            };
        */
        //将申请的内存传给网络命名空间中net->mib.mptcp_statistics
        if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib))
                free_percpu(mib);

        return true;
}

void mptcp_seq_show(struct seq_file *seq)
{
        //这里减一,我觉得是数组最后一个成员SNMP_MIB_SENTINEL是NULL所以要减一
        unsigned long sum[ARRAY_SIZE(mptcp_snmp_list) - 1];
        //通过struct seq_file这个机构指针获取网络命名空间对象
        //这里应该在某个初始化的位置将seq->private指向了net,所以这可以通过eq->private获取net
        struct net *net = seq->private;
        int i;
        
        //struct seq_file这个结构体是这样的
        /* 
        struct seq_file {
            char *buf;
            size_t size;
            size_t from;
            size_t count;
            size_t pad_until;
            loff_t index;
            loff_t read_pos;
            struct mutex lock;
            const struct seq_operations *op;
            int poll_event;
            const struct file *file;
            void *private;
        };
        */
        //将字符"MPTcpExt:"存入seq->buf中
        seq_puts(seq, "MPTcpExt:");
        for (i = 0; mptcp_snmp_list[i].name; i++)
                //遍历mptcp_snmp_list数组将.name的信息名称依次存入seq->buf中
                seq_printf(seq, " %s", mptcp_snmp_list[i].name);

        //将字符"\nMPTcpExt:"存入seq->buf中,在前面加一个换行是为了另起一行
        /*如
            MPTcpExt: name1 name2 name3
            MPTcpExt: 
        */
        seq_puts(seq, "\nMPTcpExt:");
        
        //sum数组清零
        memset(sum, 0, sizeof(sum));
        if (net->mib.mptcp_statistics)
                //将net->mib.mptcp_statistics中的mptcp的mib信息传给sum数组
                snmp_get_cpu_field_batch(sum, mptcp_snmp_list,
                                         net->mib.mptcp_statistics);

        for (i = 0; mptcp_snmp_list[i].name; i++)
                //将获取到mptcp的mib信息也填入seq->buf中
                seq_printf(seq, " %lu", sum[i]);
        /*最终形成
            MPTcpExt: name1 name2 name3
            MPTcpExt: data1 data2 data3
        */
        
        //最后加换行,和下一个协议隔开
        seq_putc(seq, '\n');
}

4.总结

        这个文件的主要作用是

        1.为每个cpu申请一份struct mptcp_mib内存

        2.将mptcp的mib信息从net命名空间获取,然后给到seq_file结构中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值