summaryrefslogtreecommitdiff
path: root/include/net/mrp.h
blob: b28915ffea284c2bee1a7619cdd390cfe68bfaea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _NET_MRP_H
#define _NET_MRP_H

#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/types.h>

#define MRP_END_MARK		0x0

struct mrp_pdu_hdr {
	u8	version;
};

struct mrp_msg_hdr {
	u8	attrtype;
	u8	attrlen;
};

struct mrp_vecattr_hdr {
	__be16	lenflags;
	unsigned char	firstattrvalue[];
#define MRP_VECATTR_HDR_LEN_MASK cpu_to_be16(0x1FFF)
#define MRP_VECATTR_HDR_FLAG_LA cpu_to_be16(0x2000)
};

enum mrp_vecattr_event {
	MRP_VECATTR_EVENT_NEW,
	MRP_VECATTR_EVENT_JOIN_IN,
	MRP_VECATTR_EVENT_IN,
	MRP_VECATTR_EVENT_JOIN_MT,
	MRP_VECATTR_EVENT_MT,
	MRP_VECATTR_EVENT_LV,
	__MRP_VECATTR_EVENT_MAX
};

struct mrp_skb_cb {
	struct mrp_msg_hdr	*mh;
	struct mrp_vecattr_hdr	*vah;
	unsigned char		attrvalue[];
};

static inline struct mrp_skb_cb *mrp_cb(struct sk_buff *skb)
{
	BUILD_BUG_ON(sizeof(struct mrp_skb_cb) >
		     sizeof_field(struct sk_buff, cb));
	return (struct mrp_skb_cb *)skb->cb;
}

enum mrp_applicant_state {
	MRP_APPLICANT_INVALID,
	MRP_APPLICANT_VO,
	MRP_APPLICANT_VP,
	MRP_APPLICANT_VN,
	MRP_APPLICANT_AN,
	MRP_APPLICANT_AA,
	MRP_APPLICANT_QA,
	MRP_APPLICANT_LA,
	MRP_APPLICANT_AO,
	MRP_APPLICANT_QO,
	MRP_APPLICANT_AP,
	MRP_APPLICANT_QP,
	__MRP_APPLICANT_MAX
};
#define MRP_APPLICANT_MAX	(__MRP_APPLICANT_MAX - 1)

enum mrp_event {
	MRP_EVENT_NEW,
	MRP_EVENT_JOIN,
	MRP_EVENT_LV,
	MRP_EVENT_TX,
	MRP_EVENT_R_NEW,
	MRP_EVENT_R_JOIN_IN,
	MRP_EVENT_R_IN,
	MRP_EVENT_R_JOIN_MT,
	MRP_EVENT_R_MT,
	MRP_EVENT_R_LV,
	MRP_EVENT_R_LA,
	MRP_EVENT_REDECLARE,
	MRP_EVENT_PERIODIC,
	__MRP_EVENT_MAX
};
#define MRP_EVENT_MAX		(__MRP_EVENT_MAX - 1)

enum mrp_tx_action {
	MRP_TX_ACTION_NONE,
	MRP_TX_ACTION_S_NEW,
	MRP_TX_ACTION_S_JOIN_IN,
	MRP_TX_ACTION_S_JOIN_IN_OPTIONAL,
	MRP_TX_ACTION_S_IN_OPTIONAL,
	MRP_TX_ACTION_S_LV,
};

struct mrp_attr {
	struct rb_node			node;
	enum mrp_applicant_state	state;
	u8				type;
	u8				len;
	unsigned char			value[];
};

enum mrp_applications {
	MRP_APPLICATION_MVRP,
	__MRP_APPLICATION_MAX
};
#define MRP_APPLICATION_MAX	(__MRP_APPLICATION_MAX - 1)

struct mrp_application {
	enum mrp_applications	type;
	unsigned int		maxattr;
	struct packet_type	pkttype;
	unsigned char		group_address[ETH_ALEN];
	u8			version;
};

struct mrp_applicant {
	struct mrp_application	*app;
	struct net_device	*dev;
	struct timer_list	join_timer;
	struct timer_list	periodic_timer;

	spinlock_t		lock;
	struct sk_buff_head	queue;
	struct sk_buff		*pdu;
	struct rb_root		mad;
	struct rcu_head		rcu;
	bool			active;
};

struct mrp_port {
	struct mrp_applicant __rcu	*applicants[MRP_APPLICATION_MAX + 1];
	struct rcu_head			rcu;
};

int mrp_register_application(struct mrp_application *app);
void mrp_unregister_application(struct mrp_application *app);

int mrp_init_applicant(struct net_device *dev, struct mrp_application *app);
void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *app);

int mrp_request_join(const struct net_device *dev,
		     const struct mrp_application *app,
		     const void *value, u8 len, u8 type);
void mrp_request_leave(const struct net_device *dev,
		       const struct mrp_application *app,
		       const void *value, u8 len, u8 type);

#endif /* _NET_MRP_H */