summaryrefslogtreecommitdiffstats
path: root/vrrpd/vrrp.h
blob: d060b95dfab2a4167d7254bb5de6dea0cdb0f109 (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
/*
 * VRRP global definitions and state machine.
 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
 * Quentin Young
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; see the file COPYING; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */
#ifndef __VRRP_H__
#define __VRRP_H__

#include <zebra.h>
#include <netinet/ip.h>

#include "lib/hash.h"
#include "lib/hook.h"
#include "lib/if.h"
#include "lib/linklist.h"
#include "lib/privs.h"
#include "lib/stream.h"
#include "lib/thread.h"

/* Global definitions */
#define VRRP_DEFAULT_ADVINT 100
#define VRRP_DEFAULT_PRIORITY 100
#define VRRP_RADV_INT 16
#define VRRP_PRIO_MASTER 255
#define VRRP_MCASTV4_GROUP_STR "224.0.0.18"
#define VRRP_MCASTV6_GROUP_STR "ff02:0:0:0:0:0:0:12"
#define VRRP_MCASTV4_GROUP 0xe0000012
#define VRRP_MCASTV6_GROUP 0xff020000000000000000000000000012
#define IPPROTO_VRRP 112

#define VRRP_LOGPFX_VRID "[VRID: %u] "

/* threadmaster */
extern struct thread_master *master;

/* privileges */
extern struct zebra_privs_t vrrp_privs;

/* Global hash of all Virtual Routers */
struct hash *vrrp_vrouters_hash;

/*
 * VRRP Router.
 *
 * This struct contains all state for a particular VRRP Router operating in a
 * Virtual Router for either IPv4 or IPv6.
 */
struct vrrp_router {
	/*
	 * Whether this VRRP Router is active.
	 */
	bool is_active;

	/* Whether we are the address owner */
	bool is_owner;

	/* Rx socket: Rx from parent of mvl_ifp */
	int sock_rx;
	/* Tx socket; Tx from mvl_ifp */
	int sock_tx;

	/* macvlan interface */
	struct interface *mvl_ifp;

	/* Source address for advertisements */
	struct ipaddr src;

	/* Socket read buffer */
	uint8_t ibuf[IP_MAXPACKET];

	/*
	 * Address family of this Virtual Router.
	 * Either AF_INET or AF_INET6.
	 */
	int family;

	/*
	 * Virtual Router this VRRP Router is participating in.
	 */
	struct vrrp_vrouter *vr;

	/*
	 * One or more IPvX addresses associated with this Virtual
	 * Router. The first address must be the "primary" address this
	 * Virtual Router is backing up in the case of IPv4. In the case of
	 * IPv6 it must be the link-local address of vr->ifp.
	 *
	 * Type: struct ipaddr *
	 */
	struct list *addrs;

	/*
	 * Effective priority
	 *    => vr->priority if we are Backup
	 *    => 255 if we are Master
	 */
	uint8_t priority;

	/*
	 * Advertisement interval contained in ADVERTISEMENTS received from the
	 * Master (centiseconds)
	 */
	uint16_t master_adver_interval;

	/*
	 * Time to skew Master_Down_Interval in centiseconds. Calculated as:
	 * (((256 - priority) * Master_Adver_Interval) / 256)
	 */
	uint16_t skew_time;

	/*
	 * Time interval for Backup to declare Master down (centiseconds).
	 * Calculated as:
	 * (3 * Master_Adver_Interval) + Skew_time
	 */
	uint16_t master_down_interval;

	/*
	 * The MAC address used for the source MAC address in VRRP
	 * advertisements, advertised in ARP requests/responses, and advertised
	 * in ND Neighbor Advertisements.
	 */
	struct ethaddr vmac;

	struct {
		int state;
	} fsm;

	struct thread *t_master_down_timer;
	struct thread *t_adver_timer;
	struct thread *t_read;
	struct thread *t_write;
};

/*
 * VRRP Virtual Router.
 *
 * This struct contains all state and configuration for a given Virtual Router
 * Identifier on a given interface, both v4 and v6.
 *
 * RFC5798 s. 1 states:
 *    "Within a VRRP router, the virtual routers in each of the IPv4 and IPv6
 *    address families are a domain unto themselves and do not overlap."
 *
 * This implementation has chosen the tuple (interface, VRID) as the key for a
 * particular VRRP Router, and the rest of the program is designed around this
 * assumption. Additionally, base protocol configuration parameters such as the
 * advertisement interval and (configured) priority are shared between v4 and
 * v6 instances. This corresponds to the choice made by other industrial
 * implementations.
 */
struct vrrp_vrouter {
	/* Interface */
	struct interface *ifp;

	/* Version */
	uint8_t version;

	/* Virtual Router Identifier */
	uint32_t vrid;

	/* Configured priority */
	uint8_t priority;

	/*
	 * Time interval between ADVERTISEMENTS (centiseconds). Default is 100
	 * centiseconds (1 second).
	 */
	uint16_t advertisement_interval;

	/*
	 * Controls whether a (starting or restarting) higher-priority Backup
	 * router preempts a lower-priority Master router. Values are True to
	 * allow preemption and False to prohibit preemption. Default is True.
	 */
	bool preempt_mode;

	/*
	 * Controls whether a virtual router in Master state will accept
	 * packets addressed to the address owner's IPvX address as its own if
	 * it is not the IPvX address owner. The default is False.
	 */
	bool accept_mode;

	struct vrrp_router *v4;
	struct vrrp_router *v6;
};

/*
 * Initialize VRRP global datastructures.
 */
void vrrp_init(void);


/* Creation and destruction ------------------------------------------------ */

/*
 * Create and register a new VRRP Virtual Router.
 *
 * ifp
 *    Base interface to configure VRRP on
 *
 * vrid
 *    Virtual Router Identifier
 */
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid);

