This adds the needed bits to send the flowspec rules to the RDE.
The RDE just drops them on the ground for now.

-- 
:wq Claudio

Index: bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.257
diff -u -p -r1.257 bgpd.c
--- bgpd.c      14 Feb 2023 15:33:46 -0000      1.257
+++ bgpd.c      18 Apr 2023 15:15:36 -0000
@@ -598,6 +598,7 @@ send_config(struct bgpd_config *conf)
        struct roa              *roa;
        struct aspa_set         *aspa;
        struct rtr_config       *rtr;
+       struct flowspec_config  *f, *nf;
 
        reconfpending = 3;      /* one per child */
 
@@ -655,6 +656,26 @@ send_config(struct bgpd_config *conf)
 
        /* networks go via kroute to the RDE */
        kr_net_reload(conf->default_tableid, 0, &conf->networks);
+
+       /* flowspec goes directly to the RDE, also remove old objects */
+       RB_FOREACH_SAFE(f, flowspec_tree, &conf->flowspecs, nf) {
+               if (f->reconf_action != RECONF_DELETE) {
+                       if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_ADD, 0, 0, -1,
+                           f->flow, FLOWSPEC_SIZE + f->flow->len) == -1)
+                               return (-1);
+                       if (send_filterset(ibuf_rde, &f->attrset) == -1)
+                               return (-1);
+                       if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_DONE, 0, 0, -1,
+                           NULL, 0) == -1)
+                               return (-1);
+               } else {
+                       if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_REMOVE, 0, 0,
+                           -1, f->flow, FLOWSPEC_SIZE + f->flow->len) == -1)
+                               return (-1);
+                       RB_REMOVE(flowspec_tree, &conf->flowspecs, f);
+                       flowspec_free(f);
+               }
+       }
 
        /* prefixsets for filters in the RDE */
        while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) {
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.472
diff -u -p -r1.472 bgpd.h
--- bgpd.h      18 Apr 2023 12:11:27 -0000      1.472
+++ bgpd.h      18 Apr 2023 15:15:36 -0000
@@ -526,7 +526,7 @@ struct network {
 struct flowspec {
        uint16_t                len;
        uint8_t                 aid;
-       uint8_t                 pad;
+       uint8_t                 flags;
        uint8_t                 data[1];
 };
 #define FLOWSPEC_SIZE  (offsetof(struct flowspec, data))
@@ -613,6 +613,9 @@ enum imsg_type {
        IMSG_NETWORK_REMOVE,
        IMSG_NETWORK_FLUSH,
        IMSG_NETWORK_DONE,
+       IMSG_FLOWSPEC_ADD,
+       IMSG_FLOWSPEC_DONE,
+       IMSG_FLOWSPEC_REMOVE,
        IMSG_FILTER_SET,
        IMSG_SOCKET_CONN,
        IMSG_SOCKET_CONN_CTL,
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.601
diff -u -p -r1.601 rde.c
--- rde.c       13 Apr 2023 15:51:16 -0000      1.601
+++ rde.c       18 Apr 2023 15:18:19 -0000
@@ -102,6 +102,10 @@ void                network_delete(struct network_con
 static void     network_dump_upcall(struct rib_entry *, void *);
 static void     network_flush_upcall(struct rib_entry *, void *);
 
+void            flowspec_add(struct flowspec *, struct filterstate *,
+                   struct filter_set_head *);
+void            flowspec_delete(struct flowspec *);
+
 void            rde_shutdown(void);
 static int      ovs_match(struct prefix *, uint32_t);
 static int      avs_match(struct prefix *, uint32_t);
@@ -719,6 +723,7 @@ rde_dispatch_imsg_parent(struct imsgbuf 
        static struct rde_prefixset     *last_prefixset;
        static struct as_set    *last_as_set;
        static struct l3vpn     *vpn;
+       static struct flowspec  *curflow;
        struct imsg              imsg;
        struct mrt               xmrt;
        struct roa               roa;
@@ -817,6 +822,75 @@ rde_dispatch_imsg_parent(struct imsgbuf 
                        TAILQ_INIT(&netconf_p.attrset);
                        network_delete(&netconf_p);
                        break;
+               case IMSG_FLOWSPEC_ADD:
+                       if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
+                               log_warnx("rde_dispatch: wrong imsg len");
+                               break;
+                       }
+                       if (curflow != NULL) {
+                               log_warnx("rde_dispatch: "
+                                   "unexpected flowspec add");
+                               break;
+                       }
+                       curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+                       if (curflow == NULL)
+                               fatal(NULL);
+                       memcpy(curflow, imsg.data,
+                           imsg.hdr.len - IMSG_HEADER_SIZE);
+                       if (curflow->len + FLOWSPEC_SIZE !=
+                           imsg.hdr.len - IMSG_HEADER_SIZE) {
+                               free(curflow);
+                               curflow = NULL;
+                               log_warnx("rde_dispatch: wrong flowspec len");
+                               break;
+                       }
+                       break;
+               case IMSG_FLOWSPEC_DONE:
+                       if (curflow == NULL) {
+                               log_warnx("rde_dispatch: "
+                                   "unexpected flowspec done");
+                               break;
+                       }
+
+                       rde_filterstate_init(&state);
+                       asp = &state.aspath;
+                       asp->aspath = aspath_get(NULL, 0);
+                       asp->origin = ORIGIN_IGP;
+                       asp->flags = F_ATTR_ORIGIN | F_ATTR_ASPATH |
+                           F_ATTR_LOCALPREF | F_PREFIX_ANNOUNCED;
+
+                       flowspec_add(curflow, &state, &parent_set);
+                       rde_filterstate_clean(&state);
+                       filterset_free(&parent_set);
+                       free(curflow);
+                       curflow = NULL;
+                       break;
+               case IMSG_FLOWSPEC_REMOVE:
+                       if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
+                               log_warnx("rde_dispatch: wrong imsg len");
+                               break;
+                       }
+                       if (curflow != NULL) {
+                               log_warnx("rde_dispatch: "
+                                   "unexpected flowspec remove");
+                               break;
+                       }
+                       curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+                       if (curflow == NULL)
+                               fatal(NULL);
+                       memcpy(curflow, imsg.data,
+                           imsg.hdr.len - IMSG_HEADER_SIZE);
+                       if (curflow->len + FLOWSPEC_SIZE !=
+                           imsg.hdr.len - IMSG_HEADER_SIZE) {
+                               free(curflow);
+                               curflow = NULL;
+                               log_warnx("rde_dispatch: wrong flowspec len");
+                               break;
+                       }
+                       flowspec_delete(curflow);
+                       free(curflow);
+                       curflow = NULL;
+                       break;
                case IMSG_RECONF_CONF:
                        if (imsg.hdr.len - IMSG_HEADER_SIZE !=
                            sizeof(struct bgpd_config))
@@ -4487,6 +4561,20 @@ network_flush_upcall(struct rib_entry *r
        if (prefix_withdraw(rib_byid(RIB_ADJ_IN), peerself, 0, &addr,
            prefixlen) == 1)
                peerself->stats.prefix_cnt--;
+}
+
+/*
+ * flowspec announcement stuff
+ */
+void
+flowspec_add(struct flowspec *f, struct filterstate *state,
+    struct filter_set_head *attrset)
+{
+}
+
+void
+flowspec_delete(struct flowspec *f)
+{
 }
 
 /* clean up */

Reply via email to