Implement code to pass the flowspec config over to the RDE. The parent
authorclaudio <claudio@openbsd.org>
Wed, 19 Apr 2023 07:12:22 +0000 (07:12 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 19 Apr 2023 07:12:22 +0000 (07:12 +0000)
process tracks which prefixes are added / removed and issues the
corresponding imsg calls.
Right now the RDE does nothing with the received information.
OK tb@

usr.sbin/bgpd/bgpd.c
usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/rde.c

index b1f5c0e..1d72bd8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.c,v 1.257 2023/02/14 15:33:46 claudio Exp $ */
+/*     $OpenBSD: bgpd.c,v 1.258 2023/04/19 07:12:22 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -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 */
 
@@ -656,6 +657,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) {
                SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry);
index eb59cb3..b410d47 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.472 2023/04/18 12:11:27 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.473 2023/04/19 07:12:22 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -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 e3f6891..343126e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.601 2023/04/13 15:51:16 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.602 2023/04/19 07:12:22 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -102,6 +102,10 @@ void                network_delete(struct network_config *);
 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 *ibuf)
        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 *ibuf)
                        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))
@@ -4489,6 +4563,20 @@ network_flush_upcall(struct rib_entry *re, void *ptr)
                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 */
 void
 rde_shutdown(void)