2 * Copyright (C) 1998, 2001 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "sockunion.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgp_addpath.h"
35 void bgp_table_lock(struct bgp_table
*rt
)
40 void bgp_table_unlock(struct bgp_table
*rt
)
49 route_table_finish(rt
->route_table
);
50 rt
->route_table
= NULL
;
52 XFREE(MTYPE_BGP_TABLE
, rt
);
55 void bgp_table_finish(struct bgp_table
**rt
)
58 bgp_table_unlock(*rt
);
66 static struct route_node
*bgp_node_create(route_table_delegate_t
*delegate
,
67 struct route_table
*table
)
69 struct bgp_node
*node
;
70 node
= XCALLOC(MTYPE_BGP_NODE
, sizeof(struct bgp_node
));
72 RB_INIT(bgp_adj_out_rb
, &node
->adj_out
);
73 return bgp_dest_to_rnode(node
);
79 static void bgp_node_destroy(route_table_delegate_t
*delegate
,
80 struct route_table
*table
, struct route_node
*node
)
82 struct bgp_node
*bgp_node
;
84 bgp_node
= bgp_dest_from_rnode(node
);
88 bgp_addpath_free_node_data(&rt
->bgp
->tx_addpath
,
89 &bgp_node
->tx_addpath
,
93 XFREE(MTYPE_BGP_NODE
, bgp_node
);
97 * Function vector to customize the behavior of the route table
98 * library for BGP route tables.
100 route_table_delegate_t bgp_table_delegate
= {.create_node
= bgp_node_create
,
101 .destroy_node
= bgp_node_destroy
};
106 struct bgp_table
*bgp_table_init(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
108 struct bgp_table
*rt
;
110 rt
= XCALLOC(MTYPE_BGP_TABLE
, sizeof(struct bgp_table
));
112 rt
->route_table
= route_table_init_with_delegate(&bgp_table_delegate
);
115 * Set up back pointer to bgp_table.
117 route_table_set_info(rt
->route_table
, rt
);
120 * pointer to bgp instance allows working back from bgp_path_info to bgp
131 /* Delete the route node from the selection deferral route list */
132 void bgp_delete_listnode(struct bgp_node
*node
)
134 struct route_node
*rn
= NULL
;
135 struct bgp_table
*table
= NULL
;
136 struct bgp
*bgp
= NULL
;
140 /* If the route to be deleted is selection pending, update the
141 * route node in gr_info
143 if (CHECK_FLAG(node
->flags
, BGP_NODE_SELECT_DEFER
)) {
144 table
= bgp_dest_table(node
);
153 rn
= bgp_dest_to_rnode(node
);
155 if (bgp
&& rn
&& rn
->lock
== 1) {
156 /* Delete the route from the selection pending list */
157 bgp
->gr_info
[afi
][safi
].gr_deferred
--;
158 UNSET_FLAG(node
->flags
, BGP_NODE_SELECT_DEFER
);
163 struct bgp_node
*bgp_table_subtree_lookup(const struct bgp_table
*table
,
164 const struct prefix
*p
)
166 struct bgp_node
*node
= bgp_dest_from_rnode(table
->route_table
->top
);
167 struct bgp_node
*matched
= NULL
;
174 const struct prefix
*node_p
= bgp_dest_get_prefix(node
);
176 if (node_p
->prefixlen
>= p
->prefixlen
) {
177 if (!prefix_match(p
, node_p
))
184 if (!prefix_match(node_p
, p
))
187 if (node_p
->prefixlen
== p
->prefixlen
) {
192 node
= bgp_dest_from_rnode(node
->link
[prefix_bit(
193 &p
->u
.prefix
, node_p
->prefixlen
)]);
199 bgp_dest_lock_node(matched
);
203 printfrr_ext_autoreg_p("BD", printfrr_bd
)
204 static ssize_t
printfrr_bd(char *buf
, size_t bsz
, const char *fmt
,
205 int prec
, const void *ptr
)
207 const struct bgp_dest
*dest
= ptr
;
208 const struct prefix
*p
;
211 p
= bgp_dest_get_prefix(dest
);
212 prefix2str(p
, buf
, bsz
);
214 strlcpy(buf
, "NULL", bsz
);