net/hsr/hsr_netlink.c

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

File Facts

System
Linux kernel
Corpus path
net/hsr/hsr_netlink.c
Extension
.c
Size
14648 bytes
Lines
605
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 (!interlink) {
			NL_SET_ERR_MSG_MOD(extack, "Interlink does not exist");
			return -EINVAL;
		}
	}

	if (interlink && interlink == link[0]) {
		NL_SET_ERR_MSG_MOD(extack, "Interlink and Slave1 are the same");
		return -EINVAL;
	}

	if (interlink && interlink == link[1]) {
		NL_SET_ERR_MSG_MOD(extack, "Interlink and Slave2 are the same");
		return -EINVAL;
	}

	multicast_spec = nla_get_u8_default(data[IFLA_HSR_MULTICAST_SPEC], 0);

	if (data[IFLA_HSR_PROTOCOL])
		proto = nla_get_u8(data[IFLA_HSR_PROTOCOL]);

	if (proto >= HSR_PROTOCOL_MAX) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol");
		return -EINVAL;
	}

	if (!data[IFLA_HSR_VERSION]) {
		proto_version = HSR_V0;
	} else {
		if (proto == HSR_PROTOCOL_PRP) {
			NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported");
			return -EINVAL;
		}

		proto_version = nla_get_u8(data[IFLA_HSR_VERSION]);
		if (proto_version > HSR_V1) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Only HSR version 0/1 supported");
			return -EINVAL;
		}
	}

	if (proto == HSR_PROTOCOL_PRP) {
		proto_version = PRP_V1;
		if (interlink) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Interlink only works with HSR");
			return -EINVAL;
		}
	}

	return hsr_dev_finalize(dev, link, interlink, multicast_spec,
				proto_version, extack);
}

static void hsr_dellink(struct net_device *dev, struct list_head *head)
{
	struct hsr_priv *hsr = netdev_priv(dev);

	timer_delete_sync(&hsr->prune_timer);
	timer_delete_sync(&hsr->prune_proxy_timer);
	timer_delete_sync(&hsr->announce_timer);
	timer_delete_sync(&hsr->announce_proxy_timer);

	hsr_debugfs_term(hsr);
	hsr_del_ports(hsr);

	hsr_del_self_node(hsr);
	hsr_del_nodes(&hsr->node_db);
	hsr_del_nodes(&hsr->proxy_node_db);

	unregister_netdevice_queue(dev, head);
}

static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
	struct hsr_priv *hsr = netdev_priv(dev);
	u8 proto = HSR_PROTOCOL_HSR;
	struct hsr_port *port;

	port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
	if (port) {
		if (nla_put_u32(skb, IFLA_HSR_SLAVE1, port->dev->ifindex))
			goto nla_put_failure;
	}

	port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
	if (port) {
		if (nla_put_u32(skb, IFLA_HSR_SLAVE2, port->dev->ifindex))
			goto nla_put_failure;

Annotation

Implementation Notes