summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-06-25 16:26:26 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-06-25 16:26:26 +0000
commitf7bfda00155de15887ece175b7bcd37c0a866376 (patch)
tree909430ec889f854f39c414aa0b473f85cf6c1494
parentf33027af4f5a8d1fd4dfb867b870187824cac9f0 (diff)
Make the name2id/id2name code generically usable. This will be needed by
the upcomming filter rewrite. OK henning@
-rw-r--r--usr.sbin/bgpd/name2id.c97
1 files changed, 73 insertions, 24 deletions
diff --git a/usr.sbin/bgpd/name2id.c b/usr.sbin/bgpd/name2id.c
index 5916f221d44..03eafdcc1d4 100644
--- a/usr.sbin/bgpd/name2id.c
+++ b/usr.sbin/bgpd/name2id.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: name2id.c,v 1.1 2005/06/13 21:16:18 henning Exp $ */
+/* $OpenBSD: name2id.c,v 1.2 2005/06/25 16:26:25 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -21,6 +21,7 @@
#include <net/route.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -28,26 +29,53 @@
#define IDVAL_MAX 50000
-struct rt_label {
- TAILQ_ENTRY(rt_label) entry;
- char name[RTLABEL_LEN];
- u_int16_t id;
- int ref;
+struct n2id_label {
+ TAILQ_ENTRY(n2id_label) entry;
+ char *name;
+ u_int16_t id;
+ int ref;
};
-TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
+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);
+int _exists(struct n2id_labels *, const char *);
+
+struct n2id_labels rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
+struct n2id_labels filter_labels = TAILQ_HEAD_INITIALIZER(filter_labels);
u_int16_t
rtlabel_name2id(char *name)
{
- struct rt_label *label, *p = NULL;
+ return (_name2id(&rt_labels, name));
+}
+
+const char *
+rtlabel_id2name(u_int16_t id)
+{
+ return (_id2name(&rt_labels, id));
+}
+
+void
+rtlabel_unref(u_int16_t id)
+{
+ _unref(&rt_labels, id);
+}
+
+u_int16_t
+_name2id(struct n2id_labels *head, const char *name)
+{
+ struct n2id_label *label, *p = NULL;
u_int16_t new_id = 1;
- if (!name[0])
+ if (!name[0]) {
+ errno = EINVAL;
return (0);
+ }
- TAILQ_FOREACH(label, &rt_labels, entry)
+ TAILQ_FOREACH(label, head, entry)
if (strcmp(name, label->name) == 0) {
label->ref++;
return (label->id);
@@ -59,37 +87,42 @@ rtlabel_name2id(char *name)
* is empty, append a new entry at the end.
*/
- if (!TAILQ_EMPTY(&rt_labels))
- for (p = TAILQ_FIRST(&rt_labels); p != NULL &&
+ if (!TAILQ_EMPTY(head))
+ for (p = TAILQ_FIRST(head); p != NULL &&
p->id == new_id; p = TAILQ_NEXT(p, entry))
new_id = p->id + 1;
- if (new_id > IDVAL_MAX)
+ if (new_id > IDVAL_MAX) {
+ errno = ERANGE;
return (0);
+ }
- if ((label = calloc(1, sizeof(struct rt_label))) == NULL)
+ if ((label = calloc(1, sizeof(struct n2id_label))) == NULL)
return (0);
- strlcpy(label->name, name, sizeof(label->name));
+ if ((label->name = strdup(name)) == NULL) {
+ free(label);
+ return (0);
+ }
label->id = new_id;
label->ref++;
if (p != NULL) /* insert new entry before p */
TAILQ_INSERT_BEFORE(p, label, entry);
else /* either list empty or no free slot in between */
- TAILQ_INSERT_TAIL(&rt_labels, label, entry);
+ TAILQ_INSERT_TAIL(head, label, entry);
return (label->id);
}
const char *
-rtlabel_id2name(u_int16_t id)
+_id2name(struct n2id_labels *head, u_int16_t id)
{
- struct rt_label *label;
+ struct n2id_label *label;
if (!id)
- return("");
+ return ("");
- TAILQ_FOREACH(label, &rt_labels, entry)
+ TAILQ_FOREACH(label, head, entry)
if (label->id == id)
return (label->name);
@@ -97,21 +130,37 @@ rtlabel_id2name(u_int16_t id)
}
void
-rtlabel_unref(u_int16_t id)
+_unref(struct n2id_labels *head, u_int16_t id)
{
- struct rt_label *p, *next;
+ struct n2id_label *p, *next;
if (id == 0)
return;
- for (p = TAILQ_FIRST(&rt_labels); p != NULL; p = next) {
+ for (p = TAILQ_FIRST(head); p != NULL; p = next) {
next = TAILQ_NEXT(p, entry);
if (id == p->id) {
if (--p->ref == 0) {
- TAILQ_REMOVE(&rt_labels, p, entry);
+ TAILQ_REMOVE(head, p, entry);
+ free(p->name);
free(p);
}
break;
}
}
}
+
+int
+_exists(struct n2id_labels *head, const char *name)
+{
+ struct n2id_label *label;
+
+ if (!name[0])
+ return (0);
+
+ TAILQ_FOREACH(label, head, entry)
+ if (strcmp(name, label->name) == 0)
+ return (label->id);
+
+ return (0);
+}