summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route_refresh.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route_refresh.c')
-rw-r--r--bgpd/bgp_route_refresh.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/bgpd/bgp_route_refresh.c b/bgpd/bgp_route_refresh.c
new file mode 100644
index 00000000..d50f977b
--- /dev/null
+++ b/bgpd/bgp_route_refresh.c
@@ -0,0 +1,186 @@
+/* BGP ROUTE-REFRESH and ORF handling
+ * Copyright (C) Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra 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.
+ *
+ * GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include "lib/zassert.h"
+#include "lib/memory.h"
+#include "lib/vector.h"
+
+#include "bgpd/bgp_route_refresh.h"
+
+/*==============================================================================
+ * A bgp_route_refresh structure encapsulates the contents of a BGP
+ * ROUTE-REFRESH message, with or without ORF part.
+ *
+ * For incoming messages, expect a bgp_route_refresh structure to be the
+ * contents of a single ROUTE-REFRESH message.
+ *
+ * For outgoing messages, a bgp_route_refresh structure may contain a large
+ * number of ORF entries, and those are carved up into as many ROUTE-REFRESH
+ * messages as required.
+ */
+
+/*==============================================================================
+ * Create/Destroy bgp_route_refresh
+ */
+
+/*------------------------------------------------------------------------------
+ * Allocate and initialise new bgp_route_refresh
+ *
+ * Constructs complete simple ROUTE-REFRESH -- ORF stuff can then be added.
+ *
+ * Can specify an expected number of ORF entries (need not be actual number).
+ */
+extern bgp_route_refresh
+bgp_route_refresh_new(iAFI_t afi, iSAFI_t safi, unsigned count)
+{
+ bgp_route_refresh rr ;
+
+ rr = XCALLOC(MTYPE_BGP_ROUTE_REFRESH, sizeof(struct bgp_route_refresh)) ;
+
+ rr->afi = afi ;
+ rr->safi = safi ;
+
+ vector_init_new(&rr->entries, count) ;
+
+ /* rest of bgp_route_refresh zeroised -- not relevant when vector empty */
+
+ return rr ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Free bgp_route_refresh
+ */
+extern void
+bgp_route_refresh_free(bgp_route_refresh rr)
+{
+ bgp_orf_entry entry ;
+ while((entry = vector_ream_keep(&rr->entries)) != NULL)
+ XFREE(MTYPE_BGP_ORF_ENTRY, entry) ;
+
+ XFREE(MTYPE_BGP_ROUTE_REFRESH, rr) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Allocate new bgp_orf_entry -- for known or unknown type.
+ *
+ * Is for known type if unknown_size == 0 !
+ *
+ * Sets orf_type and unknown elements of the entry.
+ *
+ * NB: it is a FATAL error to set an unknown ORF type unless is explicitly
+ * unknown ! (In this context "pre-RFC" types are unknown.)
+ *
+ * Zeroises rest of structure -- in particular remove_all == false !
+ *
+ * Pushes entry onto the bgp_route_refresh list.
+ */
+static bgp_orf_entry
+bgp_orf_entry_new(bgp_route_refresh rr, uint8_t orf_type, size_t unknown_size)
+{
+ bgp_orf_entry orfe ;
+ size_t e_size ;
+
+ if (unknown_size == 0)
+ {
+ if (orf_type != BGP_ORF_T_PREFIX)
+ zabort("unknown ORF type") ;
+ e_size = 0 ;
+ }
+ else
+ {
+ if (unknown_size < bgp_orf_unknown_min_l)
+ e_size = 0 ;
+ else
+ e_size = unknown_size - bgp_orf_unknown_min_l ;
+ } ;
+
+ orfe = XCALLOC(MTYPE_BGP_ORF_ENTRY, sizeof(struct bgp_orf_entry) + e_size) ;
+
+ orfe->orf_type = orf_type ;
+ orfe->unknown = (unknown_size != 0) ;
+
+ vector_push_item(&rr->entries, orfe) ;
+
+ return orfe ;
+} ;
+
+/*==============================================================================
+ * Creating new ORF entries.
+ */
+
+/*------------------------------------------------------------------------------
+ * Add an entry for known type of ORF.
+ *
+ * Sets the common ORF entry part.
+ *
+ * Returns address of the ORF type specific structure, to be filled in.
+ *
+ * The orf_type presented must be a known BGP_ORF_T_xxx value, EXCLUDING any
+ * "pre-RFC" types. (Any use of pre-RFC values is looked after at the message
+ * level).
+ *
+ * NB: it is a FATAL error to set an unknown ORF type
+ */
+extern void*
+bgp_orf_add(bgp_route_refresh rr, uint8_t orf_type, flag_t remove, flag_t deny)
+{
+ bgp_orf_entry orfe = bgp_orf_entry_new(rr, orf_type, 0) ;
+
+ orfe->remove = (remove != 0) ;
+ orfe->deny = (deny != 0) ;
+
+ return &orfe->body ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Add a remove_all entry.
+ *
+ * The orf_type presented must be a known BGP_ORF_T_xxx value, EXCLUDING any
+ * "pre-RFC" types. (Any use of pre-RFC values is looked after at the message
+ * level).
+ *
+ * NB: it is a FATAL error to set an unknown ORF type
+ */
+extern void
+bgp_orf_add_remove_all(bgp_route_refresh rr, uint8_t orf_type)
+{
+ bgp_orf_entry orfe = bgp_orf_entry_new(rr, orf_type, 0) ;
+
+ orfe->remove_all = 1 ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Add an entry for an unknown type of ORF -- copy the entry verbatim.
+ *
+ * Provided so that can capture entire contents of incoming message.
+ */
+extern void
+bgp_orf_add_unknown(bgp_route_refresh rr, uint8_t orf_type, bgp_size_t length,
+ const void* entries)
+{
+ bgp_orf_entry orfe = bgp_orf_entry_new(rr, orf_type,
+ (length > 0) ? length : 1) ;
+
+ if (length != 0)
+ memcpy(&orfe->body.orf_unknown.data, entries, length) ;
+} ;