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