diff --git a/babeld/patches/000-export-add-filters-and-simplify-interface.patch b/babeld/patches/000-export-add-filters-and-simplify-interface.patch new file mode 100644 index 0000000..90bee74 --- /dev/null +++ b/babeld/patches/000-export-add-filters-and-simplify-interface.patch @@ -0,0 +1,116 @@ +From 7c053fe7584b7b4fe4effc09624ae620304d6717 Mon Sep 17 00:00:00 2001 +From: Juliusz Chroboczek +Date: Tue, 29 Mar 2022 19:26:50 +0200 +Subject: [PATCH] Export add_filters and simplify interface. + +--- + configuration.c | 32 +++++++++++++++++++++++++------- + configuration.h | 6 ++++++ + 2 files changed, 31 insertions(+), 7 deletions(-) + +--- a/configuration.c ++++ b/configuration.c +@@ -693,9 +693,26 @@ parse_ifconf(int c, gnc_t gnc, void *clo + return -2; + } + +-static void +-add_filter(struct filter *filter, struct filter **filters) ++int ++add_filter(struct filter *filter, int type) + { ++ struct filter **filters; ++ switch(type) { ++ case FILTER_TYPE_INPUT: ++ filters = &input_filters; ++ break; ++ case FILTER_TYPE_OUTPUT: ++ filters = &output_filters; ++ break; ++ case FILTER_TYPE_REDISTRIBUTE: ++ filters = &redistribute_filters; ++ break; ++ case FILTER_TYPE_INSTALL: ++ filters = &install_filters; ++ break; ++ default: ++ return -1; ++ } + if(*filters == NULL) { + filter->next = NULL; + *filters = filter; +@@ -707,6 +724,7 @@ add_filter(struct filter *filter, struct + filter->next = NULL; + f->next = filter; + } ++ return 1; + } + + static void +@@ -1012,7 +1030,7 @@ parse_config_line(int c, gnc_t gnc, void + c = parse_filter(c, gnc, closure, &filter); + if(c < -1) + goto fail; +- add_filter(filter, &input_filters); ++ add_filter(filter, FILTER_TYPE_INPUT); + } else if(strcmp(token, "out") == 0) { + struct filter *filter; + if(config_finalised) +@@ -1020,7 +1038,7 @@ parse_config_line(int c, gnc_t gnc, void + c = parse_filter(c, gnc, closure, &filter); + if(c < -1) + goto fail; +- add_filter(filter, &output_filters); ++ add_filter(filter, FILTER_TYPE_OUTPUT); + } else if(strcmp(token, "redistribute") == 0) { + struct filter *filter; + if(config_finalised) +@@ -1028,7 +1046,7 @@ parse_config_line(int c, gnc_t gnc, void + c = parse_filter(c, gnc, closure, &filter); + if(c < -1) + goto fail; +- add_filter(filter, &redistribute_filters); ++ add_filter(filter, FILTER_TYPE_REDISTRIBUTE); + } else if(strcmp(token, "install") == 0) { + struct filter *filter; + if(config_finalised) +@@ -1036,7 +1054,7 @@ parse_config_line(int c, gnc_t gnc, void + c = parse_filter(c, gnc, closure, &filter); + if(c < -1) + goto fail; +- add_filter(filter, &install_filters); ++ add_filter(filter, FILTER_TYPE_INSTALL); + } else if(strcmp(token, "interface") == 0) { + struct interface_conf *if_conf; + c = parse_ifconf(c, gnc, closure, &if_conf); +@@ -1360,7 +1378,7 @@ finalise_config() + filter->proto = RTPROT_BABEL_LOCAL; + filter->plen_le = 128; + filter->src_plen_le = 128; +- add_filter(filter, &redistribute_filters); ++ add_filter(filter, FILTER_TYPE_REDISTRIBUTE); + + while(interface_confs) { + struct interface_conf *if_conf; +--- a/configuration.h ++++ b/configuration.h +@@ -29,6 +29,11 @@ THE SOFTWARE. + #define CONFIG_ACTION_UNMONITOR 4 + #define CONFIG_ACTION_NO 5 + ++#define FILTER_TYPE_INPUT 0 ++#define FILTER_TYPE_OUTPUT 1 ++#define FILTER_TYPE_REDISTRIBUTE 2 ++#define FILTER_TYPE_INSTALL 3 ++ + struct filter_result { + unsigned int add_metric; /* allow = 0, deny = INF, metric = <0..INF> */ + unsigned char *src_prefix; +@@ -60,6 +65,7 @@ void flush_ifconf(struct interface_conf + + int parse_config_from_file(const char *filename, int *line_return); + int parse_config_from_string(char *string, int n, const char **message_return); ++int add_filter(struct filter *filter, int type); + void renumber_filters(void); + + int input_filter(const unsigned char *id, diff --git a/babeld/patches/600-add-ubus.patch b/babeld/patches/600-add-ubus.patch index 252a299..351d559 100644 --- a/babeld/patches/600-add-ubus.patch +++ b/babeld/patches/600-add-ubus.patch @@ -57,7 +57,7 @@ static struct filter *input_filters = NULL; static struct filter *output_filters = NULL; static struct filter *redistribute_filters = NULL; -@@ -849,7 +851,8 @@ parse_option(int c, gnc_t gnc, void *clo +@@ -867,7 +869,8 @@ parse_option(int c, gnc_t gnc, void *clo strcmp(token, "daemonise") == 0 || strcmp(token, "skip-kernel-setup") == 0 || strcmp(token, "ipv6-subtrees") == 0 || @@ -67,7 +67,7 @@ int b; c = getbool(c, &b, gnc, closure); if(c < -1) -@@ -867,6 +870,8 @@ parse_option(int c, gnc_t gnc, void *clo +@@ -885,6 +888,8 @@ parse_option(int c, gnc_t gnc, void *clo has_ipv6_subtrees = b; else if(strcmp(token, "reflect-kernel-metric") == 0) reflect_kernel_metric = b; diff --git a/babeld/src/ubus.c b/babeld/src/ubus.c index 2066994..dec71a1 100644 --- a/babeld/src/ubus.c +++ b/babeld/src/ubus.c @@ -2,10 +2,10 @@ #include #include -#include #include #include #include +#include #include #include @@ -63,6 +63,60 @@ static const struct blobmsg_policy interface_policy[__INTERFACE_MAX] = { [INTERFACE_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING}, }; +// Definition of filter function enums (to be used with ubox's blobmsg +// helpers). +enum { FILTER_IFNAME, FILTER_TYPE, FILTER_METRIC, __FILTER_MAX }; + +// Definition of filter parsing (to be used with ubox's blobmsg helpers). +static const struct blobmsg_policy filter_policy[__FILTER_MAX] = { + [FILTER_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING}, + [FILTER_TYPE] = {"type", BLOBMSG_TYPE_INT32}, + [FILTER_METRIC] = {"metric", BLOBMSG_TYPE_INT32}, +}; + +// Adds a filter (ubus equivalent to "filter"-function). +static int babeld_ubus_add_filter(struct ubus_context *ctx_local, + struct ubus_object *obj, + struct ubus_request_data *req, + const char *method, struct blob_attr *msg) { + struct blob_attr *tb[__FILTER_MAX]; + struct blob_buf b = {0}; + struct filter *filter = NULL; + char *ifname; + int metric, type; + + blobmsg_parse(filter_policy, __FILTER_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[FILTER_IFNAME]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (!tb[FILTER_TYPE]) + return UBUS_STATUS_INVALID_ARGUMENT; + + type = blobmsg_get_u32(tb[FILTER_TYPE]); + + if (tb[FILTER_METRIC]) + metric = blobmsg_get_u32(tb[FILTER_METRIC]); + + filter = calloc(1, sizeof(struct filter)); + if (filter == NULL) + return UBUS_STATUS_UNKNOWN_ERROR; + + filter->af = AF_INET6; + filter->proto = 0; + filter->plen_le = 128; + filter->src_plen_le = 128; + filter->action.add_metric = metric; + + ifname = blobmsg_get_string(tb[FILTER_IFNAME]); + filter->ifname = strdup(ifname); + filter->ifindex = if_nametoindex(filter->ifname); + + add_filter(filter, type); + + return UBUS_STATUS_OK; +} + // Adds an inteface (ubus equivalent to "interface"-function). static int babeld_ubus_add_interface(struct ubus_context *ctx_local, struct ubus_object *obj, @@ -364,6 +418,7 @@ static int babeld_ubus_get_neighbours(struct ubus_context *ctx_local, // List of functions we expose via the ubus bus. static const struct ubus_method babeld_methods[] = { UBUS_METHOD("add_interface", babeld_ubus_add_interface, interface_policy), + UBUS_METHOD("add_filter", babeld_ubus_add_filter, filter_policy), UBUS_METHOD_NOARG("get_info", babeld_ubus_babeld_info), UBUS_METHOD_NOARG("get_xroutes", babeld_ubus_get_xroutes), UBUS_METHOD_NOARG("get_routes", babeld_ubus_get_routes), diff --git a/babeld/src/ubus.h b/babeld/src/ubus.h index 951fee5..08aeb52 100644 --- a/babeld/src/ubus.h +++ b/babeld/src/ubus.h @@ -2,6 +2,12 @@ IPC integration of babeld with OpenWrt. The ubus interface offers following functions: + - add_filter '{"ifname":"eth0", "type":0, "metric":5000}' + type: + 0: FILTER_TYPE_INPUT + 1: FILTER_TYPE_OUTPUT + 2: FILTER_TYPE_REDISTRIBUTE + 3: FILTER_TYPE_INSTALL - add_interface '{"ifname":"eth0"}' - get_info - get_neighbours