bgpd: efficient NLRI packing for AFs != ipv4-unicast

ISSUE:

  Currently, for non-ipv4-unicast address families where prefixes are
  encoded in MP_REACH/MP_UNREACH attributes, BGP ends up sending one
  prefix per UPDATE message. This is quite inefficient. The patch
  addresses the issue.

PATCH:

  We introduce a scratch buffer in the peer structure that stores the
  MP_REACH/MP_UNREACH attributes for non-ipv4-unicast families. This
  enables us to encode multiple prefixes. In the end, the two buffers
  are merged to create the UPDATE packet.

Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
[DL: removed no longer existing bgp_packet_withdraw prototype]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/lib/stream.h b/lib/stream.h
index f10aa6d..f0c742c 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -122,6 +122,9 @@
   /* number of bytes still to be read */
 #define STREAM_READABLE(S) ((S)->endp - (S)->getp)
 
+#define STREAM_CONCAT_REMAIN(S1, S2, size) \
+  ((size) - (S1)->endp - (S2)->endp)
+
 /* deprecated macros - do not use in new code */
 #define STREAM_PNT(S)   stream_pnt((S))
 #define STREAM_DATA(S)  ((S)->data)
@@ -145,6 +148,14 @@
 extern size_t stream_get_size (struct stream *);
 extern u_char *stream_get_data (struct stream *);
 
+/**
+ * Create a new stream structure; copy offset bytes from s1 to the new
+ * stream; copy s2 data to the new stream; copy rest of s1 data to the
+ * new stream.
+ */
+extern struct stream *stream_dupcat(struct stream *s1, struct stream *s2,
+				    size_t offset);
+
 extern void stream_set_getp (struct stream *, size_t);
 extern void stream_set_endp (struct stream *, size_t);
 extern void stream_forward_getp (struct stream *, size_t);