Cleanup and fix the network code.
authorclaudio <claudio@openbsd.org>
Wed, 20 Jul 2022 12:43:27 +0000 (12:43 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 20 Jul 2022 12:43:27 +0000 (12:43 +0000)
- introduce network_free() to properly free a network struct including
  the possible rtlabel reference.
- change expand_networks() and the reload code to not only expand the
  main network config but also the network configs inside L3VPN sections.
- adjust reload logic to properly match any kind of network struct.
  Up until now rtlabel and priority network statememnts were not correctly
  reloaded.
OK tb@

usr.sbin/bgpd/bgpd.c
usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/config.c
usr.sbin/bgpd/kroute.c

index 2d97a7a..cb42e5d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.c,v 1.248 2022/06/23 13:09:03 claudio Exp $ */
+/*     $OpenBSD: bgpd.c,v 1.249 2022/07/20 12:43:27 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -599,7 +599,9 @@ send_config(struct bgpd_config *conf)
 
        reconfpending = 3;      /* one per child */
 
-       expand_networks(conf);
+       expand_networks(conf, &conf->networks);
+       SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry)
+               expand_networks(conf, &vpn->net_l);
 
        cflags = conf->flags;
 
index c7caaea..54c0a23 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.441 2022/07/11 17:08:21 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.442 2022/07/20 12:43:27 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -476,8 +476,8 @@ struct network_config {
        struct filter_set_head   attrset;
        char                     psname[SET_NAME_LEN];
        uint64_t                 rd;
-       uint16_t                 rtlabel;
        enum network_type        type;
+       uint16_t                 rtlabel;
        uint8_t                  prefixlen;
        uint8_t                  priority;
        uint8_t                  old;   /* used for reloading */
@@ -1275,6 +1275,7 @@ int       control_imsg_relay(struct imsg *);
 /* config.c */
 struct bgpd_config     *new_config(void);
 void           copy_config(struct bgpd_config *, struct bgpd_config *);
+void           network_free(struct network *);
 void           free_l3vpns(struct l3vpn_head *);
 void           free_config(struct bgpd_config *);
 void           free_prefixsets(struct prefixset_head *);
@@ -1285,7 +1286,7 @@ void              free_rtrs(struct rtr_config_head *);
 void           filterlist_free(struct filter_head *);
 int            host(const char *, struct bgpd_addr *, uint8_t *);
 uint32_t       get_bgpid(void);
-void           expand_networks(struct bgpd_config *);
+void           expand_networks(struct bgpd_config *, struct network_head *);
 RB_PROTOTYPE(prefixset_tree, prefixset_item, entry, prefixset_cmp);
 int            roa_cmp(struct roa *, struct roa *);
 RB_PROTOTYPE(roa_tree, roa, entry, roa_cmp);
index f4f767f..035252e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.102 2022/06/05 12:43:13 claudio Exp $ */
+/*     $OpenBSD: config.c,v 1.103 2022/07/20 12:43:27 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -85,6 +85,14 @@ copy_config(struct bgpd_config *to, struct bgpd_config *from)
        to->fib_priority = from->fib_priority;
 }
 
+void
+network_free(struct network *n)
+{
+       rtlabel_unref(n->net.rtlabel);
+       filterset_free(&n->net.attrset);
+       free(n);
+}
+
 void
 free_networks(struct network_head *networks)
 {
@@ -92,8 +100,7 @@ free_networks(struct network_head *networks)
 
        while ((n = TAILQ_FIRST(networks)) != NULL) {
                TAILQ_REMOVE(networks, n, entry);
-               filterset_free(&n->net.attrset);
-               free(n);
+               network_free(n);
        }
 }
 
@@ -431,7 +438,8 @@ host_ip(const char *s, struct bgpd_addr *h, uint8_t *len)
                sa2addr(res->ai_addr, h, NULL);
                freeaddrinfo(res);
        } else {        /* ie. for 10/8 parsing */
-               if ((bits = inet_net_pton(AF_INET, s, &h->v4, sizeof(h->v4))) == -1)
+               if ((bits = inet_net_pton(AF_INET, s, &h->v4,
+                   sizeof(h->v4))) == -1)
                        return (0);
                *len = bits;
                h->aid = AID_INET;
@@ -502,10 +510,9 @@ prepare_listeners(struct bgpd_config *conf)
 }
 
 void
