diff options
| author | Avneesh Sachdev <avneesh@sproute.com> | 2016-04-04 10:54:55 -0700 | 
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-09-23 12:12:16 -0400 | 
| commit | dad253b46d62d71b61d11cab94a7fe68acfed677 (patch) | |
| tree | 1d56dee4697b11ba7c158b322fadcbeff336d38e /qpb | |
| parent | 6d24eb2b752354d91e518419f3f5ed421cf06f21 (diff) | |
qpb: Add support for protobuf.
Infrastructure that allows protocol buffers to be used in Quagga. The
changes below comprise of:
  - Build hooks
  - Protobuf definitions for common types.
  - Library routines for working with protobuf, including functions
    that help translate between common quagga types and their protobuf
    equivalents.
Changes:
  * qpb/{Makefile.am,README.txt,qpb.h,.gitignore}
    Add the qpb library, which provides shared code and definitions
    for using protocol buffers in quagga code.
  * qpb/qpb.proto
    Protobuf definitions that can be shared by all of quagga.
  * qpb/linear_allocator.h
    An allocator that allocates memory by walking down towards the end
    of a buffer. This is used to cheaply allocate/deallocate memory on
    the stack for protobuf operations.
  * qpb/qpb_allocator.[ch]
    Thin layer that allows a linear allocator to be used with the
    protobuf-c library.
  * common.am
    This is an automake fragment that is intended to be shared by
    Makefile.am files in the tree. It currently includes definitions
    related to protobuf.
  * configure.ac
    - Add logic to optionally build protobuf code.
      By default, protobuf support is enabled if the protobuf C
      compiler (protoc-c) is available, and the associated header
      files/library can be found.
      The user can choose to override this behavior via the new
      --disable-protobuf/--enable-protobuf flags.
    - Include the quagga protobuf library (qpb) in the build.
  * .gitignore
    Ignore source code generated by protobuf compiler.
  * Makefile.am
    Add 'qpb' to the list of subdirectories.
Signed-off-by: Avneesh Sachdev <avneesh@sproute.com>
Edited: Paul Jakma <paul.jakma@hpe.com>: Change the sense of the
        configure enable option to require explicit specifying, as
        an experimental feature.
