Skip to content

Commit

Permalink
lib: Add Aggregate Table and Aggregate_node
Browse files Browse the repository at this point in the history
Add a abstraction for `struct route_node` and `struct route_table`
such that we can have an aggregate route_node and table.  This
is because only bgp/rfapi and ripng use the aggregate data pointer
in `struct route_node`.  For full route tables other routing
protocols and tables are paying a 8 byte overhead per node.
A full bgp table ends up being ~1.2 million routes in bgp
and zebra.  This is not an insiginificant amount of data.

So create the data structures for this replacement, but
do not replace the aggregate pointer yet.  This is because
later commits will convert rfapi and ripng over to this
new data, and finally we'll move the aggregate pointer.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
  • Loading branch information
donaldsharp committed Aug 30, 2018
1 parent 66a9aa8 commit 3a77d6d
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 0 deletions.
59 changes: 59 additions & 0 deletions lib/agg_table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Aggregate Route
* Copyright (C) 2018 Cumulus Networks, Inc.
* Donald Sharp
*
* FRR 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.
*
* FRR 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; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "zebra.h"

#include "agg_table.h"


static struct route_node *agg_node_create(route_table_delegate_t *delegate,
struct route_table *table)
{
struct agg_node *node;

node = XCALLOC(MTYPE_TMP, sizeof(struct agg_node));

return agg_node_to_rnode(node);
}

static void agg_node_destroy(route_table_delegate_t *delegate,
struct route_table *table, struct route_node *node)

{
struct agg_node *anode = agg_node_from_rnode(node);

XFREE(MTYPE_TMP, anode);
}

route_table_delegate_t agg_table_delegate = {
.create_node = agg_node_create,
.destroy_node = agg_node_destroy,
};

extern struct agg_table *agg_table_init(void)
{
struct agg_table *at;

at = XCALLOC(MTYPE_TMP, sizeof(struct agg_table));

at->route_table = route_table_init_with_delegate(&agg_table_delegate);
at->route_table->info = at;

return at;
}
151 changes: 151 additions & 0 deletions lib/agg_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* agg_table - Aggregate Table Header
* Copyright (C) 2018 Cumulus Networks, Inc.
* Donald Sharp
*
* FRR 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.
*
* FRR 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; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __AGG_TABLE_H__
#define __AGG_TABLE_H__

#include "prefix.h"
#include "table.h"

struct agg_table {
struct route_table *route_table;

void *info;
};

struct agg_node {
/*
* Caution these must be the very first fields
* @see agg_node_to_rnode
* @see agg_node_from_rnode
*/
ROUTE_NODE_FIELDS

};

static inline struct route_node *agg_node_to_rnode(struct agg_node *node)
{
return (struct route_node *)node;
}

static inline struct agg_node *agg_node_from_rnode(struct route_node *node)
{
return (struct agg_node *)node;
}

static inline struct agg_node *agg_lock_node(struct agg_node *node)
{
return (struct agg_node *)route_lock_node(agg_node_to_rnode(node));
}

static inline void agg_unlock_node(struct agg_node *node)
{
return route_unlock_node(agg_node_to_rnode(node));
}

static inline void agg_set_table_info(struct agg_table *atable, void *data)
{
atable->info = data;
}

static inline void *agg_get_table_info(struct agg_table *atable)
{
return atable->info;
}

static inline struct agg_node *agg_route_top(struct agg_table *table)
{
return agg_node_from_rnode(route_top(table->route_table));
}

static inline struct agg_node *agg_route_next(struct agg_node *node)
{
return agg_node_from_rnode(route_next(agg_node_to_rnode(node)));
}

static inline struct agg_node *agg_node_get(struct agg_table *table,
struct prefix *p)
{
return agg_node_from_rnode(route_node_get(table->route_table, p));
}

static inline struct agg_node *
agg_node_lookup(const struct agg_table *const table, struct prefix *p)
{
return agg_node_from_rnode(route_node_lookup(table->route_table, p));
}

static inline struct agg_node *agg_route_next_until(struct agg_node *node,
struct agg_node *limit)
{
struct route_node *rnode;

rnode = route_next_until(agg_node_to_rnode(node),
agg_node_to_rnode(limit));

return agg_node_from_rnode(rnode);
}

static inline struct agg_node *agg_node_match(struct agg_table *table,
struct prefix *p)
{
return agg_node_from_rnode(route_node_match(table->route_table, p));
}

static inline struct agg_node *agg_node_parent(struct agg_node *node)
{
struct route_node *rn = agg_node_to_rnode(node);

return agg_node_from_rnode(rn->parent);
}

static inline struct agg_node *agg_node_left(struct agg_node *node)
{
struct route_node *rn = agg_node_to_rnode(node);

return agg_node_from_rnode(rn->l_left);
}

static inline struct agg_node *agg_node_right(struct agg_node *node)
{
struct route_node *rn = agg_node_to_rnode(node);

return agg_node_from_rnode(rn->l_right);
}

extern struct agg_table *agg_table_init(void);

static inline void agg_table_finish(struct agg_table *atable)
{
route_table_finish(atable->route_table);
atable->route_table = NULL;

XFREE(MTYPE_TMP, atable);
}

static inline struct agg_node *agg_route_table_top(struct agg_node *node)
{
return (struct agg_node *)route_top(node->table);
}

static inline struct agg_table *agg_get_table(struct agg_node *node)
{
return (struct agg_table *)node->table->info;
}
#endif
2 changes: 2 additions & 0 deletions lib/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ lib_libfrr_la_LDFLAGS = -version-info 0:0:0
lib_libfrr_la_LIBADD = @LIBCAP@

lib_libfrr_la_SOURCES = \
lib/agg_table.c \
lib/bfd.c \
lib/buffer.c \
lib/checksum.c \
Expand Down Expand Up @@ -89,6 +90,7 @@ lib/nexthop_group_clippy.c: $(CLIPPY_DEPS)
lib/nexthop_group.lo: lib/nexthop_group_clippy.c

pkginclude_HEADERS += \
lib/agg_table.h \
lib/bfd.h \
lib/bitfield.h \
lib/buffer.h \
Expand Down

0 comments on commit 3a77d6d

Please sign in to comment.