From f585166c566c26cdff6cc35fff3c736786a3b456 Mon Sep 17 00:00:00 2001 From: Gaspare Iengo Date: Sun, 3 Mar 2024 20:37:57 +0000 Subject: [PATCH 1/3] Added Visual Studio Code directory to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4e888447..afcd3145 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ tags *.orig *~ \#*# +.vscode/ From 893834d48a07a5a5479dbd2db8f43d0b8a1a275f Mon Sep 17 00:00:00 2001 From: Gaspare Iengo Date: Sun, 3 Mar 2024 21:03:16 +0000 Subject: [PATCH 2/3] Added router id to install filter The router id allows to assign origin-based pref-src. A use case is, when installing default routes originated by two edge routers with different subnets, and the client has 2 ips matching the separate subnets install ip 0.0.0.0/0 eq 0 id 00:02:00:00:00:00:1d:01 pref-src 66.199.5.163 install ip 0.0.0.0/0 eq 0 id 00:02:00:00:00:00:1d:00 pref-src 12.144.66.186 --- configuration.c | 5 +++-- configuration.h | 3 ++- route.c | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/configuration.c b/configuration.c index 045d3043..297bbb0f 100644 --- a/configuration.c +++ b/configuration.c @@ -1503,13 +1503,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; diff --git a/configuration.h b/configuration.h index 95ce16cc..4e10fa00 100644 --- a/configuration.h +++ b/configuration.h @@ -84,7 +84,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); diff --git a/route.c b/route.c index fa5bf30a..cf2dcedf 100644 --- a/route.c +++ b/route.c @@ -446,7 +446,8 @@ change_route(int operation, const struct babel_route *route, int metric, 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) { From 9a08f36165a4a3b0c745323fbaabc70ef49a122e Mon Sep 17 00:00:00 2001 From: Gaspare Iengo Date: Sun, 3 Mar 2024 21:21:37 +0000 Subject: [PATCH 3/3] Fix pref-src on route change When two similar routes with pref-src were switched, the pref-src was not updated to the new one. With this fix, switch_routes passes the new->src to change_route, which is used to reapply the install_filter and retrieve the newpref_src from the filter_result. kernel_route for netlink has been updated to support the newpref_src on ROUTE_MODIFY --- kernel.h | 3 ++- kernel_netlink.c | 9 +++++---- kernel_socket.c | 9 +++++---- route.c | 26 ++++++++++++++++++++------ 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/kernel.h b/kernel.h index 94bcb4fb..56060d1a 100644 --- a/kernel.h +++ b/kernel.h @@ -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); diff --git a/kernel_netlink.c b/kernel_netlink.c index 6ee991d8..5de9cc04 100644 --- a/kernel_netlink.c +++ b/kernel_netlink.c @@ -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; @@ -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; diff --git a/kernel_socket.c b/kernel_socket.c index 9ffa2f53..f96e6b5c 100644 --- a/kernel_socket.c +++ b/kernel_socket.c @@ -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; @@ -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; } @@ -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); } diff --git a/route.c b/route.c index cf2dcedf..b316ef7a 100644 --- a/route.c +++ b/route.c @@ -439,10 +439,12 @@ 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; @@ -456,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 @@ -491,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; @@ -517,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; @@ -551,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; @@ -581,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;