diff options
author | Pradosh Mohapatra <pmohapat@cumulusnetworks.com> | 2014-01-15 06:57:57 +0000 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2014-06-03 15:08:32 +0200 |
commit | 8c71e481dae11b7ae3f1ef561a989624b2ae84b6 (patch) | |
tree | 4c13b76e1b9aedc45ad9b086be972ba4999ada03 /lib | |
parent | 2c13299a05e5544a5e79c2a970256a21f488a3fa (diff) | |
download | quagga-8c71e481dae11b7ae3f1ef561a989624b2ae84b6.tar.bz2 quagga-8c71e481dae11b7ae3f1ef561a989624b2ae84b6.tar.xz |
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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/stream.c | 19 | ||||
-rw-r--r-- | lib/stream.h | 11 |
2 files changed, 30 insertions, 0 deletions
diff --git a/lib/stream.c b/lib/stream.c index ccd4623f..9a6fcbcf 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -154,6 +154,25 @@ stream_dup (struct stream *s) return (stream_copy (new, s)); } +struct stream * +stream_dupcat (struct stream *s1, struct stream *s2, size_t offset) +{ + struct stream *new; + + STREAM_VERIFY_SANE (s1); + STREAM_VERIFY_SANE (s2); + + if ( (new = stream_new (s1->endp + s2->endp)) == NULL) + return NULL; + + memcpy (new->data, s1->data, offset); + memcpy (new->data + offset, s2->data, s2->endp); + memcpy (new->data + offset + s2->endp, s1->data + offset, + (s1->endp - offset)); + new->endp = s1->endp + s2->endp; + return new; +} + size_t stream_resize (struct stream *s, size_t newsize) { diff --git a/lib/stream.h b/lib/stream.h index f10aa6d4..f0c742c0 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -122,6 +122,9 @@ struct stream_fifo /* 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_endp (struct stream *); 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); |