babeld: send events via ubus (#633)
authorPolynomdivision <vincent@systemli.org>
Mon, 1 Feb 2021 14:26:44 +0000 (15:26 +0100)
committerGitHub <noreply@github.com>
Mon, 1 Feb 2021 14:26:44 +0000 (15:26 +0100)
* babeld: send events via ubus

Send a notification via the ubus bus if we experience any changes in
neighbours, routes or xroutes.

The format looks like this:
  {route,xroute,neighbour}.add: Object was added
  {route,xroute,neighbour}.change: Object was changed
  {route,xroute,neighbour}.flush: Object was flushed

If ubus_bindings is turned off, it will minimally effect performance,
since only an if-statement has to be evaluated.
If no subscriber is available, it will minimally change the performance,
since only an if-statmenet that checks for subscribers has to be
evaluated.

Signed-off-by: Nick Hainke <vincent@systemli.org>
babeld/Makefile
babeld/patches/600-add-ubus.patch
babeld/src/ubus.c
babeld/src/ubus.h

index 43d9133e4865dfc3f2b73830541ea6fd094018d0..9b618c21e41e2ff11badef76abd490aac3f4145c 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=babeld
 PKG_VERSION:=1.9.2
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
index 7ffa47e87d4972721e8ea33d2f0c79dde066ddd8..956ec66bde0e566b000f20e23168df2f89969854 100644 (file)
          else
              abort();
      } else if(strcmp(token, "protocol-group") == 0) {
+--- a/local.c
++++ b/local.c
+@@ -42,6 +42,8 @@ THE SOFTWARE.
+ #include "local.h"
+ #include "version.h"
++#include "ubus.h"
++
+ int local_server_socket = -1;
+ struct local_socket local_sockets[MAX_LOCAL_SOCKETS];
+ int num_local_sockets = 0;
+@@ -80,7 +82,7 @@ write_timeout(int fd, const void *buf, i
+     }
+ }
+-static const char *
++const char *
+ local_kind(int kind)
+ {
+     switch(kind) {
+@@ -191,6 +193,8 @@ local_notify_neighbour(struct neighbour
+         if(local_sockets[i].monitor)
+             local_notify_neighbour_1(&local_sockets[i], neigh, kind);
+     }
++    if(ubus_bindings)
++          ubus_notify_neighbour(neigh, kind);
+ }
+ static void
+@@ -228,6 +232,8 @@ local_notify_xroute(struct xroute *xrout
+         if(local_sockets[i].monitor)
+             local_notify_xroute_1(&local_sockets[i], xroute, kind);
+     }
++    if(ubus_bindings)
++          ubus_notify_xroute(xroute, kind);
+ }
+ static void
+@@ -273,6 +279,8 @@ local_notify_route(struct babel_route *r
+         if(local_sockets[i].monitor)
+             local_notify_route_1(&local_sockets[i], route, kind);
+     }
++    if(ubus_bindings)
++          ubus_notify_route(route, kind);
+ }
+ static void
+--- a/local.h
++++ b/local.h
+@@ -55,3 +55,4 @@ int local_read(struct local_socket *s);
+ int local_header(struct local_socket *s);
+ struct local_socket *local_socket_create(int fd);
+ void local_socket_destroy(int i);
++const char * local_kind(int kind);
index 5bec96fd3088e8f0c403a9fe568ed1c39bad78d5..d1909c7d8afd3340272e2d650d3724cca8fdde5f 100644 (file)
@@ -87,7 +87,8 @@ static void babeld_add_xroute_buf(struct xroute *xroute, struct blob_buf *b) {
   blobmsg_close_table(b, prefix);
 }
 
