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"
34 #include "bgp_trace.h"
36 void bgp_table_lock(struct bgp_table
*rt
)
41 void bgp_table_unlock(struct bgp_table
*rt
)
50 route_table_finish(rt
->route_table
);
51 rt
->route_table
= NULL
;
53 XFREE(MTYPE_BGP_TABLE
, rt
);
56 void bgp_table_finish(struct bgp_table
**rt
)
59 bgp_table_unlock(*rt
);
65 * bgp_dest_unlock_node
67 void bgp_dest_unlock_node(struct bgp_dest
*dest
)
69 frrtrace(1, frr_bgp
, bgp_dest_unlock
, dest
);
70 bgp_delete_listnode(dest
);
71 route_unlock_node(bgp_dest_to_rnode(dest
));
77 struct bgp_dest
*bgp_dest_lock_node(struct bgp_dest
*dest
)
79 frrtrace(1, frr_bgp
, bgp_dest_lock
, dest
);
80 struct route_node
*rn
= route_lock_node(bgp_dest_to_rnode(dest
));
82 return bgp_dest_from_rnode(rn
);
86 * bgp_dest_get_prefix_str
88 const char *bgp_dest_get_prefix_str(struct bgp_dest
*dest
)
90 const struct prefix
*p
= NULL
;
91 static char str
[PREFIX_STRLEN
] = {0};
93 p
= bgp_dest_get_prefix(dest
);
95 return prefix2str(p
, str
, sizeof(str
));
103 static struct route_node
*bgp_node_create(route_table_delegate_t
*delegate
,
104 struct route_table
*table
)
106 struct bgp_node
*node
;
107 node
= XCALLOC(MTYPE_BGP_NODE
, sizeof(struct bgp_node
));
109 RB_INIT(bgp_adj_out_rb
, &node
->adj_out
);
110 return bgp_dest_to_rnode(node
);
116 static void bgp_node_destroy(route_table_delegate_t
*delegate
,
117 struct route_table
*table
, struct route_node
*node
)
119 struct bgp_node
*bgp_node
;
120 struct bgp_table
*rt
;
121 bgp_node
= bgp_dest_from_rnode(node
);
125 bgp_addpath_free_node_data(&rt
->bgp
->tx_addpath
,
126 &bgp_node
->tx_addpath
,
130 XFREE(MTYPE_BGP_NODE
, bgp_node
);
134 * Function vector to customize the behavior of the route table
135 * library for BGP route tables.
137 route_table_delegate_t bgp_table_delegate
= {.create_node
= bgp_node_create
,
138 .destroy_node
= bgp_node_destroy
};
143 struct bgp_table
*bgp_table_init(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
145 struct bgp_table
*rt
;
147 rt
= XCALLOC(MTYPE_BGP_TABLE
, sizeof(struct bgp_table
));
149 rt
->route_table
= route_table_init_with_delegate(&bgp_table_delegate
);
152 * Set up back pointer to bgp_table.
154 route_table_set_info(rt
->route_table
, rt
);
157 * pointer to bgp instance allows working back from bgp_path_info to bgp
168 /* Delete the route node from the selection deferral route list */
169 void bgp_delete_listnode(struct bgp_node
*node
)
171 struct route_node
*rn
= NULL
;
172 struct bgp_table
*table
= NULL
;
173 struct bgp
*bgp
= NULL
;
177 /* If the route to be deleted is selection pending, update the
178 * route node in gr_info
180 if (CHECK_FLAG(node
->flags
, BGP_NODE_SELECT_DEFER
)) {
181 table
= bgp_dest_table(node
);
190 rn
= bgp_dest_to_rnode(node
);
192 if (bgp
&& rn
&& rn
->lock
== 1) {
193 /* Delete the route from the selection pending list */
194 bgp
->gr_info
[afi
][safi
].gr_deferred
--;
195 UNSET_FLAG(node
->flags
, BGP_NODE_SELECT_DEFER
);
200 struct bgp_node
*bgp_table_subtree_lookup(const struct bgp_table
*table
,
201 const struct prefix
*p
)
203 struct bgp_node
*node
= bgp_dest_from_rnode(table
->route_table
->top
);
204 struct bgp_node
*matched
= NULL
;
211 const struct prefix
*node_p
= bgp_dest_get_prefix(node
);
213 if (node_p
->prefixlen
>= p
->prefixlen
) {
214 if (!prefix_match(p
, node_p
))
221 if (!prefix_match(node_p
, p
))
224 if (node_p
->prefixlen
== p
->prefixlen
) {
229 node
= bgp_dest_from_rnode(node
->link
[prefix_bit(
230 &p
->u
.prefix
, node_p
->prefixlen
)]);
236 bgp_dest_lock_node(matched
);
240 printfrr_ext_autoreg_p("BD", printfrr_bd
);
241 static ssize_t
printfrr_bd(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
244 const struct bgp_dest
*dest
= ptr
;
245 const struct prefix
*p
= bgp_dest_get_prefix(dest
);
246 char cbuf
[PREFIX_STRLEN
];
249 return bputs(buf
, "(null)");
251 /* need to get the real length even if buffer too small */
252 prefix2str(p
, cbuf
, sizeof(cbuf
));
253 return bputs(buf
, cbuf
);