-expand_networks(struct bgpd_config *c)
+expand_networks(struct bgpd_config *c, struct network_head *nw)
 {
        struct network          *n, *m, *tmp;
-       struct network_head     *nw = &c->networks;
        struct prefixset        *ps;
        struct prefixset_item   *psi;
 
@@ -527,8 +534,7 @@ expand_networks(struct bgpd_config *c)
                                    &m->net.attrset);
                                TAILQ_INSERT_TAIL(nw, m, entry);
                        }
-                       filterset_free(&n->net.attrset);
-                       free(n);
+                       network_free(n);
                }
        }
 }
index 6e855fc..08312ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kroute.c,v 1.274 2022/07/19 10:26:19 claudio Exp $ */
+/*     $OpenBSD: kroute.c,v 1.275 2022/07/20 12:43:27 claudio Exp $ */
 
 /*
  * Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
@@ -141,7 +141,6 @@ int kr4_delete(struct ktable *, struct kroute_full *);
 int    kr6_delete(struct ktable *, struct kroute_full *);
 int    krVPN4_delete(struct ktable *, struct kroute_full *);
 int    krVPN6_delete(struct ktable *, struct kroute_full *);
-void   kr_net_delete(struct network *);
 int    kr_net_match(struct ktable *, struct network_config *, uint16_t, int);
 struct network *kr_net_find(struct ktable *, struct network *);
 void   kr_net_clear(struct ktable *);
@@ -1243,13 +1242,6 @@ kr_ifinfo(char *ifname)
                }
 }
 
-void
-kr_net_delete(struct network *n)
-{
-       filterset_free(&n->net.attrset);
-       free(n);
-}
-
 static int
 kr_net_redist_add(struct ktable *kt, struct network_config *net,
     struct filter_set_head *attr, int dynamic)
@@ -1370,7 +1362,9 @@ kr_net_find(struct ktable *kt, struct network *n)
        TAILQ_FOREACH(xn, &kt->krn, entry) {
                if (n->net.type != xn->net.type ||
                    n->net.prefixlen != xn->net.prefixlen ||
-                   n->net.rd != xn->net.rd)
+                   n->net.rd != xn->net.rd ||
+                   n->net.rtlabel != xn->net.rtlabel ||
+                   n->net.priority != xn->net.priority)
                        continue;
                if (memcmp(&n->net.prefix, &xn->net.prefix,
                    sizeof(n->net.prefix)) == 0)
@@ -1397,7 +1391,7 @@ kr_net_reload(u_int rtableid, uint64_t rd, struct network_head *nh)
                        xn->net.old = 0;
                        filterset_free(&xn->net.attrset);
                        filterset_move(&n->net.attrset, &xn->net.attrset);
-                       kr_net_delete(n);
+                       network_free(n);
                } else
                        TAILQ_INSERT_TAIL(&kt->krn, n, entry);
        }
@@ -1412,7 +1406,7 @@ kr_net_clear(struct ktable *kt)
                TAILQ_REMOVE(&kt->krn, n, entry);
                if (n->net.type == NETWORK_DEFAULT)
                        kr_net_redist_del(kt, &n->net, 0);
-               kr_net_delete(n);
+               network_free(n);
        }
 }
 
@@ -1556,7 +1550,7 @@ ktable_postload(void)
                                TAILQ_REMOVE(&kt->krn, n, entry);
                                if (n->net.type == NETWORK_DEFAULT)
                                        kr_net_redist_del(kt, &n->net, 0);
-                               kr_net_delete(n);
+                               network_free(n);
                        }
                }
        }