summaryrefslogtreecommitdiff
path: root/usr.sbin/ldomd/ds.h
blob: a55c6d7392203342f9233f7516609db3895b7d63 (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*	$OpenBSD: ds.h,v 1.2 2012/11/04 18:57:10 kettenis Exp $	*/

/*
 * Copyright (c) 2012 Mark Kettenis
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/types.h>
#include <sys/queue.h>

/*
 * LDC virtual link layer protocol.
 */

#define LDC_VERSION_MAJOR	1
#define LDC_VERSION_MINOR	0

#define LDC_PKT_PAYLOAD	48

struct ldc_pkt {
	uint8_t		type;
	uint8_t		stype;
	uint8_t		ctrl;
	uint8_t		env;
	uint32_t	seqid;

	uint16_t	major;
	uint16_t	minor;
	uint32_t	ackid;

	uint64_t	data[6];
};

/* Packet types. */
#define LDC_CTRL	0x01
#define LDC_DATA	0x02
#define LDC_ERR		0x10

/* Packet subtypes. */
#define LDC_INFO	0x01
#define LDC_ACK		0x02
#define LDC_NACK	0x04

/* Control info values. */
#define LDC_VERS	0x01
#define LDC_RTS		0x02
#define LDC_RTR		0x03
#define LDC_RDX		0x04

/* Packet envelope. */
#define LDC_MODE_RAW		0x00
#define LDC_MODE_UNRELIABLE	0x01
#define LDC_MODE_RELIABLE	0x03

#define LDC_LEN_MASK	0x3f
#define LDC_FRAG_MASK	0xc0
#define LDC_FRAG_START	0x40
#define LDC_FRAG_STOP	0x80

#define LDC_MSG_MAX	4096

struct ldc_conn {
	int		lc_fd;

	uint32_t	lc_tx_seqid;
	uint8_t		lc_state;
#define LDC_SND_VERS	1
#define LDC_RCV_VERS	2
#define LDC_SND_RTS	3
#define LDC_SND_RTR	4
#define LDC_SND_RDX	5

	uint64_t	lc_msg[LDC_MSG_MAX / 8];
	size_t		lc_len;

	void		*lc_cookie;
	void		(*lc_reset)(struct ldc_conn *);
	void		(*lc_start)(struct ldc_conn *);
	void		(*lc_rx_data)(struct ldc_conn *, void *, size_t);
};

void	ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
void	ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);

void	ldc_send_vers(struct ldc_conn *);

void	ldc_reset(struct ldc_conn *);

struct ds_msg {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	data[5];
};

struct ds_init_req {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint16_t	major_vers;
	uint16_t	minor_vers;
} __packed;

struct ds_init_ack {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint16_t	minor_vers;
} __packed;

#define DS_INIT_REQ	0x00
#define DS_INIT_ACK	0x01
#define DS_INIT_NACK	0x02

struct ds_reg_req {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
	uint16_t	major_vers;
	uint16_t	minor_vers;
	char		svc_id[1];
} __packed;

#define DS_REG_REQ	0x03

struct ds_reg_ack {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
	uint16_t	minor_vers;
	uint8_t		_reserved[6];
} __packed;

#define DS_REG_ACK	0x04

struct ds_reg_nack {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
	uint64_t	result;
	uint16_t	major_vers;
	uint8_t		_reserved[6];
} __packed;

#define DS_REG_NACK	0x05

struct ds_unreg {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
} __packed;

#define DS_UNREG	0x06
#define DS_UNREG_ACK	0x07
#define DS_UNREG_NACK	0x08

struct ds_data {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
	uint64_t	data[4];
};

#define DS_DATA		0x09

struct ds_nack {
	uint32_t	msg_type;
	uint32_t	payload_len;
	uint64_t	svc_handle;
	uint64_t	result;
} __packed;

#define DS_NACK		0x0a

#define DS_REG_VER_NACK	0x01
#define DS_REG_DUP	0x02
#define DS_INV_HDL	0x03
#define DS_TYPE_UNKNOWN	0x04

struct ds_service {
	const char	*ds_svc_id;
	uint16_t	ds_major_vers;
	uint16_t	ds_minor_vers;

	void		(*ds_start)(struct ldc_conn *, uint64_t);
	void		(*ds_rx_data)(struct ldc_conn *, uint64_t, void *,
			    size_t);
};

void	ldc_ack(struct ldc_conn *, uint32_t);
void	ds_rx_msg(struct ldc_conn *, void *, size_t);

void	ds_init_ack(struct ldc_conn *);
void	ds_reg_ack(struct ldc_conn *, uint64_t);
void	ds_reg_nack(struct ldc_conn *, uint64_t);
void	ds_unreg_ack(struct ldc_conn *, uint64_t);
void	ds_unreg_nack(struct ldc_conn *, uint64_t);

void	ds_receive_msg(struct ldc_conn *lc, void *, size_t);
void	ds_send_msg(struct ldc_conn *lc, void *, size_t);

struct ds_conn_svc {
	struct ds_service *service;
	uint64_t svc_handle;
	uint32_t ackid;

	TAILQ_ENTRY(ds_conn_svc) link;
};

struct ds_conn {
	char *path;
	void *cookie;
	int id;
	struct ldc_conn lc;
	int fd;

	TAILQ_HEAD(ds_conn_svc_head, ds_conn_svc) services;
	TAILQ_ENTRY(ds_conn) link;
};

struct ds_conn *ds_conn_open(const char *, void *);
void	ds_conn_register_service(struct ds_conn *, struct ds_service *);
void	ds_conn_serve(void);
void	ds_conn_handle(struct ds_conn *);