summaryrefslogtreecommitdiffstats
path: root/bfdd/bfddp_packet.h
blob: afcbdd758167101a103e2f8b36bebf52cedf8a5c (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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
// SPDX-License-Identifier: MIT
/*
 * BFD Data Plane protocol messages header.
 *
 * Copyright (C) 2020 Network Device Education Foundation, Inc. ("NetDEF")
 *                    Rafael F. Zalamena
 */

/**
 * \file bfddp_packet.h
 */
#ifndef BFD_DP_PACKET_H
#define BFD_DP_PACKET_H

#include <netinet/in.h>

#include <stdint.h>

/*
 * Protocol definitions.
 */

/**
 * BFD protocol version as defined in RFC5880 Section 4.1 Generic BFD Control
 * Packet Format.
 */
#define BFD_PROTOCOL_VERSION 1

/** Default data plane port. */
#define BFD_DATA_PLANE_DEFAULT_PORT 50700

/** BFD single hop UDP port, as defined in RFC 5881 Section 4. Encapsulation. */
#define BFD_SINGLE_HOP_PORT 3784

/** BFD multi hop UDP port, as defined in RFC 5883 Section 5. Encapsulation. */
#define BFD_MULTI_HOP_PORT 4784

/** Default slow start multiplier. */
#define SLOWSTART_DMULT 3
/** Default slow start transmission speed. */
#define SLOWSTART_TX 1000000u
/** Default slow start receive speed. */
#define SLOWSTART_RX 1000000u
/** Default slow start echo receive speed. */
#define SLOWSTART_ERX 0u

/*
 * BFD single hop source UDP ports. As defined in RFC 5881 Section 4.
 * Encapsulation.
 */
#define BFD_SOURCE_PORT_BEGIN 49152
#define BFD_SOURCE_PORT_END 65535

/** BFD data plane protocol version. */
#define BFD_DP_VERSION 1

/** BFD data plane message types. */
enum bfddp_message_type {
	/** Ask for BFD daemon or data plane for echo packet. */
	ECHO_REQUEST = 0,
	/** Answer a ECHO_REQUEST packet. */
	ECHO_REPLY = 1,
	/** Add or update BFD peer session. */
	DP_ADD_SESSION = 2,
	/** Delete BFD peer session. */
	DP_DELETE_SESSION = 3,
	/** Tell BFD daemon state changed: timer expired or session down. */
	BFD_STATE_CHANGE = 4,

	/** Ask for BFD session counters. */
	DP_REQUEST_SESSION_COUNTERS = 5,
	/** Tell BFD daemon about counters values. */
	BFD_SESSION_COUNTERS = 6,
};

/**
 * `ECHO_REQUEST`/`ECHO_REPLY` data payload.
 *
 * Data plane might use whatever precision it wants for `dp_time`
 * field, however if you want to be able to tell the delay between
 * data plane packet send and BFD daemon packet processing you should
 * use `gettimeofday()` and have the data plane clock synchronized with
 * BFD daemon (not a problem if data plane runs in the same system).
 *
 * Normally data plane will only check the time stamp it sent to determine
 * the whole packet trip time.
 */
struct bfddp_echo {
	/** Filled by data plane. */
	uint64_t dp_time;
	/** Filled by BFD daemon. */
	uint64_t bfdd_time;
};


/** BFD session flags. */
enum bfddp_session_flag {
	/** Set when using multi hop. */
	SESSION_MULTIHOP = (1 << 0),
	/** Set when using demand mode. */
	SESSION_DEMAND = (1 << 1),
	/** Set when using cbit (Control Plane Independent). */
	SESSION_CBIT = (1 << 2),
	/** Set when using echo mode. */
	SESSION_ECHO = (1 << 3),
	/** Set when using IPv6. */
	SESSION_IPV6 = (1 << 4),
	/** Set when using passive mode. */
	SESSION_PASSIVE = (1 << 5),
	/** Set when session is administrative down. */
	SESSION_SHUTDOWN = (1 << 6),
};

/**
 * `DP_ADD_SESSION`/`DP_DELETE_SESSION` data payload.
 *
 * `lid` is unique in BFD daemon so it might be used as key for data
 * structures lookup.
 */
struct bfddp_session {
	/** Important session flags. \see bfddp_session_flag. */
	uint32_t flags;
	/**
	 * Session source address.
	 *
	 * Check `flags` field for `SESSION_IPV6` before using as IPv6.
	 */
	struct in6_addr src;
	/**
	 * Session destination address.
	 *
	 * Check `flags` field for `SESSION_IPV6` before using as IPv6.
	 */
	struct in6_addr dst;

	/** Local discriminator. */
	uint32_t lid;
	/**
	 * Minimum desired transmission interval (in microseconds) without
	 * jitter.
	 */
	uint32_t min_tx;
	/**
	 * Required minimum receive interval rate (in microseconds) without
	 * jitter.
	 */
	uint32_t min_rx;
	/**
	 * Minimum desired echo transmission interval (in microseconds)
	 * without jitter.
	 */
	uint32_t min_echo_tx;
	/**
	 * Required minimum echo receive interval rate (in microseconds)
	 * without jitter.
	 */
	uint32_t min_echo_rx;
	/** Amount of milliseconds to wait before starting the session */
	uint32_t hold_time;

	/** Minimum TTL. */
	uint8_t ttl;
	/** Detection multiplier. */
	uint8_t detect_mult;
	/** Reserved / zeroed. */
	uint16_t zero;

	/** Interface index (set to `0` when unavailable). */
	uint32_t ifindex;
	/** Interface name (empty when unavailable). */
	char ifname[64];

	/* TODO: missing authentication. */
};

/** BFD packet state values as defined in RFC 5880, Section 4.1. */
enum bfd_state_value {
	/** Session is administratively down. */
	STATE_ADMINDOWN = 0,
	/** Session is down or went down. */
	STATE_DOWN = 1,
	/** Session is initializing. */
	STATE_INIT = 2,
	/** Session is up. */
	STATE_UP = 3,
};

/** BFD diagnostic field values as defined in RFC 5880, Section 4.1. */
enum bfd_diagnostic_value {
	/** Nothing was diagnosed. */
	DIAG_NOTHING = 0,
	/** Control detection time expired. */
	DIAG_CONTROL_EXPIRED = 1,
	/** Echo function failed. */
	DIAG_ECHO_FAILED = 2,
	/** Neighbor signaled down. */
	DIAG_DOWN = 3,
	/** Forwarding plane reset. */
	DIAG_FP_RESET = 4,
	/** Path down. */
	DIAG_PATH_DOWN = 5,
	/** Concatenated path down. */
	DIAG_CONCAT_PATH_DOWN = 6,
	/** Administratively down. */
	DIAG_ADMIN_DOWN = 7,
	/** Reverse concatenated path down. */
	DIAG_REV_CONCAT_PATH_DOWN = 8,
};

/** BFD remote state flags. */
enum bfd_remote_flags {
	/** Control Plane Independent bit. */
	RBIT_CPI = (1 << 0),
	/** Demand mode bit. */
	RBIT_DEMAND = (1 << 1),
	/** Multipoint bit. */
	RBIT_MP = (1 << 2),
};

/**
 * `BFD_STATE_CHANGE` data payload.
 */
struct bfddp_state_change {
	/** Local discriminator. */
	uint32_t lid;
	/** Remote discriminator. */
	uint32_t rid;
	/** Remote configurations/bits set. \see bfd_remote_flags. */
	uint32_t remote_flags;
	/** Remote minimum desired transmission interval. */
	uint32_t desired_tx;
	/** Remote minimum receive interval. */
	uint32_t required_rx;
	/** Remote minimum echo receive interval. */
	uint32_t required_echo_rx;
	/** Remote state. \see bfd_state_values.*/
	uint8_t state;
	/** Remote diagnostics (if any) */
	uint8_t diagnostics;
	/** Remote detection multiplier. */
	uint8_t detection_multiplier;
};

/**
 * BFD control packet state bits definition.
 */
enum bfddp_control_state_bits {
	/** Used to request connection establishment signal. */
	STATE_POLL_BIT = (1 << 5),
	/** Finalizes the connection establishment signal. */
	STATE_FINAL_BIT = (1 << 4),
	/** Signalizes that forward plane doesn't depend on control plane. */
	STATE_CPI_BIT = (1 << 3),
	/** Signalizes the use of authentication. */
	STATE_AUTH_BIT = (1 << 2),
	/** Signalizes that peer is using demand mode. */
	STATE_DEMAND_BIT = (1 << 1),
	/** Used in RFC 8562 implementation. */
	STATE_MULTI_BIT = (1 << 0),
};

/**
 * BFD control packet.
 *
 * As defined in 'RFC 5880 Section 4.1 Generic BFD Control Packet Format'.
 */
struct bfddp_control_packet {
	/** (3 bits version << 5) | (5 bits diag). */
	uint8_t version_diag;
	/**
	 * (2 bits state << 6) | (6 bits flags)
	 *
	 * \see bfd_state_value, bfddp_control_state_bits.
	 */
	uint8_t state_bits;
	/** Detection multiplier. */
	uint8_t detection_multiplier;
	/** Packet length in bytes. */
	uint8_t length;
	/** Our discriminator. */
	uint32_t local_id;
	/** Remote system discriminator. */
	uint32_t remote_id;
	/** Desired minimum send interval in microseconds. */
	uint32_t desired_tx;
	/** Desired minimum receive interval in microseconds. */
	uint32_t required_rx;
	/** Desired minimum echo receive interval in microseconds. */
	uint32_t required_echo_rx;
};

/**
 * The protocol wire message header structure.
 */
struct bfddp_message_header {
	/** Protocol version format. \see BFD_DP_VERSION. */
	uint8_t version;
	/** Reserved / zero field. */
	uint8_t zero;
	/** Message contents type. \see bfddp_message_type. */
	uint16_t type;
	/**
	 * Message identification (to pair request/response).
	 *
	 * The ID `0` is reserved for asynchronous messages (e.g. unrequested
	 * messages).
	 */
	uint16_t id;
	/** Message length. */
	uint16_t length;
};

/**
 * Data plane session counters request.
 *
 * Message type: `DP_REQUEST_SESSION_COUNTERS`.
 */
struct bfddp_request_counters {
	/** Session local discriminator. */
	uint32_t lid;
};

/**
 * BFD session counters reply.
 *
 * Message type: `BFD_SESSION_COUNTERS`.
 */
struct bfddp_session_counters {
	/** Session local discriminator. */
	uint32_t lid;

	/** Control packet bytes input. */
	uint64_t control_input_bytes;
	/** Control packets input. */
	uint64_t control_input_packets;
	/** Control packet bytes output. */
	uint64_t control_output_bytes;
	/** Control packets output. */
	uint64_t control_output_packets;

	/** Echo packet bytes input. */
	uint64_t echo_input_bytes;
	/** Echo packets input. */
	uint64_t echo_input_packets;
	/** Echo packet bytes output. */
	uint64_t echo_output_bytes;
	/** Echo packets output. */
	uint64_t echo_output_packets;
};

/**
 * The protocol wire messages structure.
 */
struct bfddp_message {
	/** Message header. \see bfddp_message_header. */
	struct bfddp_message_header header;

	/** Message payload. \see bfddp_message_type. */
	union {
		struct bfddp_echo echo;
		struct bfddp_session session;
		struct bfddp_state_change state;
		struct bfddp_control_packet control;
		struct bfddp_request_counters counters_req;
		struct bfddp_session_counters session_counters;
	} data;
};

#endif /* BFD_DP_PACKET_H */