diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-06-25 16:26:26 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-06-25 16:26:26 +0000 |
commit | f7bfda00155de15887ece175b7bcd37c0a866376 (patch) | |
tree | 909430ec889f854f39c414aa0b473f85cf6c1494 | |
parent | f33027af4f5a8d1fd4dfb867b870187824cac9f0 (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.c | 97 |
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); +} |