This diff does nothing else than prep for the possibility to use
struct rde_aspath objects that sit on the stack instead of being
malloc()-ed. Currently a lot of copies are created when filter modify
aspath entries when in practice it is not needed.
The main changes are:
- path_copy() gets a second argument (dst, src)
- a new function path_prep() is introduced to initialize a aspath object
Additionally some const where added to the *_copy functions to make it
more obvious which is the source and target. Also the pftable_ref and
rtlabel_ref functions return now the id so you can do:
rttable_id = rttable_ref(another_id)
Which is nicer.
This does not yet reduce the copy overhead. Working on that next.
--
:wq Claudio
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.319
diff -u -p -r1.319 bgpd.h
--- bgpd.h 25 Jun 2018 14:28:33 -0000 1.319
+++ bgpd.h 29 Jun 2018 10:01:13 -0000
@@ -1110,11 +1110,11 @@ void rib_ref(u_int16_t);
u_int16_t rtlabel_name2id(const char *);
const char *rtlabel_id2name(u_int16_t);
void rtlabel_unref(u_int16_t);
-void rtlabel_ref(u_int16_t);
+u_int16_t rtlabel_ref(u_int16_t);
u_int16_t pftable_name2id(const char *);
const char *pftable_id2name(u_int16_t);
void pftable_unref(u_int16_t);
-void pftable_ref(u_int16_t);
+u_int16_t pftable_ref(u_int16_t);
/* parse.y */
int cmdline_symset(char *);
Index: name2id.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/name2id.c,v
retrieving revision 1.9
diff -u -p -r1.9 name2id.c
--- name2id.c 4 Jun 2009 04:46:42 -0000 1.9
+++ name2id.c 29 Jun 2018 10:03:48 -0000
@@ -41,7 +41,7 @@ TAILQ_HEAD(n2id_labels, n2id_label);
u_int16_t _name2id(struct n2id_labels *, const char *);
const char *_id2name(struct n2id_labels *, u_int16_t);
void _unref(struct n2id_labels *, u_int16_t);
-void _ref(struct n2id_labels *, u_int16_t);
+u_int16_t _ref(struct n2id_labels *, u_int16_t);
struct n2id_labels rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
struct n2id_labels pftable_labels = TAILQ_HEAD_INITIALIZER(pftable_labels);
@@ -64,10 +64,10 @@ rtlabel_unref(u_int16_t id)
_unref(&rt_labels, id);
}
-void
+u_int16_t
rtlabel_ref(u_int16_t id)
{
- _ref(&rt_labels, id);
+ return (_ref(&rt_labels, id));
}
u_int16_t
@@ -88,10 +88,10 @@ pftable_unref(u_int16_t id)
_unref(&pftable_labels, id);
}
-void
+u_int16_t
pftable_ref(u_int16_t id)
{
- _ref(&pftable_labels, id);
+ return (_ref(&pftable_labels, id));
}
u_int16_t
@@ -180,17 +180,20 @@ _unref(struct n2id_labels *head, u_int16
}
}
-void
+u_int16_t
_ref(struct n2id_labels *head, u_int16_t id)
{
struct n2id_label *label;
if (id == 0)
- return;
+ return (0);
TAILQ_FOREACH(label, head, entry)
if (label->id == id) {
++label->ref;
- break;
+ return (id);
}
+
+ /* id not found, treat like no id */
+ return (0);
}
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.174
diff -u -p -r1.174 rde.h
--- rde.h 28 Jun 2018 09:54:48 -0000 1.174
+++ rde.h 29 Jun 2018 10:11:27 -0000
@@ -351,7 +351,7 @@ void attr_shutdown(void);
int attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t,
void *, u_int16_t);
struct attr *attr_optget(const struct rde_aspath *, u_int8_t);
-void attr_copy(struct rde_aspath *, struct rde_aspath *);
+void attr_copy(struct rde_aspath *, const struct rde_aspath *);
int attr_compare(struct rde_aspath *, struct rde_aspath *);
void attr_freeall(struct rde_aspath *);
void attr_free(struct rde_aspath *, struct attr *);
@@ -473,7 +473,8 @@ void path_remove(struct rde_aspath *);
u_int32_t path_remove_stale(struct rde_aspath *, u_int8_t);
void path_destroy(struct rde_aspath *);
int path_empty(struct rde_aspath *);
-struct rde_aspath *path_copy(struct rde_aspath *);
+struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *);
+struct rde_aspath *path_prep(struct rde_aspath *);
struct rde_aspath *path_get(void);
void path_put(struct rde_aspath *);
Index: rde_attr.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
retrieving revision 1.101
diff -u -p -r1.101 rde_attr.c
--- rde_attr.c 2 Apr 2018 19:25:33 -0000 1.101
+++ rde_attr.c 29 Jun 2018 10:09:44 -0000
@@ -209,7 +209,7 @@ attr_optget(const struct rde_aspath *asp
}
void
-attr_copy(struct rde_aspath *t, struct rde_aspath *s)
+attr_copy(struct rde_aspath *t, const struct rde_aspath *s)
{
u_int8_t l;
Index: rde_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.93
diff -u -p -r1.93 rde_filter.c
--- rde_filter.c 28 Jun 2018 09:54:48 -0000 1.93
+++ rde_filter.c 29 Jun 2018 10:13:31 -0000
@@ -305,8 +305,7 @@ rde_apply_set(struct filter_set_head *sh
/* FALLTHROUGH */
case ACTION_PFTABLE_ID:
pftable_unref(asp->pftableid);
- asp->pftableid = set->action.id;
- pftable_ref(asp->pftableid);
+ asp->pftableid = pftable_ref(set->action.id);
break;
case ACTION_RTLABEL:
/* convert the route label to an id for faster access */
@@ -315,8 +314,7 @@ rde_apply_set(struct filter_set_head *sh
/* FALLTHROUGH */
case ACTION_RTLABEL_ID:
rtlabel_unref(asp->rtlabelid);
- asp->rtlabelid = set->action.id;
- rtlabel_ref(asp->rtlabelid);
+ asp->rtlabelid = rtlabel_ref(set->action.id);
break;
case ACTION_SET_ORIGIN:
asp->origin = set->action.origin;
@@ -1023,7 +1021,7 @@ rde_filter(struct filter_head *rules, st
if (asp != NULL && new != NULL) {
/* asp may get modified so create a copy */
if (*new == NULL) {
- *new = path_copy(asp);
+ *new = path_copy(path_get(), asp);
/* ... and use the copy from now on */
asp = *new;
}
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.164
diff -u -p -r1.164 rde_rib.c
--- rde_rib.c 28 Jun 2018 08:55:56 -0000 1.164
+++ rde_rib.c 29 Jun 2018 10:23:28 -0000
@@ -420,7 +420,7 @@ path_update(struct rib *rib, struct rde_
*/
if ((asp = path_lookup(nasp, peer)) == NULL) {
/* Path not available, create and link a new one. */
- asp = path_copy(nasp);
+ asp = path_copy(path_get(), nasp);
path_link(asp, peer);
}
@@ -638,46 +638,36 @@ path_link(struct rde_aspath *asp, struct
}
/*
- * copy asp to a new UNLINKED one mainly for filtering
+ * Copy asp to a new UNLINKED aspath
+ * On dst either path_get() or path_prep() had to be called before.
*/
struct rde_aspath *
-path_copy(struct rde_aspath *asp)
+path_copy(struct rde_aspath *dst, const struct rde_aspath *src)
{
- struct rde_aspath *nasp;
-
- nasp = path_get();
- nasp->aspath = asp->aspath;
- if (nasp->aspath != NULL) {
- nasp->aspath->refcnt++;
+ dst->aspath = src->aspath;
+ if (dst->aspath != NULL) {
+ dst->aspath->refcnt++;
rdemem.aspath_refs++;
}
- nasp->nexthop = nexthop_ref(asp->nexthop);
- nasp->med = asp->med;
- nasp->lpref = asp->lpref;
- nasp->weight = asp->weight;
- nasp->origin = asp->origin;
- nasp->rtlabelid = asp->rtlabelid;
- rtlabel_ref(nasp->rtlabelid);
- nasp->pftableid = asp->pftableid;
- pftable_ref(nasp->pftableid);
+ dst->nexthop = nexthop_ref(src->nexthop);
+ dst->med = src->med;
+ dst->lpref = src->lpref;
+ dst->weight = src->weight;
+ dst->origin = src->origin;
+ dst->rtlabelid = rtlabel_ref(src->rtlabelid);
+ dst->pftableid = pftable_ref(src->pftableid);
- nasp->flags = asp->flags & ~(F_ATTR_LINKED | F_ATTR_UPDATE);
- attr_copy(nasp, asp);
+ dst->flags = src->flags & ~(F_ATTR_LINKED | F_ATTR_UPDATE);
+ attr_copy(dst, src);
- return (nasp);
+ return (dst);
}
-/* alloc and initialize new entry. May not fail. */
+/* initialize or pepare an aspath for use */
struct rde_aspath *
-path_get(void)
+path_prep(struct rde_aspath *asp)
{
- struct rde_aspath *asp;
-
- asp = calloc(1, sizeof(*asp));
- if (asp == NULL)
- fatal("path_alloc");
- rdemem.path_cnt++;
-
+ memset(asp, 0, sizeof(*asp));
TAILQ_INIT(&asp->prefixes);
TAILQ_INIT(&asp->updates);
asp->origin = ORIGIN_INCOMPLETE;
@@ -687,6 +677,20 @@ path_get(void)
/* rtlabel = 0 */
return (asp);
+}
+
+/* alloc and initialize new entry. May not fail. */
+struct rde_aspath *
+path_get(void)
+{
+ struct rde_aspath *asp;
+
+ asp = malloc(sizeof(*asp));
+ if (asp == NULL)
+ fatal("path_get");
+ rdemem.path_cnt++;
+
+ return (path_prep(asp));
}
/* free an unlinked element */