1134911Ssam// SPDX-License-Identifier: GPL-2.0-only
2134911Ssam/*
3134911Ssam * 	IEEE 802.1Q GARP VLAN Registration Protocol (GVRP)
4134911Ssam *
5134911Ssam * 	Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
6134911Ssam */
7134911Ssam#include <linux/types.h>
8134911Ssam#include <linux/if_vlan.h>
9134911Ssam#include <net/garp.h>
10134911Ssam#include "vlan.h"
11134911Ssam
12134911Ssam#define GARP_GVRP_ADDRESS	{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 }
13134911Ssam
14134911Ssamenum gvrp_attributes {
15134911Ssam	GVRP_ATTR_INVALID,
16134911Ssam	GVRP_ATTR_VID,
17134911Ssam	__GVRP_ATTR_MAX
18134911Ssam};
19134911Ssam#define GVRP_ATTR_MAX	(__GVRP_ATTR_MAX - 1)
20134911Ssam
21134911Ssamstatic struct garp_application vlan_gvrp_app __read_mostly = {
22134911Ssam	.proto.group_address	= GARP_GVRP_ADDRESS,
23134911Ssam	.maxattr		= GVRP_ATTR_MAX,
24134911Ssam	.type			= GARP_APPLICATION_GVRP,
25134911Ssam};
26134911Ssam
27134911Ssamint vlan_gvrp_request_join(const struct net_device *dev)
28134911Ssam{
29134911Ssam	const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
30134911Ssam	__be16 vlan_id = htons(vlan->vlan_id);
31134911Ssam
32134911Ssam	if (vlan->vlan_proto != htons(ETH_P_8021Q))
33134911Ssam		return 0;
34134911Ssam	return garp_request_join(vlan->real_dev, &vlan_gvrp_app,
35134911Ssam				 &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID);
36134911Ssam}
37134911Ssam
38134911Ssamvoid vlan_gvrp_request_leave(const struct net_device *dev)
39134911Ssam{
40134911Ssam	const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
41134911Ssam	__be16 vlan_id = htons(vlan->vlan_id);
42134911Ssam
43134911Ssam	if (vlan->vlan_proto != htons(ETH_P_8021Q))
44134911Ssam		return;
45134911Ssam	garp_request_leave(vlan->real_dev, &vlan_gvrp_app,
46134911Ssam			   &vlan_id, sizeof(vlan_id), GVRP_ATTR_VID);
47134911Ssam}
48134911Ssam
49134911Ssamint vlan_gvrp_init_applicant(struct net_device *dev)
50134911Ssam{
51134911Ssam	return garp_init_applicant(dev, &vlan_gvrp_app);
52134911Ssam}
53134911Ssam
54134911Ssamvoid vlan_gvrp_uninit_applicant(struct net_device *dev)
55134911Ssam{
56134911Ssam	garp_uninit_applicant(dev, &vlan_gvrp_app);
57134911Ssam}
58134911Ssam
59134911Ssamint __init vlan_gvrp_init(void)
60134911Ssam{
61134911Ssam	return garp_register_application(&vlan_gvrp_app);
62134911Ssam}
63134911Ssam
64134911Ssamvoid vlan_gvrp_uninit(void)
65134911Ssam{
66134911Ssam	garp_unregister_application(&vlan_gvrp_app);
67134911Ssam}
68134911Ssam