112510Sdg/* SPDX-License-Identifier: GPL-2.0 */
212510Sdg#ifndef _NET_GARP_H
312510Sdg#define _NET_GARP_H
412510Sdg
512510Sdg#include <linux/if_ether.h>
612510Sdg#include <linux/types.h>
712510Sdg#include <net/stp.h>
812510Sdg
912510Sdg#define GARP_PROTOCOL_ID	0x1
1012510Sdg#define GARP_END_MARK		0x0
1112510Sdg
1212510Sdgstruct garp_pdu_hdr {
1312510Sdg	__be16	protocol;
1412510Sdg};
1512510Sdg
1612510Sdgstruct garp_msg_hdr {
1712510Sdg	u8	attrtype;
1812510Sdg};
1912510Sdg
2012510Sdgenum garp_attr_event {
2112510Sdg	GARP_LEAVE_ALL,
2212510Sdg	GARP_JOIN_EMPTY,
2312510Sdg	GARP_JOIN_IN,
2412510Sdg	GARP_LEAVE_EMPTY,
2512510Sdg	GARP_LEAVE_IN,
2612510Sdg	GARP_EMPTY,
2729138Sdg};
2812510Sdg
2912510Sdgstruct garp_attr_hdr {
3012510Sdg	u8	len;
3112510Sdg	u8	event;
3212510Sdg	u8	data[];
3312510Sdg};
3412510Sdg
3512510Sdgstruct garp_skb_cb {
3629138Sdg	u8	cur_type;
3729138Sdg};
3829138Sdg
3929138Sdgstatic inline struct garp_skb_cb *garp_cb(struct sk_buff *skb)
4029138Sdg{
4129138Sdg	BUILD_BUG_ON(sizeof(struct garp_skb_cb) >
4229138Sdg		     sizeof_field(struct sk_buff, cb));
4329138Sdg	return (struct garp_skb_cb *)skb->cb;
4429138Sdg}
4529138Sdg
4629138Sdgenum garp_applicant_state {
4729138Sdg	GARP_APPLICANT_INVALID,
4812510Sdg	GARP_APPLICANT_VA,
4929138Sdg	GARP_APPLICANT_AA,
5029138Sdg	GARP_APPLICANT_QA,
5129138Sdg	GARP_APPLICANT_LA,
5229138Sdg	GARP_APPLICANT_VP,
5329138Sdg	GARP_APPLICANT_AP,
5429138Sdg	GARP_APPLICANT_QP,
5529138Sdg	GARP_APPLICANT_VO,
5629138Sdg	GARP_APPLICANT_AO,
5722255Sdg	GARP_APPLICANT_QO,
5822255Sdg	__GARP_APPLICANT_MAX
5922255Sdg};
6022255Sdg#define GARP_APPLICANT_MAX	(__GARP_APPLICANT_MAX - 1)
6122255Sdg
6212510Sdgenum garp_event {
6312510Sdg	GARP_EVENT_REQ_JOIN,
6412510Sdg	GARP_EVENT_REQ_LEAVE,
6512510Sdg	GARP_EVENT_R_JOIN_IN,
6612510Sdg	GARP_EVENT_R_JOIN_EMPTY,
6712510Sdg	GARP_EVENT_R_EMPTY,
6812510Sdg	GARP_EVENT_R_LEAVE_IN,
6912510Sdg	GARP_EVENT_R_LEAVE_EMPTY,
7012510Sdg	GARP_EVENT_TRANSMIT_PDU,
7112510Sdg	__GARP_EVENT_MAX
7212510Sdg};
7312510Sdg#define GARP_EVENT_MAX		(__GARP_EVENT_MAX - 1)
7412510Sdg
7512510Sdgenum garp_action {
7612510Sdg	GARP_ACTION_NONE,
7712510Sdg	GARP_ACTION_S_JOIN_IN,
7812510Sdg	GARP_ACTION_S_LEAVE_EMPTY,
7912510Sdg};
8012510Sdg
8112510Sdgstruct garp_attr {
8212510Sdg	struct rb_node			node;
8312510Sdg	enum garp_applicant_state	state;
8412510Sdg	u8				type;
8512510Sdg	u8				dlen;
8612510Sdg	unsigned char			data[];
8712510Sdg};
8812510Sdg
8912510Sdgenum garp_applications {
9012510Sdg	GARP_APPLICATION_GVRP,
9112510Sdg	__GARP_APPLICATION_MAX
9212510Sdg};
9312510Sdg#define GARP_APPLICATION_MAX	(__GARP_APPLICATION_MAX - 1)
9412510Sdg
9512510Sdgstruct garp_application {
9612510Sdg	enum garp_applications	type;
9712510Sdg	unsigned int		maxattr;
9812510Sdg	struct stp_proto	proto;
9912510Sdg};
10012510Sdg
10112510Sdgstruct garp_applicant {
10212510Sdg	struct garp_application	*app;
10312510Sdg	struct net_device	*dev;
10412510Sdg	struct timer_list	join_timer;
10512510Sdg
10612510Sdg	spinlock_t		lock;
10712510Sdg	struct sk_buff_head	queue;
10812510Sdg	struct sk_buff		*pdu;
10912510Sdg	struct rb_root		gid;
11012510Sdg	struct rcu_head		rcu;
11112510Sdg};
11212510Sdg
11312510Sdgstruct garp_port {
11412510Sdg	struct garp_applicant __rcu	*applicants[GARP_APPLICATION_MAX + 1];
11512510Sdg	struct rcu_head			rcu;
11612510Sdg};
11712510Sdg
11812510Sdgint garp_register_application(struct garp_application *app);
11912510Sdgvoid garp_unregister_application(struct garp_application *app);
12012510Sdg
12112510Sdgint garp_init_applicant(struct net_device *dev, struct garp_application *app);
12212510Sdgvoid garp_uninit_applicant(struct net_device *dev,
12312510Sdg			   struct garp_application *app);
12412510Sdg
12512510Sdgint garp_request_join(const struct net_device *dev,
12612510Sdg		      const struct garp_application *app, const void *data,
12712510Sdg		      u8 len, u8 type);
12812510Sdgvoid garp_request_leave(const struct net_device *dev,
12912510Sdg			const struct garp_application *app,
13012510Sdg			const void *data, u8 len, u8 type);
13112510Sdg
13212510Sdg#endif /* _NET_GARP_H */
13312510Sdg