Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added redistribute live and check_xroutes #114

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ tags
*.orig
*~
\#*#
.vscode/
4 changes: 2 additions & 2 deletions babeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ main(int argc, char **argv)

check_interfaces();

rc = check_xroutes(0, 0);
rc = check_xroutes(0, 0, 0);
if(rc < 0)
fprintf(stderr, "Warning: couldn't check exported routes.\n");

Expand Down Expand Up @@ -684,7 +684,7 @@ main(int argc, char **argv)

if(kernel_addr_changed ||
(kernel_check_interval > 0 && now.tv_sec >= kernel_dump_time)) {
rc = check_xroutes(1, !kernel_addr_changed);
rc = check_xroutes(1, !kernel_addr_changed, 0);
if(rc < 0)
fprintf(stderr, "Warning: couldn't check exported routes.\n");
kernel_addr_changed = 0;
Expand Down
49 changes: 44 additions & 5 deletions configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ static int config_finalised = 0;
/* get_next_char callback */
typedef int (*gnc_t)(void*);

static int update_filter(struct filter *f, struct filter *newf);

static int
skip_whitespace(int c, gnc_t gnc, void *closure)
{
Expand Down Expand Up @@ -1177,12 +1179,26 @@ parse_config_line(int c, gnc_t gnc, void *closure,
add_filter(filter, FILTER_TYPE_OUTPUT);
} else if(strcmp(token, "redistribute") == 0) {
struct filter *filter;
if(config_finalised)
goto fail;
c = parse_filter(c, gnc, closure, &filter);
if(c < -1)
goto fail;
add_filter(filter, FILTER_TYPE_REDISTRIBUTE);
if(config_finalised) {
if(!action_return)
goto fail;
c = update_filter(redistribute_filters, filter);
free_filter(filter);
if (c == 0) {
if(action_return)
*action_return = CONFIG_ACTION_NO;
if(message_return) {
*message_return = "Couldn't find the redistribute filter to update";
}
}
if(c < -1)
goto fail;
} else {
add_filter(filter, FILTER_TYPE_REDISTRIBUTE);
}
} else if(strcmp(token, "install") == 0) {
struct filter *filter;
if(config_finalised)
Expand Down Expand Up @@ -1256,6 +1272,11 @@ parse_config_line(int c, gnc_t gnc, void *closure,
goto fail;
add_key(key->id, key->type, key->len, key->value);
free(key);
} else if(strcmp(token, "check_xroutes") == 0) {
c = skip_eol(c, gnc, closure);
if(c < -1 || !action_return)
goto fail;
*action_return = CONFIG_ACTION_CHECK_XROUTES;
} else {
c = parse_option(c, gnc, closure, token);
if(c < -1)
Expand Down Expand Up @@ -1460,6 +1481,23 @@ do_filter(struct filter *f, const unsigned char *id,
return -1;
}

static int
update_filter(struct filter *f, struct filter *newf)
{
while(f) {
if(filter_match(f, newf->id, newf->prefix, newf->plen, newf->src_prefix, newf->src_plen,
newf->neigh, newf->ifindex, newf->proto)) {
f->action.add_metric = newf->action.add_metric;
// f->action.table = newf->action.table;
// memcpy(f->action.pref_src, newf->action.pref_src, 16);
return -1;
}
f = f->next;
}

return 0;
}

int
input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
Expand Down Expand Up @@ -1503,13 +1541,14 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen,
}

int
install_filter(const unsigned char *prefix, unsigned short plen,
install_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex,
struct filter_result *result)
{
int res;
res = do_filter(install_filters, NULL, prefix, plen,
res = do_filter(install_filters, id, prefix, plen,
src_prefix, src_plen, NULL, ifindex, 0, result);
if(res < 0)
res = INFINITY;
Expand Down
4 changes: 3 additions & 1 deletion configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ THE SOFTWARE.
#define CONFIG_ACTION_MONITOR 3
#define CONFIG_ACTION_UNMONITOR 4
#define CONFIG_ACTION_NO 5
#define CONFIG_ACTION_CHECK_XROUTES 6

#define AUTH_TYPE_NONE 0
#define AUTH_TYPE_SHA256 1
Expand Down Expand Up @@ -84,7 +85,8 @@ int redistribute_filter(const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex, int proto,
struct filter_result *result);
int install_filter(const unsigned char *prefix, unsigned short plen,
int install_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex, struct filter_result *result);
int finalise_config(void);
3 changes: 2 additions & 1 deletion kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ int kernel_route(int operation, int table,
const unsigned char *pref_src,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric, int newtable);
unsigned int newmetric, int newtable,
const unsigned char *newpref_src);
int kernel_dump(int operation, struct kernel_filter *filter);
int kernel_callback(struct kernel_filter *filter);
int if_eui64(char *ifname, int ifindex, unsigned char *eui);
Expand Down
9 changes: 5 additions & 4 deletions kernel_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,8 @@ kernel_route(int operation, int table,
const unsigned char *pref_src,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric, int newtable)
unsigned int newmetric, int newtable,
const unsigned char *newpref_src)
{
union { char raw[1024]; struct nlmsghdr nh; } buf;
struct rtmsg *rtm;
Expand Down Expand Up @@ -1011,11 +1012,11 @@ kernel_route(int operation, int table,
kernel_route(ROUTE_FLUSH, table, dest, plen,
src, src_plen, pref_src,
gate, ifindex, metric,
NULL, 0, 0, 0);
NULL, 0, 0, 0, NULL);
rc = kernel_route(ROUTE_ADD, newtable, dest, plen,
src, src_plen, pref_src,
src, src_plen, newpref_src,
newgate, newifindex, newmetric,
NULL, 0, 0, 0);
NULL, 0, 0, 0, NULL);
if(rc < 0) {
if(errno == EEXIST)
rc = 1;
Expand Down
9 changes: 5 additions & 4 deletions kernel_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,8 @@ kernel_route(int operation, int table,
const unsigned char *pref_src,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric, int newtable)
unsigned int newmetric, int newtable,
const unsigned char *newpref_src)
{
struct {
struct rt_msghdr m_rtm;
Expand All @@ -423,7 +424,7 @@ kernel_route(int operation, int table,

/* Source-specific routes & preferred source IPs
* are not implemented yet for BSD. */
if((!is_default(src, src_plen)) || pref_src) {
if((!is_default(src, src_plen)) || pref_src || newpref_src) {
errno = ENOSYS;
return -1;
}
Expand Down Expand Up @@ -454,11 +455,11 @@ kernel_route(int operation, int table,
kernel_route(ROUTE_FLUSH, table, dest, plen,
src, src_plen, NULL,
gate, ifindex, metric,
NULL, 0, 0, 0);
NULL, 0, 0, 0, NULL);
return kernel_route(ROUTE_ADD, table, dest, plen,
src, src_plen, NULL,
newgate, newifindex, newmetric,
NULL, 0, 0, 0);
NULL, 0, 0, 0, NULL);

}

Expand Down
6 changes: 6 additions & 0 deletions local.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ local_read(struct local_socket *s)
snprintf(reply, sizeof(reply), "no%s%s\n",
message ? " " : "", message ? message : "");
break;
case CONFIG_ACTION_CHECK_XROUTES:
rc = check_xroutes(1, 0, 1);
if(rc < 0) {
snprintf(reply, sizeof(reply), "Warning: couldn't check exported routes.\n");
}
break;
default:
snprintf(reply, sizeof(reply), "bad\n");
}
Expand Down
29 changes: 22 additions & 7 deletions route.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,14 +439,17 @@ move_installed_route(struct babel_route *route, int i)
static int
change_route(int operation, const struct babel_route *route, int metric,
const unsigned char *new_next_hop,
int new_ifindex, int new_metric)
int new_ifindex, int new_metric,
const struct source *newsrc)
{
struct filter_result filter_result;
unsigned char *pref_src = NULL;
unsigned char *newpref_src = NULL;
unsigned int ifindex = route->neigh->ifp->ifindex;
int m, table;

m = install_filter(route->src->prefix, route->src->plen,
m = install_filter(route->src->id,
route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen,
ifindex, &filter_result);
if(m >= INFINITY && operation == ROUTE_ADD) {
Expand All @@ -455,13 +458,24 @@ change_route(int operation, const struct babel_route *route, int metric,
}

pref_src = filter_result.pref_src;
newpref_src = pref_src;
table = filter_result.table ? filter_result.table : export_table;

if(newsrc) {
m = install_filter(newsrc->id,
newsrc->prefix, newsrc->plen,
newsrc->src_prefix, newsrc->src_plen,
new_ifindex, &filter_result);
if(m < INFINITY && filter_result.pref_src)
newpref_src = filter_result.pref_src;
}

return kernel_route(operation, table, route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen, pref_src,
route->nexthop, ifindex,
metric, new_next_hop, new_ifindex, new_metric,
operation == ROUTE_MODIFY ? table : 0);
operation == ROUTE_MODIFY ? table : 0,
newpref_src);
}

void
Expand Down Expand Up @@ -490,7 +504,7 @@ install_route(struct babel_route *route)
format_prefix(route->src->prefix, route->src->plen),
format_prefix(route->src->src_prefix, route->src->src_plen));
rc = change_route(ROUTE_ADD, route, metric_to_kernel(route_metric(route)),
NULL, 0, 0);
NULL, 0, 0, NULL);
if(rc < 0 && errno != EEXIST) {
perror("kernel_route(ADD)");
return;
Expand All @@ -516,7 +530,7 @@ uninstall_route(struct babel_route *route)
format_prefix(route->src->prefix, route->src->plen),
format_prefix(route->src->src_prefix, route->src->src_plen));
rc = change_route(ROUTE_FLUSH, route, metric_to_kernel(route_metric(route)),
NULL, 0, 0);
NULL, 0, 0, NULL);
if(rc < 0) {
perror("kernel_route(FLUSH)");
return;
Expand Down Expand Up @@ -550,7 +564,8 @@ switch_routes(struct babel_route *old, struct babel_route *new)
format_prefix(old->src->src_prefix, old->src->src_plen));
rc = change_route(ROUTE_MODIFY, old, metric_to_kernel(route_metric(old)),
new->nexthop, new->neigh->ifp->ifindex,
metric_to_kernel(route_metric(new)));
metric_to_kernel(route_metric(new)),
new->src);
if(rc < 0) {
perror("kernel_route(MODIFY)");
return;
Expand Down Expand Up @@ -580,7 +595,7 @@ change_route_metric(struct babel_route *route,
format_prefix(route->src->src_prefix, route->src->src_plen),
old_metric, new_metric);
rc = change_route(ROUTE_MODIFY, route, old_metric, route->nexthop,
route->neigh->ifp->ifindex, new_metric);
route->neigh->ifp->ifindex, new_metric, NULL);
if(rc < 0) {
perror("kernel_route(MODIFY metric)");
return;
Expand Down
6 changes: 4 additions & 2 deletions xroute.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ kernel_route_notify(int add, struct kernel_route *kroute, void *closure)


int
check_xroutes(int send_updates, int warn)
check_xroutes(int send_updates, int warn, int check_infinity)
{
int i, j, change = 0, rc;
struct kernel_route *routes;
Expand Down Expand Up @@ -481,14 +481,16 @@ check_xroutes(int send_updates, int warn)
memcpy(routes[i].src_prefix, filter_result.src_prefix, 16);
routes[i].src_plen = filter_result.src_plen;
}
debugf("Route %s metric %d\n",
format_prefix(routes[i].prefix, routes[i].plen), routes[i].metric);
}

qsort(routes, numroutes, sizeof(struct kernel_route), kernel_route_compare);
i = 0;
j = 0;
while(i < numroutes || j < numxroutes) {
/* Ignore routes filtered out. */
if(i < numroutes && routes[i].metric >= INFINITY) {
if(!check_infinity && i < numroutes && routes[i].metric >= INFINITY) {
i++;
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion xroute.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ void xroute_stream_done(struct xroute_stream *stream);
int kernel_addresses(int ifindex, int ll,
struct kernel_route *routes, int maxroutes);
void kernel_route_notify(int add, struct kernel_route *route, void *closure);
int check_xroutes(int send_updates, int warn);
int check_xroutes(int send_updates, int warn, int check_infinity);