| /* |
| * qpb.h |
| * |
| * @copyright Copyright (C) 2016 Sproute Networks, Inc. |
| * |
| * @author Avneesh Sachdev <avneesh@sproute.com> |
| * |
| * This file is part of Quagga. |
| * |
| * Quagga 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, or (at your option) any |
| * later version. |
| * |
| * Quagga 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 Quagga; see the file COPYING. If not, write to the Free |
| * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
| * 02111-1307, USA. |
| */ |
| |
| /* |
| * Main public header file for the quagga protobuf library. |
| */ |
| |
| #ifndef _QPB_H |
| #define _QPB_H |
| |
| #include "prefix.h" |
| |
| #include "qpb/qpb.pb-c.h" |
| |
| #include "qpb/qpb_allocator.h" |
| |
| /* |
| * qpb__address_family__set |
| */ |
| #define qpb_address_family_set qpb__address_family__set |
| static inline int |
| qpb__address_family__set (Qpb__AddressFamily *pb_family, u_char family) |
| { |
| switch (family) { |
| case AF_INET: |
| *pb_family = QPB__ADDRESS_FAMILY__IPV4; |
| return 1; |
| |
| case AF_INET6: |
| *pb_family = QPB__ADDRESS_FAMILY__IPV6; |
| return 1; |
| |
| default: |
| *pb_family = QPB__ADDRESS_FAMILY__UNKNOWN_AF; |
| } |
| |
| return 0; |
| } |
| |
| /* |
| * qpb__address_family__get |
| */ |
| #define qpb_address_family_get qpb__address_family__get |
| static inline int |
| qpb__address_family__get (Qpb__AddressFamily pb_family, u_char *family) |
| { |
| |
| switch (pb_family) { |
| case QPB__ADDRESS_FAMILY__IPV4: |
| *family = AF_INET; |
| return 1; |
| |
| case QPB__ADDRESS_FAMILY__IPV6: |
| *family = AF_INET6; |
| return 1; |
| |
| case QPB__ADDRESS_FAMILY__UNKNOWN_AF: |
| return 0; |
| } |
| |
| return 0; |
| } |
| |
| /* |
| * qpb__l3_prefix__create |
| */ |
| #define qpb_l3_prefix_create qpb__l3_prefix__create |
| static inline Qpb__L3Prefix * |
| qpb__l3_prefix__create (qpb_allocator_t *allocator, struct prefix *p) |
| { |
| Qpb__L3Prefix *prefix; |
| |
| prefix = QPB_ALLOC(allocator, typeof(*prefix)); |
| if (!prefix) { |
| return NULL; |
| } |
| qpb__l3_prefix__init(prefix); |
| prefix->length = p->prefixlen; |
| prefix->bytes.len = (p->prefixlen + 7)/8; |
| prefix->bytes.data = qpb_alloc(allocator, prefix->bytes.len); |
| if (!prefix->bytes.data) { |
| return NULL; |
| } |
| |
| memcpy(prefix->bytes.data, &p->u.prefix, prefix->bytes.len); |
| |
| return prefix; |
| } |
| |
| /* |
| * qpb__l3_prefix__get |
| */ |
| #define qpb_l3_prefix_get qpb__l3_prefix__get |
| static inline int |
| qpb__l3_prefix__get (const Qpb__L3Prefix *pb_prefix, u_char family, |
| struct prefix *prefix) |
| { |
| |
| switch (family) |
| { |
| |
| case AF_INET: |
| memset(prefix, 0, sizeof(struct prefix_ipv4)); |
| break; |
| |
| case AF_INET6: |
| memset(prefix, 0, sizeof(struct prefix_ipv6)); |
| break; |
| |
| default: |
| memset(prefix, 0, sizeof(*prefix)); |
| } |
| |
| prefix->prefixlen = pb_prefix->length; |
| prefix->family = family; |
| memcpy(&prefix->u.prefix, pb_prefix->bytes.data, pb_prefix->bytes.len); |
| return 1; |
| } |
| |
| /* |
| * qpb__protocol__set |
| * |
| * Translate a quagga route type to a protobuf protocol. |
| */ |
| #define qpb_protocol_set qpb__protocol__set |
| static inline int |
| qpb__protocol__set (Qpb__Protocol *pb_proto, int route_type) |
| { |
| switch (route_type) { |
| case ZEBRA_ROUTE_KERNEL: |
| *pb_proto = QPB__PROTOCOL__KERNEL; |
| break; |
| |
| case ZEBRA_ROUTE_CONNECT: |
| *pb_proto = QPB__PROTOCOL__CONNECTED; |
| break; |
| |
| case ZEBRA_ROUTE_STATIC: |
| *pb_proto = QPB__PROTOCOL__STATIC; |
| break; |
| |
| case ZEBRA_ROUTE_RIP: |
| *pb_proto = QPB__PROTOCOL__RIP; |
| break; |
| |
| case ZEBRA_ROUTE_RIPNG: |
| *pb_proto = QPB__PROTOCOL__RIPNG; |
| break; |
| |
| case ZEBRA_ROUTE_OSPF: |
| case ZEBRA_ROUTE_OSPF6: |
| *pb_proto = QPB__PROTOCOL__OSPF; |
| break; |
| |
| case ZEBRA_ROUTE_ISIS: |
| *pb_proto = QPB__PROTOCOL__ISIS; |
| break; |
| |
| case ZEBRA_ROUTE_BGP: |
| *pb_proto = QPB__PROTOCOL__BGP; |
| break; |
| |
| case ZEBRA_ROUTE_HSLS: |
| case ZEBRA_ROUTE_OLSR: |
| case ZEBRA_ROUTE_BABEL: |
| case ZEBRA_ROUTE_MAX: |
| case ZEBRA_ROUTE_SYSTEM: |
| default: |
| *pb_proto = QPB__PROTOCOL__OTHER; |
| } |
| |
| return 1; |
| } |
| |
| /* |
| * qpb__ipv4_address__create |
| */ |
| static inline Qpb__Ipv4Address * |
| qpb__ipv4_address__create (qpb_allocator_t *allocator, |
| struct in_addr *addr) |
| { |
| Qpb__Ipv4Address *v4; |
| |
| v4 = QPB_ALLOC(allocator, typeof(*v4)); |
| if (!v4) { |
| return NULL; |
| } |
| qpb__ipv4_address__init(v4); |
| |
| v4->value = ntohl(addr->s_addr); |
| return v4; |
| } |
| |
| /* |
| * qpb__ipv4_address__get |
| */ |
| static inline int |
| qpb__ipv4_address__get (const Qpb__Ipv4Address *v4, struct in_addr *addr) |
| { |
| addr->s_addr = htonl(v4->value); |
| return 1; |
| } |
| |
| /* |
| * qpb__ipv6_address__create |
| */ |
| static inline Qpb__Ipv6Address * |
| qpb__ipv6_address__create (qpb_allocator_t *allocator, struct in6_addr *addr) |
| { |
| Qpb__Ipv6Address *v6; |
| |
| v6 = QPB_ALLOC(allocator, typeof(*v6)); |
| if (!v6) |
| return NULL; |
| |
| qpb__ipv6_address__init(v6); |
| v6->bytes.len = 16; |
| v6->bytes.data = qpb_alloc(allocator, 16); |
| if (!v6->bytes.data) |
| return NULL; |
| |
| memcpy(v6->bytes.data, addr->s6_addr, v6->bytes.len); |
| return v6; |
| } |
| |
| /* |
| * qpb__ipv6_address__get |
| * |
| * Read out information from a protobuf ipv6 address structure. |
| */ |
| static inline int |
| qpb__ipv6_address__get (const Qpb__Ipv6Address *v6, struct in6_addr *addr) |
| { |
| if (v6->bytes.len != 16) |
| return 0; |
| |
| memcpy(addr->s6_addr, v6->bytes.data, v6->bytes.len); |
| return 1; |
| } |
| |
| /* |
| * qpb__l3_address__create |
| */ |
| #define qpb_l3_address_create qpb__l3_address__create |
| static inline Qpb__L3Address * |
| qpb__l3_address__create (qpb_allocator_t *allocator, union g_addr *addr, |
| u_char family) |
| { |
| Qpb__L3Address *l3_addr; |
| |
| l3_addr = QPB_ALLOC(allocator, typeof(*l3_addr)); |
| if (!l3_addr) |
| return NULL; |
| |
| qpb__l3_address__init(l3_addr); |
| |
| switch (family) { |
| |
| case AF_INET: |
| l3_addr->v4 = qpb__ipv4_address__create (allocator, &addr->ipv4); |
| if (!l3_addr->v4) |
| return NULL; |
| |
| break; |
| |
| case AF_INET6: |
| l3_addr->v6 = qpb__ipv6_address__create (allocator, &addr->ipv6); |
| if (!l3_addr->v6) |
| return NULL; |
| |
| break; |
| } |
| return l3_addr; |
| } |
| |
| /* |
| * qpb__l3_address__get |
| * |
| * Read out a gateway address from a protobuf l3 address. |
| */ |
| #define qpb_l3_address_get qpb__l3_address__get |
| static inline int |
| qpb__l3_address__get (const Qpb__L3Address *l3_addr, |
| u_char *family, union g_addr *addr) |
| { |
| if (l3_addr->v4) |
| { |
| qpb__ipv4_address__get (l3_addr->v4, &addr->ipv4); |
| *family = AF_INET; |
| return 1; |
| } |
| |
| if (l3_addr->v6) |
| { |
| qpb__ipv6_address__get(l3_addr->v6, &addr->ipv6); |
| *family = AF_INET6; |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| /* |
| * qpb__if_identifier__create |
| */ |
| #define qpb_if_identifier_create qpb__if_identifier__create |
| static inline Qpb__IfIdentifier * |
| qpb__if_identifier__create (qpb_allocator_t *allocator, uint if_index) |
| { |
| Qpb__IfIdentifier *if_id; |
| |
| if_id = QPB_ALLOC(allocator, typeof(*if_id)); |
| if (!if_id) { |
| return NULL; |
| } |
| qpb__if_identifier__init(if_id); |
| if_id->has_index = 1; |
| if_id->index = if_index; |
| return if_id; |
| } |
| |
| /* |
| * qpb__if_identifier__get |
| * |
| * Get interface name and/or if_index from an if identifier. |
| */ |
| #define qpb_if_identifier_get qpb__if_identifier__get |
| static inline int |
| qpb__if_identifier__get (Qpb__IfIdentifier *if_id, uint *if_index, |
| char **name) |
| { |
| char *str; |
| uint ix; |
| |
| if (!if_index) |
| if_index = &ix; |
| |
| if (!name) |
| name = &str; |
| |
| if (if_id->has_index) |
| *if_index = if_id->index; |
| else |
| *if_index = 0; |
| |
| *name = if_id->name; |
| return 1; |
| } |
| |
| #endif |