net/hsr/hsr_slave.c

Source file repositories/reference/linux-study-clean/net/hsr/hsr_slave.c

File Facts

System
Linux kernel
Corpus path
net/hsr/hsr_slave.c
Extension
.c
Size
6332 bytes
Lines
255
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

if (!pskb_may_pull(skb, ETH_HLEN + HSR_HLEN)) {
			kfree_skb(skb);
			goto finish_consume;
		}

		skb_set_network_header(skb, ETH_HLEN + HSR_HLEN);
	}
	skb_reset_mac_len(skb);

	/* Only the frames received over the interlink port will assign a
	 * sequence number and require synchronisation vs other sender.
	 */
	if (port->type == HSR_PT_INTERLINK) {
		spin_lock_bh(&hsr->seqnr_lock);
		hsr_forward_skb(skb, port);
		spin_unlock_bh(&hsr->seqnr_lock);
	} else {
		hsr_forward_skb(skb, port);
	}

finish_consume:
	return RX_HANDLER_CONSUMED;

finish_pass:
	return RX_HANDLER_PASS;
}

bool hsr_port_exists(const struct net_device *dev)
{
	return rcu_access_pointer(dev->rx_handler) == hsr_handle_frame;
}

static int hsr_check_dev_ok(struct net_device *dev,
			    struct netlink_ext_ack *extack)
{
	/* Don't allow HSR on non-ethernet like devices */
	if ((dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
	    dev->addr_len != ETH_ALEN) {
		NL_SET_ERR_MSG_MOD(extack, "Cannot use loopback or non-ethernet device as HSR slave.");
		return -EINVAL;
	}

	/* Don't allow enslaving hsr devices */
	if (is_hsr_master(dev)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Cannot create trees of HSR devices.");
		return -EINVAL;
	}

	if (hsr_port_exists(dev)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "This device is already a HSR slave.");
		return -EINVAL;
	}

	if (is_vlan_dev(dev)) {
		NL_SET_ERR_MSG_MOD(extack, "HSR on top of VLAN is not yet supported in this driver.");
		return -EINVAL;
	}

	if (dev->priv_flags & IFF_DONT_BRIDGE) {
		NL_SET_ERR_MSG_MOD(extack,
				   "This device does not support bridging.");
		return -EOPNOTSUPP;
	}

	/* HSR over bonded devices has not been tested, but I'm not sure it
	 * won't work...
	 */

	return 0;
}

/* Setup device to be added to the HSR bridge. */
static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
			     struct hsr_port *port,
			     struct netlink_ext_ack *extack)

{
	struct netdev_lag_upper_info lag_upper_info;
	struct net_device *hsr_dev;
	struct hsr_port *master;
	int res;

	/* Don't use promiscuous mode for offload since L2 frame forward
	 * happens at the offloaded hardware.
	 */
	if (!port->hsr->fwd_offloaded) {
		res = dev_set_promiscuity(dev, 1);
		if (res)

Annotation

Implementation Notes