Commit b8e832cb by Matthieu Boutier Committed by Juliusz Chroboczek

Change data structures and related functions to hold source prefixes.

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