summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2005-06-13 21:16:19 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2005-06-13 21:16:19 +0000
commitb67d52447b7269e8a850cde9cd3d1d55bdbf43b0 (patch)
tree5a9cf9ea456458e9d7945642b0aa24309f91d123 /usr.sbin
parentf5b0690d48b94e07abc90ee4f1e44565f941df53 (diff)
route label support, kroute part and ID allocator as well as the internal
interface changes. support in the filter language and rde to come. claudio ok
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/Makefile4
-rw-r--r--usr.sbin/bgpd/bgpd.h23
-rw-r--r--usr.sbin/bgpd/kroute.c94
-rw-r--r--usr.sbin/bgpd/name2id.c117
-rw-r--r--usr.sbin/bgpd/rde.c27
5 files changed, 212 insertions, 53 deletions
diff --git a/usr.sbin/bgpd/Makefile b/usr.sbin/bgpd/Makefile
index 6b515e411ec..e29cea78830 100644
--- a/usr.sbin/bgpd/Makefile
+++ b/usr.sbin/bgpd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.22 2005/03/28 15:16:45 henning Exp $
+# $OpenBSD: Makefile,v 1.23 2005/06/13 21:16:18 henning Exp $
.PATH: ${.CURDIR}/..
@@ -6,7 +6,7 @@ PROG= bgpd
SRCS= bgpd.c buffer.c session.c log.c parse.y config.c imsg.c \
rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c \
control.c pfkey.c rde_update.c rde_attr.c printconf.c \
- rde_filter.c pftable.c
+ rde_filter.c pftable.c name2id.c
CFLAGS+= -Wall -I${.CURDIR}
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+= -Wmissing-declarations
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 9a685c9e73e..aafad0280b1 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.167 2005/06/09 15:32:03 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.168 2005/06/13 21:16:18 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
+#include <net/route.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
@@ -369,6 +370,7 @@ struct kroute {
struct in_addr prefix;
struct in_addr nexthop;
u_int16_t flags;
+ u_int16_t labelid;
u_short ifindex;
u_int8_t prefixlen;
};
@@ -377,6 +379,7 @@ struct kroute6 {
struct in6_addr prefix;
struct in6_addr nexthop;
u_int16_t flags;
+ u_int16_t labelid;
u_short ifindex;
u_int8_t prefixlen;
};
@@ -427,6 +430,16 @@ struct ctl_neighbor {
char descr[PEER_DESCR_LEN];
};
+struct kroute_label {
+ struct kroute kr;
+ char label[RTLABEL_LEN];
+};
+
+struct kroute6_label {
+ struct kroute6 kr;
+ char label[RTLABEL_LEN];
+};
+
#define F_RIB_ELIGIBLE 0x01
#define F_RIB_ACTIVE 0x02
#define F_RIB_INTERNAL 0x04
@@ -653,10 +666,10 @@ int imsg_get_fd(struct imsgbuf *);
/* kroute.c */
int kr_init(int);
-int kr_change(struct kroute *);
-int kr_delete(struct kroute *);
-int kr6_change(struct kroute6 *);
-int kr6_delete(struct kroute6 *);
+int kr_change(struct kroute_label *);
+int kr_delete(struct kroute_label *);
+int kr6_change(struct kroute6_label *);
+int kr6_delete(struct kroute6_label *);
void kr_shutdown(void);
void kr_fib_couple(void);
void kr_fib_decouple(void);
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index dbfb8f27eca..5404086dfbd 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.136 2005/06/07 18:56:51 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.137 2005/06/13 21:16:18 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -208,12 +208,12 @@ kr_init(int fs)
}
int
-kr_change(struct kroute *kroute)
+kr_change(struct kroute_label *kl)
{
struct kroute_node *kr;
int action = RTM_ADD;
- if ((kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen)) !=
+ if ((kr = kroute_find(kl->kr.prefix.s_addr, kl->kr.prefixlen)) !=
NULL) {
if (kr->r.flags & F_BGPD_INSERTED)
action = RTM_CHANGE;
@@ -222,11 +222,15 @@ kr_change(struct kroute *kroute)
}
/* nexthop within 127/8 -> ignore silently */
- if ((kroute->nexthop.s_addr & htonl(IN_CLASSA_NET)) ==
+ if ((kl->kr.nexthop.s_addr & htonl(IN_CLASSA_NET)) ==
htonl(INADDR_LOOPBACK & IN_CLASSA_NET))
return (0);
- if (send_rtmsg(kr_state.fd, action, kroute) == -1)
+ if (kr)
+ rtlabel_unref(kr->r.labelid);
+ kl->kr.labelid = rtlabel_name2id(kl->label);
+
+ if (send_rtmsg(kr_state.fd, action, &kl->kr) == -1)
return (-1);
if (action == RTM_ADD) {
@@ -234,20 +238,22 @@ kr_change(struct kroute *kroute)
log_warn("kr_change");
return (-1);
}
- kr->r.prefix.s_addr = kroute->prefix.s_addr;
- kr->r.prefixlen = kroute->prefixlen;
- kr->r.nexthop.s_addr = kroute->nexthop.s_addr;
- kr->r.flags = kroute->flags | F_BGPD_INSERTED;
+ kr->r.prefix.s_addr = kl->kr.prefix.s_addr;
+ kr->r.prefixlen = kl->kr.prefixlen;
+ kr->r.nexthop.s_addr = kl->kr.nexthop.s_addr;
+ kr->r.flags = kl->kr.flags | F_BGPD_INSERTED;
+ kr->r.labelid = kl->kr.labelid;
if (kroute_insert(kr) == -1)
free(kr);
} else {
- kr->r.nexthop.s_addr = kroute->nexthop.s_addr;
- if (kroute->flags & F_BLACKHOLE)
+ kr->r.nexthop.s_addr = kl->kr.nexthop.s_addr;
+ kr->r.labelid = kl->kr.labelid;
+ if (kl->kr.flags & F_BLACKHOLE)
kr->r.flags |= F_BLACKHOLE;
else
kr->r.flags &= ~F_BLACKHOLE;
- if (kroute->flags & F_REJECT)
+ if (kl->kr.flags & F_REJECT)
kr->r.flags |= F_REJECT;
else
kr->r.flags &= ~F_REJECT;
@@ -257,11 +263,11 @@ kr_change(struct kroute *kroute)
}
int
-kr_delete(struct kroute *kroute)
+kr_delete(struct kroute_label *kl)
{
struct kroute_node *kr;
- if ((kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen)) ==
+ if ((kr = kroute_find(kl->kr.prefix.s_addr, kl->kr.prefixlen)) ==
NULL)
return (0);
@@ -269,11 +275,13 @@ kr_delete(struct kroute *kroute)
return (0);
/* nexthop within 127/8 -> ignore silently */
- if ((kroute->nexthop.s_addr & htonl(IN_CLASSA_NET)) ==
+ if ((kl->kr.nexthop.s_addr & htonl(IN_CLASSA_NET)) ==
htonl(INADDR_LOOPBACK & IN_CLASSA_NET))
return (0);
- if (send_rtmsg(kr_state.fd, RTM_DELETE, kroute) == -1)
+ rtlabel_unref(kl->kr.labelid);
+
+ if (send_rtmsg(kr_state.fd, RTM_DELETE, &kl->kr) == -1)
return (-1);
if (kroute_remove(kr) == -1)
@@ -283,12 +291,12 @@ kr_delete(struct kroute *kroute)
}
int
-kr6_change(struct kroute6 *kroute)
+kr6_change(struct kroute6_label *kl)
{
struct kroute6_node *kr6;
int action = RTM_ADD;
- if ((kr6 = kroute6_find(&kroute->prefix, kroute->prefixlen)) != NULL) {
+ if ((kr6 = kroute6_find(&kl->kr.prefix, kl->kr.prefixlen)) != NULL) {
if (kr6->r.flags & F_BGPD_INSERTED)
action = RTM_CHANGE;
else /* a non-bgp route already exists. not a problem */
@@ -296,10 +304,14 @@ kr6_change(struct kroute6 *kroute)
}
/* nexthop to loopback -> ignore silently */
- if (IN6_IS_ADDR_LOOPBACK(&kroute->nexthop))
+ if (IN6_IS_ADDR_LOOPBACK(&kl->kr.nexthop))
return (0);
- if (send_rt6msg(kr_state.fd, action, kroute) == -1)
+ if (kr6)
+ rtlabel_unref(kr6->r.labelid);
+ kl->kr.labelid = rtlabel_name2id(kl->label);
+
+ if (send_rt6msg(kr_state.fd, action, &kl->kr) == -1)
return (-1);
if (action == RTM_ADD) {
@@ -307,23 +319,25 @@ kr6_change(struct kroute6 *kroute)
log_warn("kr_change");
return (-1);
}
- memcpy(&kr6->r.prefix, &kroute->prefix,
+ memcpy(&kr6->r.prefix, &kl->kr.prefix,
sizeof(struct in6_addr));
- kr6->r.prefixlen = kroute->prefixlen;
- memcpy(&kr6->r.nexthop, &kroute->nexthop,
+ kr6->r.prefixlen = kl->kr.prefixlen;
+ memcpy(&kr6->r.nexthop, &kl->kr.nexthop,
sizeof(struct in6_addr));
- kr6->r.flags = kroute->flags | F_BGPD_INSERTED;
+ kr6->r.flags = kl->kr.flags | F_BGPD_INSERTED;
+ kr6->r.labelid = kl->kr.labelid;
if (kroute6_insert(kr6) == -1)
free(kr6);
} else {
- memcpy(&kr6->r.nexthop, &kroute->nexthop,
+ memcpy(&kr6->r.nexthop, &kl->kr.nexthop,
sizeof(struct in6_addr));
- if (kroute->flags & F_BLACKHOLE)
+ kr6->r.labelid = kl->kr.labelid;
+ if (kl->kr.flags & F_BLACKHOLE)
kr6->r.flags |= F_BLACKHOLE;
else
kr6->r.flags &= ~F_BLACKHOLE;
- if (kroute->flags & F_REJECT)
+ if (kl->kr.flags & F_REJECT)
kr6->r.flags |= F_REJECT;
else
kr6->r.flags &= ~F_REJECT;
@@ -333,24 +347,26 @@ kr6_change(struct kroute6 *kroute)
}
int
-kr6_delete(struct kroute6 *kroute)
+kr6_delete(struct kroute6_label *kl)
{
struct kroute6_node *kr6;
- if ((kr6 = kroute6_find(&kroute->prefix, kroute->prefixlen)) == NULL)
+ if ((kr6 = kroute6_find(&kl->kr.prefix, kl->kr.prefixlen)) == NULL)
return (0);
if (!(kr6->r.flags & F_BGPD_INSERTED))
return (0);
/* nexthop to loopback -> ignore silently */
- if (IN6_IS_ADDR_LOOPBACK(&kroute->nexthop))
+ if (IN6_IS_ADDR_LOOPBACK(&kl->kr.nexthop))
return (0);
- if (send_rt6msg(kr_state.fd, RTM_DELETE, kroute) == -1)
+ if (send_rt6msg(kr_state.fd, RTM_DELETE, &kl->kr) == -1)
return (-1);
- if (kroute6_remove(kr6) == -1)
+ rtlabel_unref(kl->kr.labelid);
+
+ if (kroute6_remove(kr6) == -1)
return (-1);
return (0);
@@ -1693,6 +1709,7 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
struct sockaddr_in prefix;
struct sockaddr_in nexthop;
struct sockaddr_in mask;
+ struct sockaddr_rtlabel label;
} r;
if (kr_state.fib_sync == 0)
@@ -1708,7 +1725,7 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
if (kroute->flags & F_REJECT)
r.hdr.rtm_flags |= RTF_REJECT;
r.hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */
- r.hdr.rtm_addrs = RTA_DST|RTA_GATEWAY|RTA_NETMASK;
+ r.hdr.rtm_addrs = RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_LABEL;
r.prefix.sin_len = sizeof(r.prefix);
r.prefix.sin_family = AF_INET;
r.prefix.sin_addr.s_addr = kroute->prefix.s_addr;
@@ -1723,6 +1740,10 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
r.mask.sin_family = AF_INET;
r.mask.sin_addr.s_addr = htonl(prefixlen2mask(kroute->prefixlen));
+ r.label.sr_len = sizeof(r.label);
+ strlcpy(r.label.sr_label, rtlabel_id2name(kroute->labelid),
+ sizeof(r.label.sr_label));
+
retry:
if (write(fd, &r, sizeof(r)) == -1) {
switch (errno) {
@@ -1762,6 +1783,7 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
struct sockaddr_in6 prefix;
struct sockaddr_in6 nexthop;
struct sockaddr_in6 mask;
+ struct sockaddr_rtlabel label;
} r;
if (kr_state.fib_sync == 0)
@@ -1777,7 +1799,7 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
if (kroute->flags & F_REJECT)
r.hdr.rtm_flags |= RTF_REJECT;
r.hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */
- r.hdr.rtm_addrs = RTA_DST|RTA_GATEWAY|RTA_NETMASK;
+ r.hdr.rtm_addrs = RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_LABEL;
r.prefix.sin6_len = sizeof(r.prefix);
r.prefix.sin6_family = AF_INET6;
memcpy(&r.prefix.sin6_addr, &kroute->prefix, sizeof(struct in6_addr));
@@ -1794,6 +1816,10 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
memcpy(&r.mask.sin6_addr, prefixlen2mask6(kroute->prefixlen),
sizeof(struct in6_addr));
+ r.label.sr_len = sizeof(r.label);
+ strlcpy(r.label.sr_label, rtlabel_id2name(kroute->labelid),
+ sizeof(r.label.sr_label));
+
retry:
if (write(fd, &r, sizeof(r)) == -1) {
switch (errno) {
diff --git a/usr.sbin/bgpd/name2id.c b/usr.sbin/bgpd/name2id.c
new file mode 100644
index 00000000000..5916f221d44
--- /dev/null
+++ b/usr.sbin/bgpd/name2id.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: name2id.c,v 1.1 2005/06/13 21:16:18 henning Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/route.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "bgpd.h"
+
+#define IDVAL_MAX 50000
+
+struct rt_label {
+ TAILQ_ENTRY(rt_label) entry;
+ char name[RTLABEL_LEN];
+ u_int16_t id;
+ int ref;
+};
+
+TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
+
+
+u_int16_t
+rtlabel_name2id(char *name)
+{
+ struct rt_label *label, *p = NULL;
+ u_int16_t new_id = 1;
+
+ if (!name[0])
+ return (0);
+
+ TAILQ_FOREACH(label, &rt_labels, entry)
+ if (strcmp(name, label->name) == 0) {
+ label->ref++;
+ return (label->id);
+ }
+
+ /*
+ * to avoid fragmentation, we do a linear search from the beginning
+ * and take the first free slot we find. if there is none or the list
+ * is empty, append a new entry at the end.
+ */
+
+ if (!TAILQ_EMPTY(&rt_labels))
+ for (p = TAILQ_FIRST(&rt_labels); p != NULL &&
+ p->id == new_id; p = TAILQ_NEXT(p, entry))
+ new_id = p->id + 1;
+
+ if (new_id > IDVAL_MAX)
+ return (0);
+
+ if ((label = calloc(1, sizeof(struct rt_label))) == NULL)
+ return (0);
+ strlcpy(label->name, name, sizeof(label->name));
+ 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);
+
+ return (label->id);
+}
+
+const char *
+rtlabel_id2name(u_int16_t id)
+{
+ struct rt_label *label;
+
+ if (!id)
+ return("");
+
+ TAILQ_FOREACH(label, &rt_labels, entry)
+ if (label->id == id)
+ return (label->name);
+
+ return ("");
+}
+
+void
+rtlabel_unref(u_int16_t id)
+{
+ struct rt_label *p, *next;
+
+ if (id == 0)
+ return;
+
+ for (p = TAILQ_FIRST(&rt_labels); p != NULL; p = next) {
+ next = TAILQ_NEXT(p, entry);
+ if (id == p->id) {
+ if (--p->ref == 0) {
+ TAILQ_REMOVE(&rt_labels, p, entry);
+ free(p);
+ }
+ break;
+ }
+ }
+}
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index a484185e4bc..a2e485e0403 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.161 2005/06/10 08:28:50 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.162 2005/06/13 21:16:18 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1611,10 +1611,10 @@ rde_dump_prefix(struct ctl_show_rib_prefix *pref, pid_t pid)
void
rde_send_kroute(struct prefix *new, struct prefix *old)
{
- struct kroute kr;
- struct bgpd_addr addr;
- struct prefix *p;
- enum imsg_type type;
+ struct kroute_label kl;
+ struct bgpd_addr addr;
+ struct prefix *p;
+ enum imsg_type type;
/*
* If old is != NULL we know it was active and should be removed.
@@ -1627,7 +1627,7 @@ rde_send_kroute(struct prefix *new, struct prefix *old)
new->aspath->flags & F_PREFIX_ANNOUNCED))
return;
- bzero(&kr, sizeof(kr));
+ bzero(&kl, sizeof(kl));
if (new == NULL || new->aspath->nexthop == NULL ||
new->aspath->nexthop->state != NEXTHOP_REACH ||
@@ -1637,18 +1637,21 @@ rde_send_kroute(struct prefix *new, struct prefix *old)
} else {
type = IMSG_KROUTE_CHANGE;
p = new;
- kr.nexthop.s_addr = p->aspath->nexthop->true_nexthop.v4.s_addr;
+ kl.kr.nexthop.s_addr =
+ p->aspath->nexthop->true_nexthop.v4.s_addr;
}
pt_getaddr(p->prefix, &addr);
- kr.prefix.s_addr = addr.v4.s_addr;
- kr.prefixlen = p->prefix->prefixlen;
+ kl.kr.prefix.s_addr = addr.v4.s_addr;
+ kl.kr.prefixlen = p->prefix->prefixlen;
if (p->aspath->flags & F_NEXTHOP_REJECT)
- kr.flags |= F_REJECT;
+ kl.kr.flags |= F_REJECT;
if (p->aspath->flags & F_NEXTHOP_BLACKHOLE)
- kr.flags |= F_BLACKHOLE;
+ kl.kr.flags |= F_BLACKHOLE;
+ /* XXX */
+ strlcpy(kl.label, rtlabel_id2name(0), sizeof(kl.label));
- if (imsg_compose(ibuf_main, type, 0, 0, -1, &kr, sizeof(kr)) == -1)
+ if (imsg_compose(ibuf_main, type, 0, 0, -1, &kl, sizeof(kl)) == -1)
fatal("imsg_compose error");
}