Import Upstream version 1.2.2
[quagga-debian.git] / qpb / qpb.h
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  *
20  * You should have received a copy of the GNU General Public License
21  * along with Quagga; see the file COPYING.  If not, write to the Free
22  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23  * 02111-1307, USA.
24  */
25
26 /*
27  * Main public header file for the quagga protobuf library.
28  */
29
30 #ifndef _QPB_H
31 #define _QPB_H
32
33 #include "prefix.h"
34
35 #include "qpb/qpb.pb-c.h"
36
37 #include "qpb/qpb_allocator.h"
38
39 /*
40  * qpb__address_family__set
41  */
42 #define qpb_address_family_set qpb__address_family__set
43 static inline int
44 qpb__address_family__set (Qpb__AddressFamily *pb_family, u_char family)
45 {
46   switch (family) {
47   case AF_INET:
48     *pb_family = QPB__ADDRESS_FAMILY__IPV4;
49     return 1;
50
51   case AF_INET6:
52     *pb_family = QPB__ADDRESS_FAMILY__IPV6;
53     return 1;
54
55   default:
56     *pb_family = QPB__ADDRESS_FAMILY__UNKNOWN_AF;
57   }
58
59   return 0;
60 }
61
62 /*
63  * qpb__address_family__get
64  */
65 #define qpb_address_family_get qpb__address_family__get
66 static inline int
67 qpb__address_family__get (Qpb__AddressFamily pb_family, u_char *family)
68 {
69
70   switch (pb_family) {
71   case QPB__ADDRESS_FAMILY__IPV4:
72     *family = AF_INET;
73     return 1;
74
75   case QPB__ADDRESS_FAMILY__IPV6:
76     *family = AF_INET6;
77     return 1;
78
79   case QPB__ADDRESS_FAMILY__UNKNOWN_AF:
80     return 0;
81   }
82
83   return 0;
84 }
85
86 /*
87  * qpb__l3_prefix__create
88  */
89 #define qpb_l3_prefix_create qpb__l3_prefix__create
90 static inline Qpb__L3Prefix *
91 qpb__l3_prefix__create (qpb_allocator_t *allocator, struct prefix *p)
92 {
93   Qpb__L3Prefix *prefix;
94
95   prefix = QPB_ALLOC(allocator, typeof(*prefix));
96   if (!prefix) {
97     return NULL;
98   }
99   qpb__l3_prefix__init(prefix);
100   prefix->length = p->prefixlen;
101   prefix->bytes.len = (p->prefixlen + 7)/8;
102   prefix->bytes.data = qpb_alloc(allocator, prefix->bytes.len);
103   if (!prefix->bytes.data) {
104     return NULL;
105   }
106
107   memcpy(prefix->bytes.data, &p->u.prefix, prefix->bytes.len);
108
109   return prefix;
110 }
111
112 /*
113  * qpb__l3_prefix__get
114  */
115 #define qpb_l3_prefix_get qpb__l3_prefix__get
116 static inline int
117 qpb__l3_prefix__get (const Qpb__L3Prefix *pb_prefix, u_char family,
118                      struct prefix *prefix)
119 {
120
121   switch (family)
122     {
123
124     case AF_INET:
125       memset(prefix, 0, sizeof(struct prefix_ipv4));
126       break;
127
128     case AF_INET6:
129       memset(prefix, 0, sizeof(struct prefix_ipv6));
130       break;
131
132     default:
133       memset(prefix, 0, sizeof(*prefix));
134     }
135
136   prefix->prefixlen = pb_prefix->length;
137   prefix->family = family;
138   memcpy(&prefix->u.prefix, pb_prefix->bytes.data, pb_prefix->bytes.len);
139   return 1;
140 }
141
142 /*
143  * qpb__protocol__set
144  *
145  * Translate a quagga route type to a protobuf protocol.
146  */
147 #define qpb_protocol_set qpb__protocol__set
148 static inline int
149 qpb__protocol__set (Qpb__Protocol *pb_proto, int route_type)
150 {
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_BABEL:
188   case ZEBRA_ROUTE_MAX:
189   case ZEBRA_ROUTE_SYSTEM:
190   default:
191     *pb_proto = QPB__PROTOCOL__OTHER;
192   }
193
194   return 1;
195 }
196
197 /*
198  * qpb__ipv4_address__create
199  */
200 static inline Qpb__Ipv4Address *
201 qpb__ipv4_address__create (qpb_allocator_t *allocator,
202                            struct in_addr *addr)
203 {
204   Qpb__Ipv4Address *v4;
205
206   v4 = QPB_ALLOC(allocator, typeof(*v4));
207   if (!v4) {
208     return NULL;
209   }
210   qpb__ipv4_address__init(v4);
211
212   v4->value = ntohl(addr->s_addr);
213   return v4;
214 }
215
216 /*
217  * qpb__ipv4_address__get
218  */
219 static inline int
220 qpb__ipv4_address__get (const Qpb__Ipv4Address *v4, struct in_addr *addr)
221 {
222   addr->s_addr = htonl(v4->value);
223   return 1;
224 }
225
226 /*
227  * qpb__ipv6_address__create
228  */
229 static inline Qpb__Ipv6Address *
230 qpb__ipv6_address__create (qpb_allocator_t *allocator, struct in6_addr *addr)
231 {
232   Qpb__Ipv6Address *v6;
233
234   v6 = QPB_ALLOC(allocator, typeof(*v6));
235   if (!v6)
236     return NULL;
237
238   qpb__ipv6_address__init(v6);
239   v6->bytes.len = 16;
240   v6->bytes.data = qpb_alloc(allocator, 16);
241   if (!v6->bytes.data)
242     return NULL;
243
244   memcpy(v6->bytes.data, addr->s6_addr, v6->bytes.len);
245   return v6;
246 }
247
248 /*
249  * qpb__ipv6_address__get
250  *
251  * Read out information from a protobuf ipv6 address structure.
252  */
253 static inline int
254 qpb__ipv6_address__get (const Qpb__Ipv6Address *v6, struct in6_addr *addr)
255 {
256   if (v6->bytes.len != 16)
257     return 0;
258
259   memcpy(addr->s6_addr, v6->bytes.data, v6->bytes.len);
260   return 1;
261 }
262
263 /*
264  * qpb__l3_address__create
265  */
266 #define qpb_l3_address_create qpb__l3_address__create
267 static inline Qpb__L3Address *
268 qpb__l3_address__create (qpb_allocator_t *allocator, union g_addr *addr,
269                          u_char family)
270 {
271   Qpb__L3Address *l3_addr;
272
273   l3_addr = QPB_ALLOC(allocator, typeof(*l3_addr));
274   if (!l3_addr)
275     return NULL;
276
277   qpb__l3_address__init(l3_addr);
278
279   switch (family) {
280
281   case AF_INET:
282     l3_addr->v4 = qpb__ipv4_address__create (allocator, &addr->ipv4);
283     if (!l3_addr->v4)
284       return NULL;
285
286     break;
287
288   case AF_INET6:
289     l3_addr->v6 = qpb__ipv6_address__create (allocator, &addr->ipv6);
290     if (!l3_addr->v6)
291       return NULL;
292
293     break;
294   }
295   return l3_addr;
296 }
297
298 /*
299  * qpb__l3_address__get
300  *
301  * Read out a gateway address from a protobuf l3 address.
302  */
303 #define qpb_l3_address_get qpb__l3_address__get
304 static inline int
305 qpb__l3_address__get (const Qpb__L3Address *l3_addr,
306                       u_char *family, union g_addr *addr)
307 {
308   if (l3_addr->v4)
309     {
310       qpb__ipv4_address__get (l3_addr->v4, &addr->ipv4);
311       *family = AF_INET;
312       return 1;
313     }
314
315   if (l3_addr->v6)
316     {
317       qpb__ipv6_address__get(l3_addr->v6, &addr->ipv6);
318       *family = AF_INET6;
319       return 1;
320     }
321
322   return 0;
323 }
324
325 /*
326  * qpb__if_identifier__create
327  */
328 #define qpb_if_identifier_create qpb__if_identifier__create
329 static inline Qpb__IfIdentifier *
330 qpb__if_identifier__create (qpb_allocator_t *allocator, uint if_index)
331 {
332   Qpb__IfIdentifier *if_id;
333
334   if_id = QPB_ALLOC(allocator, typeof(*if_id));
335   if (!if_id) {
336     return NULL;
337   }
338   qpb__if_identifier__init(if_id);
339   if_id->has_index = 1;
340   if_id->index = if_index;
341   return if_id;
342 }
343
344 /*
345  * qpb__if_identifier__get
346  *
347  * Get interface name and/or if_index from an if identifier.
348  */
349 #define qpb_if_identifier_get qpb__if_identifier__get
350 static inline int
351 qpb__if_identifier__get (Qpb__IfIdentifier *if_id, uint *if_index,
352                          char **name)
353 {
354   char *str;
355   uint ix;
356
357   if (!if_index)
358     if_index = &ix;
359
360   if (!name)
361     name = &str;
362
363   if (if_id->has_index)
364     *if_index = if_id->index;
365   else
366     *if_index = 0;
367
368   *name = if_id->name;
369   return 1;
370 }
371
372 #endif