From 0964ad9cecf3e60c843c3e55a26eecb522a98a29 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 24 Apr 2014 19:29:07 +0200 Subject: lib: add second-level route_table for srcdest IPv6 srcdest routes need to be keyed by both destination and source prefix. Since the lookup order is destination first, the simplest thing to do here is to add a second route_table to destination entries, which then contain source entries. Sadly, the result is somewhat confusing since a route_node might now be either a source node or a destination node. There are helper functions to get source and destination prefix from a given route node (which can be either a destination or a source route). The following bits have been added by Christian Franke : - make srcdest routing table reusable by moving it into lib - make the srcdest routing table structure more opaque - implement a srcdest routing table iterator - fix a refcounting issue in src_node_lookup - match route_node_lookup behavior with srcdest_rnode_lookup - add accessor for the route_node table and table_info - add string formatter srcdest_rnode2str Signed-off-by: David Lamparter Signed-off-by: Christian Franke [v3: adapted for cmaster-next as of 2016-12-05] --- lib/srcdest_table.h | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/srcdest_table.h (limited to 'lib/srcdest_table.h') diff --git a/lib/srcdest_table.h b/lib/srcdest_table.h new file mode 100644 index 0000000000..59111b5d17 --- /dev/null +++ b/lib/srcdest_table.h @@ -0,0 +1,101 @@ +/* + * SRC-DEST Routing Table + * + * Copyright (C) 2017 by David Lamparter & Christian Franke, + * Open Source Routing / NetDEF Inc. + * + * This file is part of FreeRangeRouting (FRR) + * + * 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _ZEBRA_SRC_DEST_TABLE_H +#define _ZEBRA_SRC_DEST_TABLE_H + +/* old/IPv4/non-srcdest: + * table -> route_node .info -> [obj] + * + * new/IPv6/srcdest: + * table -...-> srcdest_rnode [prefix = dest] .info -> [obj] + * .src_table -> + * srcdest table -...-> route_node [prefix = src] .info -> [obj] + * + * non-srcdest routes (src = ::/0) are treated just like before, their + * information being directly there in the info pointer. + * + * srcdest routes are found by looking up destination first, then looking + * up the source in the "src_table". src_table contains normal route_nodes, + * whose prefix is the _source_ prefix. + * + * NB: info can be NULL on the destination rnode, if there are only srcdest + * routes for a particular destination prefix. + */ + +#include "prefix.h" +#include "table.h" + +#define SRCDEST2STR_BUFFER (2*PREFIX2STR_BUFFER + sizeof(" from ")) + +/* extended route node for IPv6 srcdest routing */ +struct srcdest_rnode; + +extern route_table_delegate_t _srcdest_dstnode_delegate; +extern route_table_delegate_t _srcdest_srcnode_delegate; + +extern struct route_table *srcdest_table_init(void); +extern struct route_node *srcdest_rnode_get(struct route_table *table, + union prefix46ptr dst_pu, + struct prefix_ipv6 *src_p); +extern struct route_node *srcdest_rnode_lookup(struct route_table *table, + union prefix46ptr dst_pu, + struct prefix_ipv6 *src_p); +extern void srcdest_rnode_prefixes (struct route_node *rn, struct prefix **p, + struct prefix **src_p); +extern const char *srcdest_rnode2str(struct route_node *rn, char *str, int size); +extern struct route_node *srcdest_route_next(struct route_node *rn); + +static inline int +rnode_is_dstnode (struct route_node *rn) +{ + return rn->table->delegate == &_srcdest_dstnode_delegate; +} + +static inline int +rnode_is_srcnode (struct route_node *rn) +{ + return rn->table->delegate == &_srcdest_srcnode_delegate; +} + +static inline struct route_table * +srcdest_rnode_table (struct route_node *rn) +{ + if (rnode_is_srcnode (rn)) + { + struct route_node *dst_rn = rn->table->info; + return dst_rn->table; + } + else + { + return rn->table; + } +} +static inline void * +srcdest_rnode_table_info (struct route_node *rn) +{ + return srcdest_rnode_table(rn)->info; +} + +#endif /* _ZEBRA_SRC_DEST_TABLE_H */ -- cgit v1.2.3