]> git.proxmox.com Git - mirror_frr.git/blob - qpb/qpb.h
Merge pull request #13088 from donaldsharp/pim_use_after
[mirror_frr.git] / qpb / qpb.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * qpb.h
4 *
5 * @copyright Copyright (C) 2016 Sproute Networks, Inc.
6 *
7 * @author Avneesh Sachdev <avneesh@sproute.com>
8 */
9
10 /*
11 * Main public header file for the quagga protobuf library.
12 */
13
14 #ifndef _QPB_H
15 #define _QPB_H
16
17 #include "prefix.h"
18
19 #include "qpb/qpb.pb-c.h"
20
21 #include "qpb/qpb_allocator.h"
22
23 /*
24 * qpb__address_family__set
25 */
26 #define qpb_address_family_set qpb__address_family__set
27 static inline int qpb__address_family__set(Qpb__AddressFamily *pb_family,
28 uint8_t family)
29 {
30 switch (family) {
31 case AF_INET:
32 *pb_family = QPB__ADDRESS_FAMILY__IPV4;
33 return 1;
34
35 case AF_INET6:
36 *pb_family = QPB__ADDRESS_FAMILY__IPV6;
37 return 1;
38
39 default:
40 *pb_family = QPB__ADDRESS_FAMILY__UNKNOWN_AF;
41 }
42
43 return 0;
44 }
45
46 /*
47 * qpb__address_family__get
48 */
49 #define qpb_address_family_get qpb__address_family__get
50 static inline int qpb__address_family__get(Qpb__AddressFamily pb_family,
51 uint8_t *family)
52 {
53
54 switch (pb_family) {
55 case QPB__ADDRESS_FAMILY__IPV4:
56 *family = AF_INET;
57 return 1;
58
59 case QPB__ADDRESS_FAMILY__IPV6:
60 *family = AF_INET6;
61 return 1;
62
63 case QPB__ADDRESS_FAMILY__UNKNOWN_AF:
64 return 0;
65 case _QPB__ADDRESS_FAMILY_IS_INT_SIZE:
66 return 0;
67 }
68
69 return 0;
70 }
71
72 /*
73 * qpb__l3_prefix__create
74 */
75 #define qpb_l3_prefix_create qpb__l3_prefix__create
76 static inline Qpb__L3Prefix *qpb__l3_prefix__create(qpb_allocator_t *allocator,
77 struct prefix *p)
78 {
79 Qpb__L3Prefix *prefix;
80
81 prefix = QPB_ALLOC(allocator, typeof(*prefix));
82 if (!prefix) {
83 return NULL;
84 }
85 qpb__l3_prefix__init(prefix);
86 prefix->length = p->prefixlen;
87 prefix->bytes.len = (p->prefixlen + 7) / 8;
88 prefix->bytes.data = qpb_alloc(allocator, prefix->bytes.len);
89 if (!prefix->bytes.data) {
90 return NULL;
91 }
92
93 memcpy(prefix->bytes.data, &p->u.prefix, prefix->bytes.len);
94
95 return prefix;
96 }
97
98 /*
99 * qpb__l3_prefix__get
100 */
101 #define qpb_l3_prefix_get qpb__l3_prefix__get
102 static inline int qpb__l3_prefix__get(const Qpb__L3Prefix *pb_prefix,
103 uint8_t family, struct prefix *prefix)
104 {
105
106 switch (family) {
107
108 case AF_INET:
109 memset((struct prefix_ipv4 *)prefix, 0,
110 sizeof(struct prefix_ipv4));
111 break;
112
113 case AF_INET6:
114 memset((struct prefix_ipv6 *)prefix, 0,
115 sizeof(struct prefix_ipv6));
116 break;
117
118 default:
119 memset(prefix, 0, sizeof(*prefix));
120 }
121
122 prefix->prefixlen = pb_prefix->length;
123 prefix->family = family;
124 memcpy(&prefix->u.prefix, pb_prefix->bytes.data, pb_prefix->bytes.len);
125 return 1;
126 }
127
128 /*
129 * qpb__protocol__set
130 *
131 * Translate a quagga route type to a protobuf protocol.
132 */
133 #define qpb_protocol_set qpb__protocol__set
134 static inline int qpb__protocol__set(Qpb__Protocol *pb_proto, int route_type)
135 {
136 switch (route_type) {
137 case ZEBRA_ROUTE_KERNEL:
138 *pb_proto = QPB__PROTOCOL__KERNEL;
139 break;
140
141 case ZEBRA_ROUTE_CONNECT:
142 *pb_proto = QPB__PROTOCOL__CONNECTED;
143 break;
144
145 case ZEBRA_ROUTE_STATIC:
146 *pb_proto = QPB__PROTOCOL__STATIC;
147 break;
148
149 case ZEBRA_ROUTE_RIP:
150 *pb_proto = QPB__PROTOCOL__RIP;
151 break;
152
153 case ZEBRA_ROUTE_RIPNG:
154 *pb_proto = QPB__PROTOCOL__RIPNG;
155 break;
156
157 case ZEBRA_ROUTE_OSPF:
158 case ZEBRA_ROUTE_OSPF6:
159 *pb_proto = QPB__PROTOCOL__OSPF;
160 break;
161
162 case ZEBRA_ROUTE_ISIS:
163 *pb_proto = QPB__PROTOCOL__ISIS;
164 break;
165
166 case ZEBRA_ROUTE_BGP:
167 *pb_proto = QPB__PROTOCOL__BGP;
168 break;
169
170 case ZEBRA_ROUTE_HSLS:
171 case ZEBRA_ROUTE_OLSR:
172 case ZEBRA_ROUTE_MAX:
173 case ZEBRA_ROUTE_SYSTEM:
174 default:
175 *pb_proto = QPB__PROTOCOL__OTHER;
176 }
177
178 return 1;
179 }
180
181 /*
182 * qpb__ipv4_address__create
183 */
184 static inline Qpb__Ipv4Address *
185 qpb__ipv4_address__create(qpb_allocator_t *allocator, struct in_addr *addr)
186 {
187 Qpb__Ipv4Address *v4;
188
189 v4 = QPB_ALLOC(allocator, typeof(*v4));
190 if (!v4) {
191 return NULL;
192 }
193 qpb__ipv4_address__init(v4);
194
195 v4->value = ntohl(addr->s_addr);
196 return v4;
197 }
198
199 /*
200 * qpb__ipv4_address__get
201 */
202 static inline int qpb__ipv4_address__get(const Qpb__Ipv4Address *v4,
203 struct in_addr *addr)
204 {
205 addr->s_addr = htonl(v4->value);
206 return 1;
207 }
208
209 /*
210 * qpb__ipv6_address__create
211 */
212 static inline Qpb__Ipv6Address *
213 qpb__ipv6_address__create(qpb_allocator_t *allocator, struct in6_addr *addr)
214 {
215 Qpb__Ipv6Address *v6;
216
217 v6 = QPB_ALLOC(allocator, typeof(*v6));
218 if (!v6)
219 return NULL;
220
221 qpb__ipv6_address__init(v6);
222 v6->bytes.len = 16;
223 v6->bytes.data = qpb_alloc(allocator, 16);
224 if (!v6->bytes.data)
225 return NULL;
226
227 memcpy(v6->bytes.data, addr->s6_addr, v6->bytes.len);
228 return v6;
229 }
230
231 /*
232 * qpb__ipv6_address__get
233 *
234 * Read out information from a protobuf ipv6 address structure.
235 */
236 static inline int qpb__ipv6_address__get(const Qpb__Ipv6Address *v6,
237 struct in6_addr *addr)
238 {
239 if (v6->bytes.len != 16)
240 return 0;
241
242 memcpy(addr->s6_addr, v6->bytes.data, v6->bytes.len);
243 return 1;
244 }
245
246 /*
247 * qpb__l3_address__create
248 */
249 #define qpb_l3_address_create qpb__l3_address__create
250 static inline Qpb__L3Address *
251 qpb__l3_address__create(qpb_allocator_t *allocator, union g_addr *addr,
252 uint8_t family)
253 {
254 Qpb__L3Address *l3_addr;
255
256 l3_addr = QPB_ALLOC(allocator, typeof(*l3_addr));
257 if (!l3_addr)
258 return NULL;
259
260 qpb__l3_address__init(l3_addr);
261
262 switch (family) {
263
264 case AF_INET:
265 l3_addr->v4 = qpb__ipv4_address__create(allocator, &addr->ipv4);
266 if (!l3_addr->v4)
267 return NULL;
268
269 break;
270
271 case AF_INET6:
272 l3_addr->v6 = qpb__ipv6_address__create(allocator, &addr->ipv6);
273 if (!l3_addr->v6)
274 return NULL;
275
276 break;
277 }
278 return l3_addr;
279 }
280
281 /*
282 * qpb__l3_address__get
283 *
284 * Read out a gateway address from a protobuf l3 address.
285 */
286 #define qpb_l3_address_get qpb__l3_address__get
287 static inline int qpb__l3_address__get(const Qpb__L3Address *l3_addr,
288 uint8_t *family, union g_addr *addr)
289 {
290 if (l3_addr->v4) {
291 qpb__ipv4_address__get(l3_addr->v4, &addr->ipv4);
292 *family = AF_INET;
293 return 1;
294 }
295
296 if (l3_addr->v6) {
297 qpb__ipv6_address__get(l3_addr->v6, &addr->ipv6);
298 *family = AF_INET6;
299 return 1;
300 }
301
302 return 0;
303 }
304
305 /*
306 * qpb__if_identifier__create
307 */
308 #define qpb_if_identifier_create qpb__if_identifier__create
309 static inline Qpb__IfIdentifier *
310 qpb__if_identifier__create(qpb_allocator_t *allocator, uint if_index)
311 {
312 Qpb__IfIdentifier *if_id;
313
314 if_id = QPB_ALLOC(allocator, typeof(*if_id));
315 if (!if_id) {
316 return NULL;
317 }
318 qpb__if_identifier__init(if_id);
319 if_id->has_index = 1;
320 if_id->index = if_index;
321 return if_id;
322 }
323
324 /*
325 * qpb__if_identifier__get
326 *
327 * Get interface name and/or if_index from an if identifier.
328 */
329 #define qpb_if_identifier_get qpb__if_identifier__get
330 static inline int qpb__if_identifier__get(Qpb__IfIdentifier *if_id,
331 uint *if_index, char **name)
332 {
333 char *str;
334 uint ix;
335
336 if (!if_index)
337 if_index = &ix;
338
339 if (!name)
340 name = &str;
341
342 if (if_id->has_index)
343 *if_index = if_id->index;
344 else
345 *if_index = 0;
346
347 *name = if_id->name;
348 return 1;
349 }
350
351 #endif