18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 48c2ecf20Sopenharmony_ci#include <net/ip.h> 58c2ecf20Sopenharmony_ci#include <net/mptcp.h> 68c2ecf20Sopenharmony_ci#include <net/snmp.h> 78c2ecf20Sopenharmony_ci#include <net/net_namespace.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "mib.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic const struct snmp_mib mptcp_snmp_list[] = { 128c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), 138c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), 148c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), 158c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), 168c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), 178c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), 188c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), 198c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), 208c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), 218c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), 228c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), 238c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), 248c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), 258c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("OFOQueueTail", MPTCP_MIB_OFOQUEUETAIL), 268c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("OFOQueue", MPTCP_MIB_OFOQUEUE), 278c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("OFOMerge", MPTCP_MIB_OFOMERGE), 288c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), 298c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("DuplicateData", MPTCP_MIB_DUPDATA), 308c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR), 318c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD), 328c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR), 338c2ecf20Sopenharmony_ci SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW), 348c2ecf20Sopenharmony_ci SNMP_MIB_SENTINEL 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* mptcp_mib_alloc - allocate percpu mib counters 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * These are allocated when the first mptcp socket is created so 408c2ecf20Sopenharmony_ci * we do not waste percpu memory if mptcp isn't in use. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_cibool mptcp_mib_alloc(struct net *net) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci struct mptcp_mib __percpu *mib = alloc_percpu(struct mptcp_mib); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci if (!mib) 478c2ecf20Sopenharmony_ci return false; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib)) 508c2ecf20Sopenharmony_ci free_percpu(mib); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci return true; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_civoid mptcp_seq_show(struct seq_file *seq) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci struct net *net = seq->private; 588c2ecf20Sopenharmony_ci int i; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci seq_puts(seq, "MPTcpExt:"); 618c2ecf20Sopenharmony_ci for (i = 0; mptcp_snmp_list[i].name; i++) 628c2ecf20Sopenharmony_ci seq_printf(seq, " %s", mptcp_snmp_list[i].name); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci seq_puts(seq, "\nMPTcpExt:"); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci if (!net->mib.mptcp_statistics) { 678c2ecf20Sopenharmony_ci for (i = 0; mptcp_snmp_list[i].name; i++) 688c2ecf20Sopenharmony_ci seq_puts(seq, " 0"); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci seq_putc(seq, '\n'); 718c2ecf20Sopenharmony_ci return; 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci for (i = 0; mptcp_snmp_list[i].name; i++) 758c2ecf20Sopenharmony_ci seq_printf(seq, " %lu", 768c2ecf20Sopenharmony_ci snmp_fold_field(net->mib.mptcp_statistics, 778c2ecf20Sopenharmony_ci mptcp_snmp_list[i].entry)); 788c2ecf20Sopenharmony_ci seq_putc(seq, '\n'); 798c2ecf20Sopenharmony_ci} 80