Diffstat (limited to 'qpb')
| -rw-r--r-- | qpb/.gitignore | 15 | ||||
| -rw-r--r-- | qpb/Makefile.am | 30 | ||||
| -rw-r--r-- | qpb/README.txt | 1 | ||||
| -rw-r--r-- | qpb/linear_allocator.h | 207 | ||||
| -rw-r--r-- | qpb/qpb.c | 29 | ||||
| -rw-r--r-- | qpb/qpb.h | 372 | ||||
| -rw-r--r-- | qpb/qpb.proto | 121 | ||||
| -rw-r--r-- | qpb/qpb_allocator.c | 67 | ||||
| -rw-r--r-- | qpb/qpb_allocator.h | 113 | 
9 files changed, 955 insertions, 0 deletions
diff --git a/qpb/.gitignore b/qpb/.gitignore new file mode 100644 index 0000000000..b133c52a42 --- /dev/null +++ b/qpb/.gitignore @@ -0,0 +1,15 @@ +Makefile +Makefile.in +*.o +tags +TAGS +.deps +.nfs* +*.lo +*.la +*.a +*.libs +.arch-inventory +.arch-ids +*~ +*.loT diff --git a/qpb/Makefile.am b/qpb/Makefile.am new file mode 100644 index 0000000000..0fbda61f3c --- /dev/null +++ b/qpb/Makefile.am @@ -0,0 +1,30 @@ +include ../common.am + +AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib $(Q_PROTOBUF_C_CLIENT_INCLUDES) + +PROTOBUF_INCLUDES=-I$(top_srcdir) +PROTOBUF_PACKAGE = qpb + +lib_LTLIBRARIES = libquagga_pb.la +libquagga_pb_la_LDFLAGS = -version-info 0:0:0 + +if HAVE_PROTOBUF +protobuf_srcs =					\ +	qpb_allocator.c + +protobuf_srcs_nodist =				\ +	qpb.pb-c.c +endif + +libquagga_pb_la_SOURCES =			\ +	linear_allocator.h			\ +	qpb.h					\ +	qpb.c					\ +	qpb_allocator.h				\ +	$(protobuf_srcs) + +nodist_libquagga_pb_la_SOURCES = $(protobuf_srcs_nodist) + +CLEANFILES = $(Q_CLEANFILES) +BUILT_SOURCES = $(Q_PROTOBUF_SRCS) +EXTRA_DIST = qpb.proto diff --git a/qpb/README.txt b/qpb/README.txt new file mode 100644 index 0000000000..99ccd05511 --- /dev/null +++ b/qpb/README.txt @@ -0,0 +1 @@ +Protobuf definitions and code that is applicable to all of quagga. diff --git a/qpb/linear_allocator.h b/qpb/linear_allocator.h new file mode 100644 index 0000000000..e3ebbc64f3 --- /dev/null +++ b/qpb/linear_allocator.h @@ -0,0 +1,207 @@ +/* + * linear_allocator.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. + */ + +/* + * Header file for the linear allocator. + * + * An allocator that allocates memory by walking down towards the end + * of a buffer. No attempt is made to reuse blocks that are freed + * subsequently. The assumption is that the buffer is big enough to + * cover allocations for a given purpose. + */ +#include <assert.h> +#include <string.h> +#include <stdint.h> +#include <stddef.h> + +/* + * Alignment for block allocated by the allocator. Must be a power of 2. + */ +#define LINEAR_ALLOCATOR_ALIGNMENT        8 + +#define LINEAR_ALLOCATOR_ALIGN(value)					\ +  (((value) + LINEAR_ALLOCATOR_ALIGNMENT - 1) & ~(LINEAR_ALLOCATOR_ALIGNMENT - 1)); + +/* + * linear_allocator_align_ptr + */ +static inline char * +linear_allocator_align_ptr (char *ptr) +{ +  return (char *) LINEAR_ALLOCATOR_ALIGN ((intptr_t) ptr); +} + +typedef struct linear_allocator_t_ +{ +  char *buf; + +  /* +   * Current location in the buffer. +   */ +  char *cur; + +  /* +   * End of buffer. +   */ +  char *end; + +  /* +   * Version number of the allocator, this is bumped up when the allocator +   * is reset and helps identifies bad frees. +   */ +  uint32_t version; + +  /* +   * The number of blocks that are currently allocated. +   */ +  int num_allocated; +} linear_allocator_t; + +/* + * linear_allocator_block_t + * + * Header structure at the begining of each block. + */ +typedef struct linear_allocator_block_t_ +{ +  uint32_t flags; + +  /* +   * The version of the allocator when this block was allocated. +   */ +  uint32_t version; +  char data[0]; +} linear_allocator_block_t; + +#define LINEAR_ALLOCATOR_BLOCK_IN_USE 0x01 + +#define LINEAR_ALLOCATOR_HDR_SIZE (sizeof(linear_allocator_block_t)) + +/* + * linear_allocator_block_size + * + * The total amount of space a block will take in the buffer, + * including the size of the header. + */ +static inline size_t +linear_allocator_block_size (size_t user_size) +{ +  return LINEAR_ALLOCATOR_ALIGN (LINEAR_ALLOCATOR_HDR_SIZE + user_size); +} + +/* + * linear_allocator_ptr_to_block + */ +static inline linear_allocator_block_t * +linear_allocator_ptr_to_block (void *ptr) +{ +  void *block_ptr; +  block_ptr = ((char *) ptr) - offsetof (linear_allocator_block_t, data); +  return block_ptr; +} + +/* + * linear_allocator_init + */ +static inline void +linear_allocator_init (linear_allocator_t * allocator, char *buf, +		       size_t buf_len) +{ +  memset (allocator, 0, sizeof (*allocator)); + +  assert (linear_allocator_align_ptr (buf) == buf); +  allocator->buf = buf; +  allocator->cur = buf; +  allocator->end = buf + buf_len; +} + +/* + * linear_allocator_reset + * + * Prepare an allocator for reuse. + * + * *** NOTE ** This implicitly frees all the blocks in the allocator. + */ +static inline void +linear_allocator_reset (linear_allocator_t *allocator) +{ +  allocator->num_allocated = 0; +  allocator->version++; +  allocator->cur = allocator->buf; +} + +/* + * linear_allocator_alloc + */ +static inline void * +linear_allocator_alloc (linear_allocator_t *allocator, size_t user_size) +{ +  size_t block_size; +  linear_allocator_block_t *block; + +  block_size = linear_allocator_block_size (user_size); + +  if (allocator->cur + block_size > allocator->end) +    { +      return NULL; +    } + +  block = (linear_allocator_block_t *) allocator->cur; +  allocator->cur += block_size; + +  block->flags = LINEAR_ALLOCATOR_BLOCK_IN_USE; +  block->version = allocator->version; +  allocator->num_allocated++; +  return block->data; +} + +/* + * linear_allocator_free + */ +static inline void +linear_allocator_free (linear_allocator_t *allocator, void *ptr) +{ +  linear_allocator_block_t *block; + +  if (((char *) ptr) < allocator->buf || ((char *) ptr) >= allocator->end) +    { +      assert (0); +      return; +    } + +  block = linear_allocator_ptr_to_block (ptr); +  if (block->version != allocator->version) +    { +      assert (0); +      return; +    } + +  block->flags = block->flags & ~LINEAR_ALLOCATOR_BLOCK_IN_USE; + +  if (--allocator->num_allocated < 0) +    { +      assert (0); +    } +} diff --git a/qpb/qpb.c b/qpb/qpb.c new file mode 100644 index 0000000000..1b2b47fce5 --- /dev/null +++ b/qpb/qpb.c @@ -0,0 +1,29 @@ +/* + * qpb.c + * + * @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 file for the qpb library. + */ + diff --git a/qpb/qpb.h b/qpb/qpb.h new file mode 100644 index 0000000000..55c1deb19d --- /dev/null +++ b/qpb/qpb.h @@ -0,0 +1,372 @@ +/* + * 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 diff --git a/qpb/qpb.proto b/qpb/qpb.proto new file mode 100644 index 0000000000..7ee409df87 --- /dev/null +++ b/qpb/qpb.proto @@ -0,0 +1,121 @@ +/* + * qpb.proto + * + * @copyright Copyright (C) 2016 Sproute Networks, Inc. + * + * @author Avneesh Sachdev <avneesh@sproute.com> + * + * Permission is granted to use, copy, modify and/or distribute this + * software under either one of the licenses below. + * + * Note that if you use other files from the Quagga tree directly or + * indirectly, then the licenses in those files still apply. + * + * Please retain both licenses below when modifying this code in the + * Quagga tree. + */ + +/* + * License Option 1: GPL + * + * This program 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 of the License, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +/* + * License Option 2: ISC License + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Protobuf definitions pertaining to the Quagga Protobuf component. + */ +package qpb; + +enum AddressFamily { +  UNKNOWN_AF = 0; +  IPV4 = 1;		// IP version 4 +  IPV6 = 2;		// IP version 6 +}; + +enum SubAddressFamily { +  UNKNOWN_SAF = 0; +  UNICAST = 1; +  MULTICAST = 2; +}; + +// +// An IP version 4 address, such as 10.1.1.1. +// +message Ipv4Address { +  required fixed32 value = 1 ; +}; + +message Ipv6Address { + +  // 16 bytes. +  required bytes bytes = 1; +}; + +// +// An IP version 4 or IP version 6 address. +// +message L3Address { +  optional Ipv4Address v4 = 1; +  optional Ipv6Address v6 = 2; +}; + +// +// An IP prefix, such as 10.1/16. +// We use the message below to represent both IPv4 and IPv6 prefixes. +message L3Prefix { +  required uint32 length = 1; +  required bytes bytes = 2; +}; + +// +// Something that identifies an interface on a machine. It can either +// be a name (for instance, 'eth0') or a number currently. +// +message IfIdentifier { +  optional uint32 index = 1; +  optional string name = 2; +}; + +enum Protocol { +  UNKNOWN_PROTO = 0; +  LOCAL = 1; +  CONNECTED = 2; +  KERNEL = 3; +  STATIC = 4; +  RIP = 5; +  RIPNG = 6; +  OSPF = 7; +  ISIS = 8; +  BGP = 9; +  OTHER = 10; +}
\ No newline at end of file diff --git a/qpb/qpb_allocator.c b/qpb/qpb_allocator.c new file mode 100644 index 0000000000..4b4830a476 --- /dev/null +++ b/qpb/qpb_allocator.c @@ -0,0 +1,67 @@ +/* + * qpb_allocator.c + * + * @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. + */ + +#include "linear_allocator.h" + +#include "qpb_allocator.h" + +/* + * _qpb_alloc + */ +static void * +_qpb_alloc (void *allocator_data, size_t size) +{ +  return linear_allocator_alloc (allocator_data, size); +} + +/* + * _qpb_free + */ +static void +_qpb_free (void *allocator_data, void *ptr) +{ +  linear_allocator_free (allocator_data, ptr); +} + +static ProtobufCAllocator allocator_template = { +  _qpb_alloc, +  _qpb_free, +  NULL, +  8192, +  NULL +}; + +/* + * qpb_allocator_init_linear + * + * Initialize qpb_allocator_t with the given linear allocator. + */ +void +qpb_allocator_init_linear (qpb_allocator_t *allocator, +			   linear_allocator_t *linear_allocator) +{ +  *allocator = allocator_template; +  allocator->allocator_data = linear_allocator; +} diff --git a/qpb/qpb_allocator.h b/qpb/qpb_allocator.h new file mode 100644 index 0000000000..83ddf56cbc --- /dev/null +++ b/qpb/qpb_allocator.h @@ -0,0 +1,113 @@ +/* + * qpb_allocator.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. + */ + +/* + * Header file for quagga protobuf memory management code. + */ + +#ifndef _QPB_ALLOCATOR_H_ +#define _QPB_ALLOCATOR_H_ + +#include <google/protobuf-c/protobuf-c.h> + +struct linear_allocator_t_; + +/* + * Alias for ProtobufCAllocator that is easier on the fingers. + */ +typedef ProtobufCAllocator qpb_allocator_t; + +/* + * qpb_alloc + */ +static inline void * +qpb_alloc (qpb_allocator_t *allocator, size_t size) +{ +  return allocator->alloc (allocator->allocator_data, size); +} + +/* + * qpb_alloc_ptr_array + * + * Allocate space for the specified number of pointers. + */ +static inline void * +qpb_alloc_ptr_array (qpb_allocator_t *allocator, size_t num_ptrs) +{ +  return qpb_alloc (allocator, num_ptrs * sizeof (void *)); +} + +/* + * qpb_free + */ +static inline void +qpb_free (qpb_allocator_t *allocator, void *ptr) +{ +  allocator->free (allocator->allocator_data, ptr); +} + +/* + * QPB_ALLOC + * + * Convenience macro to reduce the probability of allocating memory of + * incorrect size. It returns enough memory to store the given type, + * and evaluates to an appropriately typed pointer. + */ +#define QPB_ALLOC(allocator, type)		\ +  (type *) qpb_alloc(allocator, sizeof(type)) + + +/* + * Externs. + */ +extern void qpb_allocator_init_linear (qpb_allocator_t *, +				       struct linear_allocator_t_ *); + +/* + * The following macros are for the common case where a qpb allocator + * is being used alongside a linear allocator that allocates memory + * off of the stack. + */ +#define QPB_DECLARE_STACK_ALLOCATOR(allocator, size)	\ +    qpb_allocator_t allocator;				\ +    linear_allocator_t lin_ ## allocator;		\ +    char lin_ ## allocator ## _buf[size] + +#define QPB_INIT_STACK_ALLOCATOR(allocator)				\ +  do									\ +    {									\ +      linear_allocator_init(&(lin_ ## allocator),			\ +			    lin_ ## allocator ## _buf,			\ +			    sizeof(lin_ ## allocator ## _buf));		\ +      qpb_allocator_init_linear(&allocator, &(lin_ ## allocator));	\ +    } while (0) + +#define QPB_RESET_STACK_ALLOCATOR(allocator)		\ +  do							\ +    {							\ +      linear_allocator_reset (&(lin_ ## allocator));	\ +    } while (0) + +#endif /* _QPB_ALLOCATOR_H_ */  | 
