]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_packet.h
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / vrrpd / vrrp_packet.h
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
5435a2bf 2/*
63d4bd12
QY
3 * VRRP packet crafting.
4 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
5 * Quentin Young
5435a2bf 6 */
63d4bd12
QY
7#ifndef __VRRP_PACKET_H__
8#define __VRRP_PACKET_H__
9
5435a2bf
QY
10#include <zebra.h>
11
63d4bd12
QY
12#include "lib/ipaddr.h"
13#include "lib/memory.h"
14#include "lib/prefix.h"
5435a2bf 15
5435a2bf
QY
16#define VRRP_TYPE_ADVERTISEMENT 1
17
ef4cc1eb
QY
18/*
19 * Shared header for VRRPv2/v3 packets.
20 */
21struct vrrp_hdr {
3eca3857
QY
22 /*
23 * H L H L
24 * 0000 0000
25 * ver type
26 */
27 uint8_t vertype;
5435a2bf
QY
28 uint8_t vrid;
29 uint8_t priority;
ef4cc1eb
QY
30 uint8_t naddr;
31 union {
32 struct {
33 uint8_t auth_type;
34 /* advertisement interval (in sec) */
35 uint8_t adver_int;
36 } v2;
37 struct {
3eca3857
QY
38 /*
39 * advertisement interval (in centiseconds)
40 * H L H L
41 * 0000 000000000000
42 * rsvd adver_int
43 */
44 uint16_t adver_int;
ef4cc1eb
QY
45 } v3;
46 };
47 uint16_t chksum;
91188ca6
QY
48} __attribute__((packed));
49
50#define VRRP_HDR_SIZE sizeof(struct vrrp_hdr)
ef4cc1eb
QY
51
52struct vrrp_pkt {
53 struct vrrp_hdr hdr;
91188ca6
QY
54 /*
55 * When used, this is actually an array of one or the other, not an
56 * array of union. If N v4 addresses are stored then
57 * sizeof(addrs) == N * sizeof(struct in_addr).
c2034b25
QY
58 *
59 * Under v2, the last 2 entries in this array are the authentication
60 * data fields. We don't support auth in v2 so these are always just 8
61 * bytes of 0x00.
91188ca6 62 */
5435a2bf
QY
63 union {
64 struct in_addr v4;
65 struct in6_addr v6;
66 } addrs[];
91188ca6
QY
67} __attribute__((packed));
68
c2034b25 69#define VRRP_PKT_SIZE(_f, _ver, _naddr) \
91188ca6
QY
70 ({ \
71 size_t _asz = ((_f) == AF_INET) ? sizeof(struct in_addr) \
72 : sizeof(struct in6_addr); \
c2034b25
QY
73 size_t _auth = 2 * sizeof(uint32_t) * (3 - (_ver)); \
74 sizeof(struct vrrp_hdr) + (_asz * (_naddr)) + _auth; \
91188ca6
QY
75 })
76
c2034b25
QY
77#define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 3, 1)
78#define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 2, 255)
79#define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 1)
80#define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 255)
91188ca6
QY
81
82#define VRRP_MIN_PKT_SIZE VRRP_MIN_PKT_SIZE_V4
83#define VRRP_MAX_PKT_SIZE VRRP_MAX_PKT_SIZE_V6
5435a2bf
QY
84
85/*
d9e01e1c 86 * Builds a VRRP ADVERTISEMENT packet.
3eca3857
QY
87 *
88 * pkt
89 * Pointer to store pointer to result buffer in
90 *
d9e01e1c
QY
91 * src
92 * Source address packet will be transmitted from. This is needed to compute
93 * the VRRP checksum. The returned packet must be sent in an IP datagram with
94 * the source address equal to this field, or the checksum will be invalid.
95 *
96 * version
97 * VRRP version; must be 2 or 3
98 *
3eca3857
QY
99 * vrid
100 * Virtual Router Identifier
101 *
102 * prio
103 * Virtual Router Priority
104 *
105 * max_adver_int
106 * time between ADVERTISEMENTs
107 *
108 * v6
109 * whether 'ips' is an array of v4 or v6 addresses
110 *
111 * numip
112 * number of IPvX addresses in 'ips'
113 *
114 * ips
115 * array of pointer to either struct in_addr (v6 = false) or struct in6_addr
116 * (v6 = true)
5435a2bf 117 */
d9e01e1c
QY
118ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src,
119 uint8_t version, uint8_t vrid, uint8_t prio,
120 uint16_t max_adver_int, uint8_t numip,
9f2379bd 121 struct ipaddr **ips, bool ipv4_ph);
91188ca6 122
7c136b08
DL
123/* free memory allocated by vrrp_pkt_adver_build's pkt arg */
124void vrrp_pkt_free(struct vrrp_pkt *pkt);
125
91188ca6 126/*
d9e01e1c 127 * Dumps a VRRP ADVERTISEMENT packet to a string.
91188ca6
QY
128 *
129 * Currently only dumps the header.
130 *
131 * buf
132 * Buffer to store string representation
133 *
134 * buflen
135 * Size of buf
136 *
137 * pkt
138 * Packet to dump to a string
139 *
140 * Returns:
141 * # bytes written to buf
142 */
d9e01e1c 143size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt);
91188ca6
QY
144
145
146/*
147 * Parses a VRRP packet, checking for illegal or invalid data.
148 *
8cb3d803
QY
149 * This function parses both VRRPv2 and VRRPv3 packets. Which version is
150 * expected is determined by the version argument. For example, if version is 3
151 * and the received packet has version field 2 it will fail to parse.
152 *
153 * Note that this function only checks whether the packet itself is a valid
154 * VRRP packet. It is up to the caller to validate whether the VRID is correct,
155 * priority and timer values are correct, etc.
91188ca6
QY
156 *
157 * family
158 * Address family of received packet
159 *
8cb3d803
QY
160 * version
161 * VRRP version to use for validation
162 *
91188ca6
QY
163 * m
164 * msghdr containing results of recvmsg() on VRRP router socket
165 *
166 * read
8cb3d803 167 * Return value of recvmsg() on VRRP router socket; must be non-negative
91188ca6 168 *
d04bb25a
QY
169 * src
170 * Pointer to struct ipaddr to store address of datagram sender
171 *
91188ca6
QY
172 * pkt
173 * Pointer to pointer to set to location of VRRP packet within buf
174 *
175 * errmsg
176 * Buffer to store human-readable error message in case of error; may be
177 * NULL, in which case no message will be stored
178 *
179 * errmsg_len
180 * Size of errmsg
181 *
182 * Returns:
183 * Size of VRRP packet, or -1 upon error
184 */
9f2379bd
SY
185ssize_t vrrp_pkt_parse_datagram(int family, int version, bool ipv4_ph,
186 struct msghdr *m, size_t read,
187 struct ipaddr *src, struct vrrp_pkt **pkt,
188 char *errmsg, size_t errmsg_len);
63d4bd12
QY
189
190#endif /* __VRRP_PACKET_H__ */