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.
diff --git a/configure.ac b/configure.ac
index c35a111..d36b580 100755
--- a/configure.ac
+++ b/configure.ac
@@ -301,6 +301,8 @@
   AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support]))
 AC_ARG_ENABLE(werror,
   AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
+AC_ARG_ENABLE([protobuf],
+  AS_HELP_STRING([--enable-protobuf], [Enable experimental protobuf support]))
 
 if test x"${enable_gcc_rdynamic}" != x"no" ; then
   if test x"${enable_gcc_rdynamic}" = x"yes" -o x"$COMPILER" = x"GCC"; then
@@ -320,6 +322,48 @@
    AC_DEFINE(HAVE_FPM,,Forwarding Plane Manager support)
 fi
 
+#
+# Logic for protobuf support.
+#
+if test "$enable_protobuf" = "yes"; then
+   have_protobuf=yes
+
+   # Check for protoc-c
+   AC_CHECK_PROG([PROTOC_C], [protoc-c], [protoc-c], [/bin/false])
+   if test "x$PROTOC_C" = "x/bin/false"; then
+      have_protobuf=no
+   else
+      found_protobuf_c=no
+      PKG_CHECK_MODULES([PROTOBUF_C], libprotobuf-c >= 0.14,
+                     [found_protobuf_c=yes],
+                     [AC_MSG_RESULT([pkg-config did not find libprotobuf-c])])
+
+      if test "x$found_protobuf_c" = "xyes"; then
+         LDFLAGS="$LDFLAGS $PROTOBUF_C_LIBS"
+         CFLAGS="$CFLAGS $PROTOBUF_C_CFLAGS"
+      else
+        AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [],
+                        [have_protobuf=no; AC_MSG_RESULT([Couldn't find google/protobuf-c.h])])
+      fi
+   fi
+fi
+
+# Fail if the user explicity enabled protobuf support and we couldn't
+# find the compiler or libraries.
+if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then
+   AC_MSG_ERROR([Protobuf enabled explicitly but can't find libraries/tools])
+fi
+
+if test "x$have_protobuf" = "xyes"; then
+   AC_DEFINE(HAVE_PROTOBUF,, protobuf)
+fi
+
+AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"])
+
+#
+# End of logic for protobuf support.
+#
+
 if test "${enable_tcp_zebra}" = "yes"; then
   AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
 fi
@@ -1530,7 +1574,7 @@
 )
 AC_MSG_RESULT($ac_cv_htonl_works)
 
-AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile 
+AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile 
 	  ripngd/Makefile bgpd/Makefile ospfd/Makefile watchquagga/Makefile
 	  ospf6d/Makefile isisd/Makefile vtysh/Makefile
 	  doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
@@ -1570,6 +1614,7 @@
 group for vty sockets	: ${enable_vty_group}
 config file mask        : ${enable_configfile_mask}
 log file mask           : ${enable_logfile_mask}
+zebra protobuf enabled  : ${have_protobuf:-no}
 
 The above user and group must have read/write access to the state file
 directory and to the config files in the config file directory."