-// Sends an exported routes message on ubus socket, splitting apart IPv4 and IPv6 routes.
+// Sends an exported routes message on ubus socket, splitting apart IPv4 and
+// IPv6 routes.
 static void babeld_ubus_get_xroutes(struct ubus_context *ctx_local,
                                     struct ubus_object *obj,
                                     struct ubus_request_data *req,
@@ -187,7 +188,8 @@ static void babeld_add_route_buf(struct babel_route *route,
   blobmsg_close_table(b, prefix);
 }
 
-// Sends received routes message on ubus socket, splitting apart IPv4 and IPv6 routes.
+// Sends received routes message on ubus socket, splitting apart IPv4 and IPv6
+// routes.
 static void babeld_ubus_get_routes(struct ubus_context *ctx_local,
                                    struct ubus_object *obj,
                                    struct ubus_request_data *req,
@@ -259,7 +261,8 @@ static void babeld_add_neighbour_buf(struct neighbour *neigh,
   blobmsg_close_table(b, neighbour);
 }
 
-// Sends neighbours message on ubus socket, splitting apart IPv4 and IPv6 neighbours.
+// Sends neighbours message on ubus socket, splitting apart IPv4 and IPv6
+// neighbours.
 static void babeld_ubus_get_neighbours(struct ubus_context *ctx_local,
                                        struct ubus_object *obj,
                                        struct ubus_request_data *req,
@@ -342,7 +345,8 @@ static bool ubus_init_object() {
   return true;
 }
 
-// Initializes the global ubus context, connecting to the bus to be able to receive and send messages.
+// Initializes the global ubus context, connecting to the bus to be able to
+// receive and send messages.
 static bool babeld_ubus_init(void) {
   if (shared_ctx)
     return true;
@@ -354,6 +358,63 @@ static bool babeld_ubus_init(void) {
   return true;
 }
 
+void ubus_notify_route(struct babel_route *route, int kind) {
+  struct blob_buf b = {0};
+  char method[50]; // possible methods are route.change, route.add, route.flush
+
+  if (!babeld_object.has_subscribers)
+    return;
+
+  if (!route)
+    return;
+
+  if (!shared_ctx)
+    return;
+
+  blob_buf_init(&b, 0);
+  babeld_add_route_buf(route, &b);
+  snprintf(method, sizeof(method), "route.%s", local_kind(kind));
+  ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
+}
+
+void ubus_notify_xroute(struct xroute *xroute, int kind) {
+  struct blob_buf b = {0};
+  char method[50]; // possible methods are xroute.change, xroute.add, xroute.flush
+
+  if (!babeld_object.has_subscribers)
+    return;
+
+  if (!xroute)
+    return;
+
+  if (!shared_ctx)
+    return;
+
+  blob_buf_init(&b, 0);
+  babeld_add_xroute_buf(xroute, &b);
+  snprintf(method, sizeof(method), "xroute.%s", local_kind(kind));
+  ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
+}
+
+void ubus_notify_neighbour(struct neighbour *neigh, int kind) {
+  struct blob_buf b = {0};
+  char method[50]; // possible methods are neigh.change, neigh.add, neigh.flush
+
+  if (!babeld_object.has_subscribers)
+    return;
+
+  if (!neigh)
+    return;
+
+  if (!shared_ctx)
+    return;
+
+  blob_buf_init(&b, 0);
+  babeld_add_neighbour_buf(neigh, &b);
+  snprintf(method, sizeof(method), "neigh.%s", local_kind(kind));
+  ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
+}
+
 void babeld_ubus_receive(fd_set *readfds) {
   if (!shared_ctx)
     return;
index 84be97f1f4cefe0e22e0ea76923bf3cc6c8f5145..66ef997a0bb91bb01f48f448f9fb55fab9acfe91 100644 (file)
@@ -1,13 +1,24 @@
 /*
     IPC integration of babeld with OpenWrt.
-    
+
     The ubus interface offers following functions:
     - get_info
     - get_neighbours
     - get_xroutes
     - get_routes
-    
+
     All output is divided into IPv4 and IPv6.
+
+    Ubus notifications are sent if we receive updates for
+    - xroutes
+    - routes
+    - neighbours
+
+    The format is:
+    - {route,xroute,neighbour}.add: Object was added
+    - {route,xroute,neighbour}.change: Object was changed
+    - {route,xroute,neighbour}.flush: Object was flushed
+
 */
 
 #include <libubus.h>
@@ -28,18 +39,49 @@ bool babeld_add_ubus();
  * Add ubus socket to given filedescriptor set.
  *
  * We need to check repeatedly if the ubus socket has something to read.
- * The functions allows to add the ubus socket to the normal while(1)-loop of babeld.
+ * The functions allows to add the ubus socket to the normal while(1)-loop of
+ * babeld.
  *
  * @param readfs: the filedescriptor set
  * @param maxfd: the current maximum file descriptor
  * @return the maximum file descriptor
  */
-int babeld_ubus_add_read_sock(fd_set* readfds, int maxfd);
-
+int babeld_ubus_add_read_sock(fd_set *readfds, int maxfd);
 
 /**
  * Check and process ubus socket.
  *
- * If the ubus-socket signals that data is available, the ubus_handle_event is called.
+ * If the ubus-socket signals that data is available, the ubus_handle_event is
+ * called.
+ */
+void babeld_ubus_receive(fd_set *readfds);
+
+/***
+ * Notify the ubus bus that a new xroute is received.
+ *
+ * If a new xroute is received or changed, we will notify subscribers.
+ *
+ * @param xroute: xroute that experienced some change
+ * @param kind: kind that describes if we have a flush, add or change
+ */
+void ubus_notify_xroute(struct xroute *xroute, int kind);
+
+/***
+ * Notify the ubus bus that a new route is received.
+ *
+ * If a new route is received or changed, we will notify subscribers.
+ *
+ * @param route: route that experienced some change
+ * @param kind: kind that describes if we have a flush, add or change
+ */
+void ubus_notify_route(struct babel_route *route, int kind);
+
+/***
+ * Notify the ubus bus that a new neighbour is received.
+ *
+ * If a new neighbour is received or changed, we will notify subscribers.
+ *
+ * @param neigh: neighbour that experienced some change
+ * @param kind: kind that describes if we have a flush, add or change
  */
-void babeld_ubus_receive(fd_set* readfds);
+void ubus_notify_neighbour(struct neighbour *neigh, int kind);