Commit b8e832cb authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Change data structures and related functions to hold source prefixes.

parent 46ac5f94
...@@ -714,7 +714,7 @@ main(int argc, char **argv) ...@@ -714,7 +714,7 @@ main(int argc, char **argv)
if(timeval_compare(&now, &ifp->hello_timeout) >= 0) if(timeval_compare(&now, &ifp->hello_timeout) >= 0)
send_hello(ifp); send_hello(ifp);
if(timeval_compare(&now, &ifp->update_timeout) >= 0) if(timeval_compare(&now, &ifp->update_timeout) >= 0)
send_update(ifp, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
if(timeval_compare(&now, &ifp->update_flush_timeout) >= 0) if(timeval_compare(&now, &ifp->update_flush_timeout) >= 0)
flushupdates(ifp); flushupdates(ifp);
} }
......
...@@ -938,6 +938,7 @@ do_filter(struct filter *f, const unsigned char *id, ...@@ -938,6 +938,7 @@ do_filter(struct filter *f, const unsigned char *id,
int int
input_filter(const unsigned char *id, input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen, const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
const unsigned char *neigh, unsigned int ifindex) const unsigned char *neigh, unsigned int ifindex)
{ {
int res; int res;
...@@ -948,8 +949,10 @@ input_filter(const unsigned char *id, ...@@ -948,8 +949,10 @@ input_filter(const unsigned char *id,
} }
int int
output_filter(const unsigned char *id, const unsigned char *prefix, output_filter(const unsigned char *id,
unsigned short plen, unsigned int ifindex) const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex)
{ {
int res; int res;
res = do_filter(output_filters, id, prefix, plen, NULL, ifindex, 0); res = do_filter(output_filters, id, prefix, plen, NULL, ifindex, 0);
...@@ -960,6 +963,7 @@ output_filter(const unsigned char *id, const unsigned char *prefix, ...@@ -960,6 +963,7 @@ output_filter(const unsigned char *id, const unsigned char *prefix,
int int
redistribute_filter(const unsigned char *prefix, unsigned short plen, redistribute_filter(const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex, int proto) unsigned int ifindex, int proto)
{ {
int res; int res;
......
...@@ -42,9 +42,13 @@ void renumber_filters(void); ...@@ -42,9 +42,13 @@ void renumber_filters(void);
int input_filter(const unsigned char *id, int input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen, const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
const unsigned char *neigh, unsigned int ifindex); const unsigned char *neigh, unsigned int ifindex);
int output_filter(const unsigned char *id, const unsigned char *prefix, int output_filter(const unsigned char *id,
unsigned short plen, unsigned int ifindex); const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex);
int redistribute_filter(const unsigned char *prefix, unsigned short plen, int redistribute_filter(const unsigned char *prefix, unsigned short plen,
unsigned int ifindex, int proto); const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex, int proto);
int finalise_config(void); int finalise_config(void);
...@@ -380,7 +380,7 @@ interface_up(struct interface *ifp, int up) ...@@ -380,7 +380,7 @@ interface_up(struct interface *ifp, int up)
set_timeout(&ifp->update_timeout, ifp->update_interval); set_timeout(&ifp->update_timeout, ifp->update_interval);
send_hello(ifp); send_hello(ifp);
if(rc > 0) if(rc > 0)
send_update(ifp, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
send_request(ifp, NULL, 0); send_request(ifp, NULL, 0);
} else { } else {
flush_interface_routes(ifp, 0); flush_interface_routes(ifp, 0);
...@@ -467,7 +467,7 @@ check_interfaces(void) ...@@ -467,7 +467,7 @@ check_interfaces(void)
rc = check_interface_ipv4(ifp); rc = check_interface_ipv4(ifp);
if(rc > 0) { if(rc > 0) {
send_request(ifp, NULL, 0); send_request(ifp, NULL, 0);
send_update(ifp, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
} }
} }
} }
......
...@@ -541,7 +541,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -541,7 +541,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
len - parsed_len, channels); len - parsed_len, channels);
} }
update_route(router_id, prefix, plen, seqno, metric, interval, update_route(router_id, prefix, plen, NULL, 0, seqno, metric, interval,
neigh, nh, neigh, nh,
channels, channels_len(channels)); channels, channels_len(channels));
} else if(type == MESSAGE_REQUEST) { } else if(type == MESSAGE_REQUEST) {
...@@ -565,9 +565,9 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -565,9 +565,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
shortly after we sent a full update. */ shortly after we sent a full update. */
if(neigh->ifp->last_update_time < if(neigh->ifp->last_update_time <
now.tv_sec - MAX(neigh->ifp->hello_interval / 100, 1)) now.tv_sec - MAX(neigh->ifp->hello_interval / 100, 1))
send_update(neigh->ifp, 0, NULL, 0); send_update(neigh->ifp, 0, NULL, 0, zeroes, 0);
} else { } else {
send_update(neigh->ifp, 0, prefix, plen); send_update(neigh->ifp, 0, prefix, plen, zeroes, 0);
} }
} else if(type == MESSAGE_MH_REQUEST) { } else if(type == MESSAGE_MH_REQUEST) {
unsigned char prefix[16], plen; unsigned char prefix[16], plen;
...@@ -1002,7 +1002,8 @@ really_send_update(struct interface *ifp, ...@@ -1002,7 +1002,8 @@ really_send_update(struct interface *ifp,
if(!if_up(ifp)) if(!if_up(ifp))
return; return;
add_metric = output_filter(id, prefix, plen, ifp->ifindex); add_metric = output_filter(id, prefix, plen, zeroes,
0, ifp->ifindex);
if(add_metric >= INFINITY) if(add_metric >= INFINITY)
return; return;
...@@ -1146,7 +1147,7 @@ flushupdates(struct interface *ifp) ...@@ -1146,7 +1147,7 @@ flushupdates(struct interface *ifp)
with the same router-id together, with IPv6 going out before IPv4. */ with the same router-id together, with IPv6 going out before IPv4. */
for(i = 0; i < n; i++) { for(i = 0; i < n; i++) {
route = find_installed_route(b[i].prefix, b[i].plen); route = find_installed_route(b[i].prefix, b[i].plen, zeroes, 0);
if(route) if(route)
memcpy(b[i].id, route->src->id, 8); memcpy(b[i].id, route->src->id, 8);
else else
...@@ -1166,8 +1167,10 @@ flushupdates(struct interface *ifp) ...@@ -1166,8 +1167,10 @@ flushupdates(struct interface *ifp)
continue; continue;
} }
xroute = find_xroute(b[i].prefix, b[i].plen); xroute = find_xroute(b[i].prefix, b[i].plen,
route = find_installed_route(b[i].prefix, b[i].plen); zeroes, 0);
route = find_installed_route(b[i].prefix, b[i].plen,
zeroes, 0);
if(xroute && (!route || xroute->metric <= kernel_metric)) { if(xroute && (!route || xroute->metric <= kernel_metric)) {
really_send_update(ifp, myid, really_send_update(ifp, myid,
...@@ -1191,6 +1194,8 @@ flushupdates(struct interface *ifp) ...@@ -1191,6 +1194,8 @@ flushupdates(struct interface *ifp)
if(metric < INFINITY) if(metric < INFINITY)
satisfy_request(route->src->prefix, route->src->plen, satisfy_request(route->src->prefix, route->src->plen,
route->src->src_prefix,
route->src->src_plen,
seqno, route->src->id, ifp); seqno, route->src->id, ifp);
if((ifp->flags & IF_SPLIT_HORIZON) && if((ifp->flags & IF_SPLIT_HORIZON) &&
...@@ -1284,20 +1289,21 @@ buffer_update(struct interface *ifp, ...@@ -1284,20 +1289,21 @@ buffer_update(struct interface *ifp,
void void
send_update(struct interface *ifp, int urgent, send_update(struct interface *ifp, int urgent,
const unsigned char *prefix, unsigned char plen) const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen)
{ {
if(ifp == NULL) { if(ifp == NULL) {
struct interface *ifp_aux; struct interface *ifp_aux;
struct babel_route *route; struct babel_route *route;
FOR_ALL_INTERFACES(ifp_aux) FOR_ALL_INTERFACES(ifp_aux)
send_update(ifp_aux, urgent, prefix, plen); send_update(ifp_aux, urgent, prefix, plen, src_prefix, src_plen);
if(prefix) { if(prefix) {
/* Since flushupdates only deals with non-wildcard interfaces, we /* Since flushupdates only deals with non-wildcard interfaces, we
need to do this now. */ need to do this now. */
route = find_installed_route(prefix, plen); route = find_installed_route(prefix, plen, src_prefix, src_plen);
if(route && route_metric(route) < INFINITY) if(route && route_metric(route) < INFINITY)
satisfy_request(prefix, plen, route->src->seqno, route->src->id, satisfy_request(prefix, plen, src_prefix, src_plen,
NULL); route->src->seqno, route->src->id, NULL);
} }
return; return;
} }
...@@ -1333,12 +1339,14 @@ send_update(struct interface *ifp, int urgent, ...@@ -1333,12 +1339,14 @@ send_update(struct interface *ifp, int urgent,
void void
send_update_resend(struct interface *ifp, send_update_resend(struct interface *ifp,
const unsigned char *prefix, unsigned char plen) const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen)
{ {
assert(prefix != NULL); assert(prefix != NULL);
send_update(ifp, 1, prefix, plen); send_update(ifp, 1, prefix, plen, src_prefix, src_plen);
record_resend(RESEND_UPDATE, prefix, plen, 0, NULL, NULL, resend_delay); record_resend(RESEND_UPDATE, prefix, plen, src_prefix, src_plen,
0, NULL, NULL, resend_delay);
} }
void void
...@@ -1394,7 +1402,8 @@ send_self_update(struct interface *ifp) ...@@ -1394,7 +1402,8 @@ send_self_update(struct interface *ifp)
while(1) { while(1) {
struct xroute *xroute = xroute_stream_next(xroutes); struct xroute *xroute = xroute_stream_next(xroutes);
if(xroute == NULL) break; if(xroute == NULL) break;
send_update(ifp, 0, xroute->prefix, xroute->plen); send_update(ifp, 0, xroute->prefix, xroute->plen,
xroute->src_prefix, xroute->src_plen);
} }
xroute_stream_done(xroutes); xroute_stream_done(xroutes);
} else { } else {
...@@ -1678,7 +1687,7 @@ send_request_resend(struct neighbour *neigh, ...@@ -1678,7 +1687,7 @@ send_request_resend(struct neighbour *neigh,
else else
send_multihop_request(NULL, prefix, plen, seqno, id, 127); send_multihop_request(NULL, prefix, plen, seqno, id, 127);
record_resend(RESEND_REQUEST, prefix, plen, seqno, id, record_resend(RESEND_REQUEST, prefix, plen, zeroes, 0, seqno, id,
neigh ? neigh->ifp : NULL, resend_delay); neigh ? neigh->ifp : NULL, resend_delay);
} }
...@@ -1691,8 +1700,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1691,8 +1700,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
struct babel_route *route; struct babel_route *route;
struct neighbour *successor = NULL; struct neighbour *successor = NULL;
xroute = find_xroute(prefix, plen); xroute = find_xroute(prefix, plen, zeroes, 0);
route = find_installed_route(prefix, plen); route = find_installed_route(prefix, plen, zeroes, 0);
if(xroute && (!route || xroute->metric <= kernel_metric)) { if(xroute && (!route || xroute->metric <= kernel_metric)) {
if(hop_count > 0 && memcmp(id, myid, 8) == 0) { if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
...@@ -1704,14 +1713,16 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1704,14 +1713,16 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
update_myseqno(); update_myseqno();
} }
} }
send_update(neigh->ifp, 1, prefix, plen); send_update(neigh->ifp, 1, prefix, plen,
xroute->src_prefix, xroute->src_plen);
return; return;
} }
if(route && if(route &&
(memcmp(id, route->src->id, 8) != 0 || (memcmp(id, route->src->id, 8) != 0 ||
seqno_compare(seqno, route->seqno) <= 0)) { seqno_compare(seqno, route->seqno) <= 0)) {
send_update(neigh->ifp, 1, prefix, plen); send_update(neigh->ifp, 1, prefix, plen,
route->src->src_prefix, route->src->src_plen);
return; return;
} }
...@@ -1736,7 +1747,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1736,7 +1747,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
find a different neighbour to forward the request to. */ find a different neighbour to forward the request to. */
struct babel_route *other_route; struct babel_route *other_route;
other_route = find_best_route(prefix, plen, 0, neigh); other_route = find_best_route(prefix, plen, zeroes, 0,
0, neigh);
if(other_route && route_metric(other_route) < INFINITY) if(other_route && route_metric(other_route) < INFINITY)
successor = other_route->neigh; successor = other_route->neigh;
} }
...@@ -1747,6 +1759,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1747,6 +1759,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
send_unicast_multihop_request(successor, prefix, plen, seqno, id, send_unicast_multihop_request(successor, prefix, plen, seqno, id,
hop_count - 1); hop_count - 1);
record_resend(RESEND_REQUEST, prefix, plen, seqno, id, record_resend(RESEND_REQUEST, prefix, plen, zeroes, 0, seqno, id,
neigh->ifp, 0); neigh->ifp, 0);
} }
...@@ -67,9 +67,12 @@ void send_hello_noupdate(struct interface *ifp, unsigned interval); ...@@ -67,9 +67,12 @@ void send_hello_noupdate(struct interface *ifp, unsigned interval);
void send_hello(struct interface *ifp); void send_hello(struct interface *ifp);
void flush_unicast(int dofree); void flush_unicast(int dofree);
void send_update(struct interface *ifp, int urgent, void send_update(struct interface *ifp, int urgent,
const unsigned char *prefix, unsigned char plen); const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen);
void send_update_resend(struct interface *ifp, void send_update_resend(struct interface *ifp,
const unsigned char *prefix, unsigned char plen); const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen);
void send_wildcard_retraction(struct interface *ifp); void send_wildcard_retraction(struct interface *ifp);
void update_myseqno(void); void update_myseqno(void);
void send_self_update(struct interface *ifp); void send_self_update(struct interface *ifp);
......
...@@ -75,6 +75,7 @@ find_resend(int kind, const unsigned char *prefix, unsigned char plen, ...@@ -75,6 +75,7 @@ find_resend(int kind, const unsigned char *prefix, unsigned char plen,
struct resend * struct resend *
find_request(const unsigned char *prefix, unsigned char plen, find_request(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
struct resend **previous_return) struct resend **previous_return)
{ {
return find_resend(RESEND_REQUEST, prefix, plen, previous_return); return find_resend(RESEND_REQUEST, prefix, plen, previous_return);
...@@ -82,6 +83,7 @@ find_request(const unsigned char *prefix, unsigned char plen, ...@@ -82,6 +83,7 @@ find_request(const unsigned char *prefix, unsigned char plen,
int int
record_resend(int kind, const unsigned char *prefix, unsigned char plen, record_resend(int kind, const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
unsigned short seqno, const unsigned char *id, unsigned short seqno, const unsigned char *id,
struct interface *ifp, int delay) struct interface *ifp, int delay)
{ {
...@@ -89,9 +91,11 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen, ...@@ -89,9 +91,11 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned int ifindex = ifp ? ifp->ifindex : 0; unsigned int ifindex = ifp ? ifp->ifindex : 0;
if((kind == RESEND_REQUEST && if((kind == RESEND_REQUEST &&
input_filter(NULL, prefix, plen, NULL, ifindex) >= INFINITY) || input_filter(NULL, prefix, plen, NULL, 0, NULL, ifindex) >=
INFINITY) ||
(kind == RESEND_UPDATE && (kind == RESEND_UPDATE &&
output_filter(NULL, prefix, plen, ifindex) >= INFINITY)) output_filter(NULL, prefix, plen, src_prefix, src_plen, ifindex) >=
INFINITY))
return 0; return 0;
if(delay >= 0xFFFF) if(delay >= 0xFFFF)
...@@ -161,7 +165,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen, ...@@ -161,7 +165,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
{ {
struct resend *request; struct resend *request;
request = find_request(prefix, plen, NULL); request = find_request(prefix, plen, zeroes, 0, NULL);
if(request == NULL || resend_expired(request)) if(request == NULL || resend_expired(request))
return 0; return 0;
...@@ -180,7 +184,7 @@ request_redundant(struct interface *ifp, ...@@ -180,7 +184,7 @@ request_redundant(struct interface *ifp,
{ {
struct resend *request; struct resend *request;
request = find_request(prefix, plen, NULL); request = find_request(prefix, plen, zeroes, 0, NULL);
if(request == NULL || resend_expired(request)) if(request == NULL || resend_expired(request))
return 0; return 0;
...@@ -205,12 +209,13 @@ request_redundant(struct interface *ifp, ...@@ -205,12 +209,13 @@ request_redundant(struct interface *ifp,
int int
satisfy_request(const unsigned char *prefix, unsigned char plen, satisfy_request(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
unsigned short seqno, const unsigned char *id, unsigned short seqno, const unsigned char *id,
struct interface *ifp) struct interface *ifp)
{ {
struct resend *request, *previous; struct resend *request, *previous;
request = find_request(prefix, plen, &previous); request = find_request(prefix, plen, zeroes, 0, &previous);
if(request == NULL) if(request == NULL)
return 0; return 0;
...@@ -297,7 +302,8 @@ do_resend() ...@@ -297,7 +302,8 @@ do_resend()
break; break;
case RESEND_UPDATE: case RESEND_UPDATE:
send_update(resend->ifp, 1, send_update(resend->ifp, 1,
resend->prefix, resend->plen); resend->prefix, resend->plen,
zeroes, 0);
break; break;
default: abort(); default: abort();
} }
......
...@@ -42,17 +42,20 @@ struct resend { ...@@ -42,17 +42,20 @@ struct resend {
extern struct timeval resend_time; extern struct timeval resend_time;
struct resend *find_request(const unsigned char *prefix, unsigned char plen, struct resend *find_request(const unsigned char *prefix, unsigned char plen,
struct resend **previous_return); const unsigned char *src_prefix, unsigned char src_plen,
struct resend **previous_return);
void flush_resends(struct neighbour *neigh); void flush_resends(struct neighbour *neigh);
int record_resend(int kind, const unsigned char *prefix, unsigned char plen, int record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id, const unsigned char *src_prefix, unsigned char src_plen,
struct interface *ifp, int delay); unsigned short seqno, const unsigned char *id,
struct interface *ifp, int delay);
int unsatisfied_request(const unsigned char *prefix, unsigned char plen, int unsatisfied_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id); unsigned short seqno, const unsigned char *id);
int request_redundant(struct interface *ifp, int request_redundant(struct interface *ifp,
const unsigned char *prefix, unsigned char plen, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id); unsigned short seqno, const unsigned char *id);
int satisfy_request(const unsigned char *prefix, unsigned char plen, int satisfy_request(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
unsigned short seqno, const unsigned char *id, unsigned short seqno, const unsigned char *id,
struct interface *ifp); struct interface *ifp);
......
This diff is collapsed.
...@@ -70,9 +70,15 @@ route_metric_noninterfering(const struct babel_route *route) ...@@ -70,9 +70,15 @@ route_metric_noninterfering(const struct babel_route *route)
} }
struct babel_route *find_route(const unsigned char *prefix, unsigned char plen, struct babel_route *find_route(const unsigned char *prefix, unsigned char plen,
struct neighbour *neigh, const unsigned char *nexthop); const unsigned char *src_prefix, unsigned char src_plen,
struct neighbour *neigh, const unsigned char *nexthop);
struct babel_route *find_installed_route(const unsigned char *prefix, struct babel_route *find_installed_route(const unsigned char *prefix,
unsigned char plen); unsigned char plen, const unsigned char *src_prefix,
unsigned char src_plen);
struct babel_route *find_min_iroute(const unsigned char *dst_prefix,
unsigned char dst_plen,
const unsigned char *src_prefix, unsigned char src_plen,
int is_min_dst, int is_min_src, int exclusive_min);
int installed_routes_estimate(void); int installed_routes_estimate(void);
void flush_route(struct babel_route *route); void flush_route(struct babel_route *route);
void flush_all_routes(void); void flush_all_routes(void);
...@@ -93,6 +99,8 @@ void change_smoothing_half_life(int half_life); ...@@ -93,6 +99,8 @@ void change_smoothing_half_life(int half_life);
int route_smoothed_metric(struct babel_route *route); int route_smoothed_metric(struct babel_route *route);
struct babel_route *find_best_route(const unsigned char *prefix, struct babel_route *find_best_route(const unsigned char *prefix,
unsigned char plen, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen,
int feasible, struct neighbour *exclude); int feasible, struct neighbour *exclude);
struct babel_route *install_best_route(const unsigned char prefix[16], struct babel_route *install_best_route(const unsigned char prefix[16],
unsigned char plen); unsigned char plen);
...@@ -101,6 +109,8 @@ void update_interface_metric(struct interface *ifp); ...@@ -101,6 +109,8 @@ void update_interface_metric(struct interface *ifp);
void update_route_metric(struct babel_route *route); void update_route_metric(struct babel_route *route);
struct babel_route *update_route(const unsigned char *id, struct babel_route *update_route(const unsigned char *id,
const unsigned char *prefix, unsigned char plen, const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen,
unsigned short seqno, unsigned short refmetric, unsigned short seqno, unsigned short refmetric,
unsigned short interval, struct neighbour *neigh, unsigned short interval, struct neighbour *neigh,
const unsigned char *nexthop, const unsigned char *nexthop,
......
...@@ -35,7 +35,9 @@ THE SOFTWARE. ...@@ -35,7 +35,9 @@ THE SOFTWARE.
struct source *srcs = NULL; struct source *srcs = NULL;
struct source* struct source*
find_source(const unsigned char *id, const unsigned char *p, unsigned char plen, find_source(const unsigned char *id,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
int create, unsigned short seqno) int create, unsigned short seqno)
{ {
struct source *src; struct source *src;
...@@ -49,7 +51,11 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen, ...@@ -49,7 +51,11 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
continue; continue;
if(src->plen != plen) if(src->plen != plen)
continue; continue;
if(memcmp(src->prefix, p, 16) == 0) if(src->src_plen != src_plen)
continue;
if(memcmp(src->prefix, prefix, 16) != 0)
continue;
if(memcmp(src->src_prefix, src_prefix, 16) == 0)
return src; return src;
} }
...@@ -63,8 +69,10 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen, ...@@ -63,8 +69,10 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
} }
memcpy(src->id, id, 8); memcpy(src->id, id, 8);
memcpy(src->prefix, p, 16); memcpy(src->prefix, prefix, 16);
src->plen = plen; src->plen = plen;
memcpy(src->src_prefix, src_prefix, 16);
src->src_plen = src_plen;
src->seqno = seqno; src->seqno = seqno;
src->metric = INFINITY; src->metric = INFINITY;
src->time = now.tv_sec; src->time = now.tv_sec;
......
...@@ -27,6 +27,8 @@ struct source { ...@@ -27,6 +27,8 @@ struct source {
unsigned char id[8]; unsigned char id[8];
unsigned char prefix[16]; unsigned char prefix[16];
unsigned char plen; unsigned char plen;
unsigned char src_prefix[16];
unsigned char src_plen;
unsigned short seqno; unsigned short seqno;
unsigned short metric; unsigned short metric;
unsigned short route_count; unsigned short route_count;
...@@ -34,8 +36,10 @@ struct source { ...@@ -34,8 +36,10 @@ struct source {
}; };
struct source *find_source(const unsigned char *id, struct source *find_source(const unsigned char *id,
const unsigned char *p, const unsigned char *prefix,
unsigned char plen, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen,
int create, unsigned short seqno); int create, unsigned short seqno);
struct source *retain_source(struct source *src); struct source *retain_source(struct source *src);
void release_source(struct source *src); void release_source(struct source *src);
......
...@@ -111,6 +111,7 @@ int linklocal(const unsigned char *address) ATTRIBUTE ((pure)); ...@@ -111,6 +111,7 @@ int linklocal(const unsigned char *address) ATTRIBUTE ((pure));
int v4mapped(const unsigned char *address) ATTRIBUTE ((pure)); int v4mapped(const unsigned char *address) ATTRIBUTE ((pure));
void v4tov6(unsigned char *dst, const unsigned char *src); void v4tov6(unsigned char *dst, const unsigned char *src);
int daemonise(void); int daemonise(void);
int set_src_prefix(unsigned char *src_addr, unsigned char *src_plen);
enum prefix_status { enum prefix_status {
PST_DISJOINT = 1 << 0, PST_DISJOINT = 1 << 0,
......
...@@ -43,12 +43,15 @@ static struct xroute *xroutes; ...@@ -43,12 +43,15 @@ static struct xroute *xroutes;
static int numxroutes = 0, maxxroutes = 0; static int numxroutes = 0, maxxroutes = 0;
struct xroute * struct xroute *
find_xroute(const unsigned char *prefix, unsigned char plen) find_xroute(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen)
{ {
int i; int i;
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
if(xroutes[i].plen == plen && if(xroutes[i].plen == plen &&
memcmp(xroutes[i].prefix, prefix, 16) == 0) memcmp(xroutes[i].prefix, prefix, 16) == 0 &&
xroutes[i].src_plen == src_plen &&
memcmp(xroutes[i].src_prefix, src_prefix, 16) == 0)
return &xroutes[i]; return &xroutes[i];
} }
return NULL; return NULL;
...@@ -86,9 +89,10 @@ flush_xroute(struct xroute *xroute) ...@@ -86,9 +89,10 @@ flush_xroute(struct xroute *xroute)
int int
add_xroute(unsigned char prefix[16], unsigned char plen, add_xroute(unsigned char prefix[16], unsigned char plen,
unsigned char src_prefix[16], unsigned char src_plen,
unsigned short metric, unsigned int ifindex, int proto) unsigned short metric, unsigned int ifindex, int proto)
{ {
struct xroute *xroute = find_xroute(prefix, plen); struct xroute *xroute = find_xroute(prefix, plen, src_prefix, src_plen);
if(xroute) { if(xroute) {
if(xroute->metric <= metric) if(xroute->metric <= metric)
return 0; return 0;
...@@ -111,6 +115,8 @@ add_xroute(unsigned char prefix[16], unsigned char plen, ...@@ -111,6 +115,8 @@ add_xroute(unsigned char prefix[16], unsigned char plen,
memcpy(xroutes[numxroutes].prefix, prefix, 16); memcpy(xroutes[numxroutes].prefix, prefix, 16);
xroutes[numxroutes].plen = plen; xroutes[numxroutes].plen = plen;
memcpy(xroutes[numxroutes].src_prefix, src_prefix, 16);
xroutes[numxroutes].src_plen = src_plen;
xroutes[numxroutes].metric = metric; xroutes[numxroutes].metric = metric;
xroutes[numxroutes].ifindex = ifindex; xroutes[numxroutes].ifindex = ifindex;
xroutes[numxroutes].proto = proto; xroutes[numxroutes].proto = proto;
...@@ -200,6 +206,7 @@ check_xroutes(int send_updates) ...@@ -200,6 +206,7 @@ check_xroutes(int send_updates)
while(i < numxroutes) { while(i < numxroutes) {
export = 0; export = 0;
metric = redistribute_filter(xroutes[i].prefix, xroutes[i].plen, metric = redistribute_filter(xroutes[i].prefix, xroutes[i].plen,
xroutes[i].src_prefix, xroutes[i].src_plen,
xroutes[i].ifindex, xroutes[i].proto); xroutes[i].ifindex, xroutes[i].proto);
if(metric < INFINITY && metric == xroutes[i].metric) { if(metric < INFINITY && metric == xroutes[i].metric) {
for(j = 0; j < numroutes; j++) { for(j = 0; j < numroutes; j++) {
...@@ -215,17 +222,20 @@ check_xroutes(int send_updates) ...@@ -215,17 +222,20 @@ check_xroutes(int send_updates)
if(!export) { if(!export) {
unsigned char prefix[16], plen; unsigned char prefix[16], plen;
unsigned char src_prefix[16], src_plen;
struct babel_route *route; struct babel_route *route;
memcpy(prefix, xroutes[i].prefix, 16); memcpy(prefix, xroutes[i].prefix, 16);
plen = xroutes[i].plen; plen = xroutes[i].plen;
memcpy(src_prefix, xroutes[i].src_prefix, 16);
src_plen = xroutes[i].src_plen;
flush_xroute(&xroutes[i]); flush_xroute(&xroutes[i]);
route = find_best_route(prefix, plen, 1, NULL); route = find_best_route(prefix, plen, src_prefix, src_plen, 1,NULL);
if(route) if(route)
install_route(route); install_route(route);
/* send_update_resend only records the prefix, so the update /* send_update_resend only records the prefix, so the update
will only be sent after we perform all of the changes. */ will only be sent after we perform all of the changes. */
if(send_updates) if(send_updates)
send_update_resend(NULL, prefix, plen); send_update_resend(NULL, prefix, plen, src_prefix, src_plen);
change = 1; change = 1;
} else { } else {
i++; i++;
...@@ -238,13 +248,17 @@ check_xroutes(int send_updates) ...@@ -238,13 +248,17 @@ check_xroutes(int send_updates)
if(martian_prefix(routes[i].prefix, routes[i].plen)) if(martian_prefix(routes[i].prefix, routes[i].plen))
continue; continue;
metric = redistribute_filter(routes[i].prefix, routes[i].plen, metric = redistribute_filter(routes[i].prefix, routes[i].plen,
routes[i].src_prefix, routes[i].src_plen,
routes[i].ifindex, routes[i].proto); routes[i].ifindex, routes[i].proto);
if(metric < INFINITY) { if(metric < INFINITY) {
rc = add_xroute(routes[i].prefix, routes[i].plen, rc = add_xroute(routes[i].prefix, routes[i].plen,
routes[i].src_prefix, routes[i].src_plen,
metric, routes[i].ifindex, routes[i].proto); metric, routes[i].ifindex, routes[i].proto);
if(rc > 0) { if(rc > 0) {
struct babel_route *route; struct babel_route *route;
route = find_installed_route(routes[i].prefix, routes[i].plen); route = find_installed_route(routes[i].prefix, routes[i].plen,
routes[i].src_prefix,
routes[i].src_plen);
if(route) { if(route) {
if(allow_duplicates < 0 || if(allow_duplicates < 0 ||
routes[i].metric < allow_duplicates) routes[i].metric < allow_duplicates)
...@@ -252,7 +266,8 @@ check_xroutes(int send_updates) ...@@ -252,7 +266,8 @@ check_xroutes(int send_updates)
} }
change = 1; change = 1;
if(send_updates) if(send_updates)
send_update(NULL, 0, routes[i].prefix, routes[i].plen); send_update(NULL, 0, routes[i].prefix, routes[i].plen,
routes[i].src_prefix, routes[i].src_plen);
} }
} }
} }
......
...@@ -23,6 +23,8 @@ THE SOFTWARE. ...@@ -23,6 +23,8 @@ THE SOFTWARE.
struct xroute { struct xroute {
unsigned char prefix[16]; unsigned char prefix[16];
unsigned char plen; unsigned char plen;
unsigned char src_prefix[16];
unsigned char src_plen;
unsigned short metric; unsigned short metric;
unsigned int ifindex; unsigned int ifindex;
int proto; int proto;
...@@ -30,9 +32,11 @@ struct xroute { ...@@ -30,9 +32,11 @@ struct xroute {
struct xroute_stream; struct xroute_stream;
struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen); struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen);
void flush_xroute(struct xroute *xroute); void flush_xroute(struct xroute *xroute);
int add_xroute(unsigned char prefix[16], unsigned char plen, int add_xroute(unsigned char prefix[16], unsigned char plen,
unsigned char src_prefix[16], unsigned char src_plen,
unsigned short metric, unsigned int ifindex, int proto); unsigned short metric, unsigned int ifindex, int proto);
int xroutes_estimate(void); int xroutes_estimate(void);
struct xroute_stream *xroute_stream(); struct xroute_stream *xroute_stream();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment