net/ipv6/proc.c

Source file repositories/reference/linux-study-clean/net/ipv6/proc.c

File Facts

System
Linux kernel
Corpus path
net/ipv6/proc.c
Extension
.c
Size
10415 bytes
Lines
315
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (icmptype) {
/* RFC 4293 v6 ICMPMsgStatsTable; named items for RFC 2466 compatibility */
		CASE(ICMPV6_DEST_UNREACH,	"DestUnreachs")
		CASE(ICMPV6_PKT_TOOBIG,		"PktTooBigs")
		CASE(ICMPV6_TIME_EXCEED,	"TimeExcds")
		CASE(ICMPV6_PARAMPROB,		"ParmProblems")
		CASE(ICMPV6_ECHO_REQUEST,	"Echos")
		CASE(ICMPV6_ECHO_REPLY,		"EchoReplies")
		CASE(ICMPV6_MGM_QUERY,		"GroupMembQueries")
		CASE(ICMPV6_MGM_REPORT,		"GroupMembResponses")
		CASE(ICMPV6_MGM_REDUCTION,	"GroupMembReductions")
		CASE(ICMPV6_MLD2_REPORT,	"MLDv2Reports")
		CASE(NDISC_ROUTER_ADVERTISEMENT, "RouterAdvertisements")
		CASE(NDISC_ROUTER_SOLICITATION, "RouterSolicits")
		CASE(NDISC_NEIGHBOUR_ADVERTISEMENT, "NeighborAdvertisements")
		CASE(NDISC_NEIGHBOUR_SOLICITATION, "NeighborSolicits")
		CASE(NDISC_REDIRECT,		"Redirects")
		}
#undef CASE
		if (!p)	/* don't print un-named types here */
			continue;
		snprintf(name, sizeof(name), "Icmp6%s%s",
			i & 0x100 ? "Out" : "In", p);
		seq_printf(seq, "%-32s\t%lu\n", name,
			   atomic_long_read(smib + i));
	}

	/* print by number (nonzero only) - ICMPMsgStat format */
	for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
		unsigned long val;

		val = atomic_long_read(smib + i);
		if (!val)
			continue;
		snprintf(name, sizeof(name), "Icmp6%sType%u",
			i & 0x100 ?  "Out" : "In", i & 0xff);
		seq_printf(seq, "%-32s\t%lu\n", name, val);
	}
}

/* can be called either with percpu mib (pcpumib != NULL),
 * or shared one (smib != NULL)
 */
static void snmp6_seq_show_item(struct seq_file *seq, void __percpu *pcpumib,
				atomic_long_t *smib,
				const struct snmp_mib *itemlist,
				int cnt)
{
	unsigned long buff[SNMP_MIB_MAX];
	int i;

	if (pcpumib) {
		memset(buff, 0, sizeof(unsigned long) * cnt);

		snmp_get_cpu_field_batch_cnt(buff, itemlist, cnt, pcpumib);
		for (i = 0; i < cnt; i++)
			seq_printf(seq, "%-32s\t%lu\n",
				   itemlist[i].name, buff[i]);
	} else {
		for (i = 0; i < cnt; i++)
			seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name,
				   atomic_long_read(smib + itemlist[i].entry));
	}
}

static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib,
				  const struct snmp_mib *itemlist,
				  int cnt, size_t syncpoff)
{
	u64 buff64[SNMP_MIB_MAX];
	int i;

	memset(buff64, 0, sizeof(u64) * cnt);

	snmp_get_cpu_field64_batch_cnt(buff64, itemlist, cnt, mib, syncpoff);
	for (i = 0; i < cnt; i++)
		seq_printf(seq, "%-32s\t%llu\n", itemlist[i].name, buff64[i]);
}

static int snmp6_seq_show(struct seq_file *seq, void *v)
{
	struct net *net = (struct net *)seq->private;

	snmp6_seq_show_item64(seq, net->mib.ipv6_statistics,
			      snmp6_ipstats_list,
			      ARRAY_SIZE(snmp6_ipstats_list),
			      offsetof(struct ipstats_mib, syncp));
	snmp6_seq_show_item(seq, net->mib.icmpv6_statistics,
			    NULL, snmp6_icmp6_list,
			    ARRAY_SIZE(snmp6_icmp6_list));

Annotation

Implementation Notes