babeld: add add_filter function
You can define filter functions in babeld by: in if eth0 metric 128 This commit adds the ubus equivalent to dynamically add filter on runtime: ubus call babeld add_filter '{"ifname":"eth0", "type":"input", "metric":128}' Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
parent
e3c6842923
commit
a618159d33
4 changed files with 180 additions and 3 deletions
|
@ -0,0 +1,116 @@
|
||||||
|
From 7c053fe7584b7b4fe4effc09624ae620304d6717 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Juliusz Chroboczek <jch@irif.fr>
|
||||||
|
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,
|
|
@ -57,7 +57,7 @@
|
||||||
static struct filter *input_filters = NULL;
|
static struct filter *input_filters = NULL;
|
||||||
static struct filter *output_filters = NULL;
|
static struct filter *output_filters = NULL;
|
||||||
static struct filter *redistribute_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, "daemonise") == 0 ||
|
||||||
strcmp(token, "skip-kernel-setup") == 0 ||
|
strcmp(token, "skip-kernel-setup") == 0 ||
|
||||||
strcmp(token, "ipv6-subtrees") == 0 ||
|
strcmp(token, "ipv6-subtrees") == 0 ||
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
int b;
|
int b;
|
||||||
c = getbool(c, &b, gnc, closure);
|
c = getbool(c, &b, gnc, closure);
|
||||||
if(c < -1)
|
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;
|
has_ipv6_subtrees = b;
|
||||||
else if(strcmp(token, "reflect-kernel-metric") == 0)
|
else if(strcmp(token, "reflect-kernel-metric") == 0)
|
||||||
reflect_kernel_metric = b;
|
reflect_kernel_metric = b;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#include <libubus.h>
|
|
||||||
#include <libubox/blob.h>
|
#include <libubox/blob.h>
|
||||||
#include <libubox/blobmsg.h>
|
#include <libubox/blobmsg.h>
|
||||||
#include <libubox/list.h>
|
#include <libubox/list.h>
|
||||||
|
#include <libubus.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
@ -63,6 +63,60 @@ static const struct blobmsg_policy interface_policy[__INTERFACE_MAX] = {
|
||||||
[INTERFACE_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING},
|
[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).
|
// Adds an inteface (ubus equivalent to "interface"-function).
|
||||||
static int babeld_ubus_add_interface(struct ubus_context *ctx_local,
|
static int babeld_ubus_add_interface(struct ubus_context *ctx_local,
|
||||||
struct ubus_object *obj,
|
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.
|
// List of functions we expose via the ubus bus.
|
||||||
static const struct ubus_method babeld_methods[] = {
|
static const struct ubus_method babeld_methods[] = {
|
||||||
UBUS_METHOD("add_interface", babeld_ubus_add_interface, interface_policy),
|
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_info", babeld_ubus_babeld_info),
|
||||||
UBUS_METHOD_NOARG("get_xroutes", babeld_ubus_get_xroutes),
|
UBUS_METHOD_NOARG("get_xroutes", babeld_ubus_get_xroutes),
|
||||||
UBUS_METHOD_NOARG("get_routes", babeld_ubus_get_routes),
|
UBUS_METHOD_NOARG("get_routes", babeld_ubus_get_routes),
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
IPC integration of babeld with OpenWrt.
|
IPC integration of babeld with OpenWrt.
|
||||||
|
|
||||||
The ubus interface offers following functions:
|
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"}'
|
- add_interface '{"ifname":"eth0"}'
|
||||||
- get_info
|
- get_info
|
||||||
- get_neighbours
|
- get_neighbours
|
||||||
|
|
Loading…
Reference in a new issue