/*
 * Destroy a VRRP Virtual Router, freeing all its resources.
 *
 * If there are any running VRRP instances, these are stopped and destroyed.
 */
void vrrp_vrouter_destroy(struct vrrp_vrouter *vr);


/* Configuration controllers ----------------------------------------------- */

/*
 * Change the configured priority of a VRRP Virtual Router.
 *
 * Note that this only changes the configured priority of the Virtual Router.
 * The currently effective priority will not be changed; to change the
 * effective priority, the Virtual Router must be restarted by issuing a
 * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP.
 *
 * vr
 *    Virtual Router to change priority of
 *
 * priority
 *    New priority
 */
void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority);

/*
 * Set Advertisement Interval on this Virtual Router.
 *
 * vr
 *    Virtual Router to change priority of
 *
 * advertisement_interval
 *    New advertisement interval
 */
void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr,
				     uint16_t advertisement_interval);

/*
 * Add an IPvX address to a VRRP Virtual Router.
 *
 * vr
 *    Virtual Router to add IPvx address to
 *
 * ip
 *    Address to add
 */
void vrrp_add_ip(struct vrrp_vrouter *vr, struct ipaddr ip);

/*
 * Add an IPv4 address to a VRRP Virtual Router.
 *
 * vr
 *    Virtual Router to add IPv4 address to
 *
 * v4
 *    Address to add
 */
void vrrp_add_ipv4(struct vrrp_vrouter *vr, struct in_addr v4);

/*
 * Add an IPv6 address to a VRRP Virtual Router.
 *
 * vr
 *    Virtual Router to add IPv6 address to
 *
 * v6
 *    Address to add
 */
void vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6);


/* State machine ----------------------------------------------------------- */

#define VRRP_STATE_INITIALIZE 0
#define VRRP_STATE_MASTER 1
#define VRRP_STATE_BACKUP 2
#define VRRP_EVENT_STARTUP 0
#define VRRP_EVENT_SHUTDOWN 1

extern const char *vrrp_state_names[3];
extern const char *vrrp_event_names[2];

/*
 * This hook called whenever the state of a Virtual Router changes, after the
 * specific internal state handlers have run.
 *
 * Use this if you need to react to state changes to perform non-critical
 * tasks. Critical tasks should go in the internal state change handlers.
 */
DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_router * r, int to), (r, to));

/*
 * Trigger a VRRP event on a given Virtual Router..
 *
 * vr
 *    Virtual Router to operate on
 *
 * event
 *    Event to kick off. All event related processing will have completed upon
 *    return of this function.
 *
 * Returns:
 *    < 0 if the event created an error
 *      0 otherwise
 */
int vrrp_event(struct vrrp_router *r, int event);


/* Other ------------------------------------------------------------------- */

/*
 * Find VRRP Virtual Router by Virtual Router ID
 */
struct vrrp_vrouter *vrrp_lookup(uint8_t vrid);

#endif /* __VRRP_H__ */