net/bridge/br_sysfs_br.c

Source file repositories/reference/linux-study-clean/net/bridge/br_sysfs_br.c

File Facts

System
Linux kernel
Corpus path
net/bridge/br_sysfs_br.c
Extension
.c
Size
30431 bytes
Lines
1088
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	Sysfs attributes of bridge
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Stephen Hemminger		<shemminger@osdl.org>
 */

#include <linux/capability.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/hex.h>
#include <linux/if_bridge.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
#include <linux/times.h>
#include <linux/sched/signal.h>

#include "br_private.h"

/* IMPORTANT: new bridge options must be added with netlink support only
 *            please do not add new sysfs entries
 */

#define to_bridge(cd)	((struct net_bridge *)netdev_priv(to_net_dev(cd)))

/*
 * Common code for storing bridge parameters.
 */
static ssize_t store_bridge_parm(struct device *d,
				 const char *buf, size_t len,
				 int (*set)(struct net_bridge *br, unsigned long val,
					    struct netlink_ext_ack *extack))
{
	struct net_bridge *br = to_bridge(d);
	struct netlink_ext_ack extack = {0};
	unsigned long val;
	int err;

	if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
		return -EPERM;

	err = kstrtoul(buf, 0, &val);
	if (err != 0)
		return err;

	if (!rtnl_trylock())
		return restart_syscall();

	err = (*set)(br, val, &extack);
	if (!err)
		netdev_state_change(br->dev);
	if (extack._msg) {
		if (err)
			br_err(br, "%s\n", extack._msg);
		else
			br_warn(br, "%s\n", extack._msg);
	}
	rtnl_unlock();

	return err ? err : len;
}


static ssize_t forward_delay_show(struct device *d,
				  struct device_attribute *attr, char *buf)
{
	struct net_bridge *br = to_bridge(d);
	return sysfs_emit(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
}

static int set_forward_delay(struct net_bridge *br, unsigned long val,
			     struct netlink_ext_ack *extack)
{
	return br_set_forward_delay(br, val);
}

static ssize_t forward_delay_store(struct device *d,
				   struct device_attribute *attr,
				   const char *buf, size_t len)
{
	return store_bridge_parm(d, buf, len, set_forward_delay);
}
static DEVICE_ATTR_RW(forward_delay);

static ssize_t hello_time_show(struct device *d, struct device_attribute *attr,
			       char *buf)
{

Annotation

Implementation Notes