]>
git.proxmox.com Git - mirror_frr.git/blob - babeld/xroute.c
1 // SPDX-License-Identifier: MIT
3 Copyright (c) 2007, 2008 by Juliusz Chroboczek
4 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
13 #include "neighbour.h"
18 #include "babel_interface.h"
20 static int xroute_add_new_route(unsigned char prefix
[16], unsigned char plen
,
21 unsigned short metric
, unsigned int ifindex
,
22 int proto
, int send_updates
);
24 static struct xroute
*xroutes
;
25 static int numxroutes
= 0, maxxroutes
= 0;
27 /* Add redistributed route to Babel table. */
29 babel_route_add (struct zapi_route
*api
)
31 unsigned char uchar_prefix
[16];
33 switch (api
->prefix
.family
) {
35 inaddr_to_uchar(uchar_prefix
, &api
->prefix
.u
.prefix4
);
36 debugf(BABEL_DEBUG_ROUTE
, "Adding new ipv4 route coming from Zebra.");
37 xroute_add_new_route(uchar_prefix
, api
->prefix
.prefixlen
+ 96,
38 api
->metric
, api
->nexthops
[0].ifindex
, 0, 1);
41 in6addr_to_uchar(uchar_prefix
, &api
->prefix
.u
.prefix6
);
42 debugf(BABEL_DEBUG_ROUTE
, "Adding new ipv6 route coming from Zebra.");
43 xroute_add_new_route(uchar_prefix
, api
->prefix
.prefixlen
,
44 api
->metric
, api
->nexthops
[0].ifindex
, 0, 1);
51 /* Remove redistributed route from Babel table. */
53 babel_route_delete (struct zapi_route
*api
)
55 unsigned char uchar_prefix
[16];
56 struct xroute
*xroute
= NULL
;
58 switch (api
->prefix
.family
) {
60 inaddr_to_uchar(uchar_prefix
, &api
->prefix
.u
.prefix4
);
61 xroute
= find_xroute(uchar_prefix
, api
->prefix
.prefixlen
+ 96);
63 debugf(BABEL_DEBUG_ROUTE
, "Removing ipv4 route (from zebra).");
68 in6addr_to_uchar(uchar_prefix
, &api
->prefix
.u
.prefix6
);
69 xroute
= find_xroute(uchar_prefix
, api
->prefix
.prefixlen
);
71 debugf(BABEL_DEBUG_ROUTE
, "Removing ipv6 route (from zebra).");
81 find_xroute(const unsigned char *prefix
, unsigned char plen
)
84 for(i
= 0; i
< numxroutes
; i
++) {
85 if(xroutes
[i
].plen
== plen
&&
86 memcmp(xroutes
[i
].prefix
, prefix
, 16) == 0)
93 flush_xroute(struct xroute
*xroute
)
98 assert(i
>= 0 && i
< numxroutes
);
100 if(i
!= numxroutes
- 1)
101 memcpy(xroutes
+ i
, xroutes
+ numxroutes
- 1, sizeof(struct xroute
));
103 VALGRIND_MAKE_MEM_UNDEFINED(xroutes
+ numxroutes
, sizeof(struct xroute
));
105 if(numxroutes
== 0) {
109 } else if(maxxroutes
> 8 && numxroutes
< maxxroutes
/ 4) {
110 struct xroute
*new_xroutes
;
111 int n
= maxxroutes
/ 2;
112 new_xroutes
= realloc(xroutes
, n
* sizeof(struct xroute
));
113 if(new_xroutes
== NULL
)
115 xroutes
= new_xroutes
;
121 add_xroute(unsigned char prefix
[16], unsigned char plen
,
122 unsigned short metric
, unsigned int ifindex
, int proto
)
124 struct xroute
*xroute
= find_xroute(prefix
, plen
);
126 if(xroute
->metric
<= metric
)
128 xroute
->metric
= metric
;
132 if(numxroutes
>= maxxroutes
) {
133 struct xroute
*new_xroutes
;
134 int n
= maxxroutes
< 1 ? 8 : 2 * maxxroutes
;
135 new_xroutes
= xroutes
== NULL
?
136 malloc(n
* sizeof(struct xroute
)) :
137 realloc(xroutes
, n
* sizeof(struct xroute
));
138 if(new_xroutes
== NULL
)
141 xroutes
= new_xroutes
;
144 memcpy(xroutes
[numxroutes
].prefix
, prefix
, 16);
145 xroutes
[numxroutes
].plen
= plen
;
146 xroutes
[numxroutes
].metric
= metric
;
147 xroutes
[numxroutes
].ifindex
= ifindex
;
148 xroutes
[numxroutes
].proto
= proto
;
153 /* Returns an overestimate of the number of xroutes. */
155 xroutes_estimate(void)
160 struct xroute_stream
{
168 struct xroute_stream
*stream
= malloc(sizeof(struct xroute_stream
));
177 xroute_stream_next(struct xroute_stream
*stream
)
179 if(stream
->index
< numxroutes
)
180 return &xroutes
[stream
->index
++];
186 xroute_stream_done(struct xroute_stream
*stream
)
191 /* add an xroute, verifying some conditions; return 0 if there is no changes */
193 xroute_add_new_route(unsigned char prefix
[16], unsigned char plen
,
194 unsigned short metric
, unsigned int ifindex
,
195 int proto
, int send_updates
)
198 if(martian_prefix(prefix
, plen
))
200 metric
= redistribute_filter(prefix
, plen
, ifindex
, proto
);
201 if(metric
< INFINITY
) {
202 rc
= add_xroute(prefix
, plen
, metric
, ifindex
, proto
);
204 struct babel_route
*route
;
205 route
= find_installed_route(prefix
, plen
);
207 uninstall_route(route
);
209 send_update(NULL
, 0, prefix
, plen
);