summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 14:00:34 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-02-26 14:00:34 +0000
commit11a180c99e46f36231edf3068b2a427969f69411 (patch)
tree8230d636d704aeee6f6653ca69945b4673fda63b /usr.sbin
parent8f7a65223ef60cf679511eed6084ba0d67d363e2 (diff)
Implement "enforce neighbor-as yes|no" which is by default on for ebgp
neighbors. While doing that check also that the nexthop is valid (not class D or E and not in 127/8 range). Kill some TODO and XXX and rename the british neighbour to neighbor as used everywhere else. OK henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/bgpd.h9
-rw-r--r--usr.sbin/bgpd/config.c5
-rw-r--r--usr.sbin/bgpd/parse.y11
-rw-r--r--usr.sbin/bgpd/rde.c6
-rw-r--r--usr.sbin/bgpd/rde.h7
-rw-r--r--usr.sbin/bgpd/rde_attr.c30
-rw-r--r--usr.sbin/bgpd/rde_decide.c6
7 files changed, 52 insertions, 22 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 801c649948b..0339b077619 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.99 2004/02/26 09:53:58 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.100 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -125,6 +125,12 @@ enum announce_type {
ANNOUNCE_ALL
};
+enum enforce_as {
+ ENFORCE_AS_UNDEF,
+ ENFORCE_AS_OFF,
+ ENFORCE_AS_ON
+};
+
struct filter_set {
u_int8_t flags;
u_int32_t localpref;
@@ -150,6 +156,7 @@ struct peer_config {
u_int16_t min_holdtime;
struct filter_set attrset;
enum announce_type announce_type;
+ enum enforce_as enforce_as;
char tcp_md5_key[TCP_MD5_KEY_LEN];
enum reconf_action reconf_action;
};
diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c
index b96706ba913..45120a2cbd5 100644
--- a/usr.sbin/bgpd/config.c
+++ b/usr.sbin/bgpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.28 2004/02/10 23:10:23 henning Exp $ */
+/* $OpenBSD: config.c,v 1.29 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -59,6 +59,9 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
if (p->conf.announce_type == ANNOUNCE_UNDEF)
p->conf.announce_type = p->conf.ebgp == 0 ?
ANNOUNCE_ALL : ANNOUNCE_SELF;
+ if (p->conf.enforce_as == ENFORCE_AS_UNDEF)
+ p->conf.enforce_as = p->conf.ebgp == 0 ?
+ ENFORCE_AS_OFF : ENFORCE_AS_ON;
}
memcpy(xconf, conf, sizeof(struct bgpd_config));
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index e77a5193242..b7119fa6d2d 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.62 2004/02/26 13:54:50 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.63 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -100,6 +100,7 @@ typedef struct {
%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE
%token GROUP NEIGHBOR NETWORK
%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX ANNOUNCE
+%token ENFORCE NEIGHBORAS
%token DUMP TABLE IN OUT
%token LOG
%token TCP MD5SIG PASSWORD KEY
@@ -393,6 +394,12 @@ peeropts : REMOTEAS number {
YYERROR;
}
}
+ | ENFORCE NEIGHBORAS yesno {
+ if ($3)
+ curpeer->conf.enforce_as = ENFORCE_AS_ON;
+ else
+ curpeer->conf.enforce_as = ENFORCE_AS_OFF;
+ }
| MAXPREFIX number {
curpeer->conf.max_prefix = $2;
}
@@ -681,6 +688,7 @@ lookup(char *s)
{ "deny", DENY},
{ "descr", DESCR},
{ "dump", DUMP},
+ { "enforce", ENFORCE},
{ "fib-update", FIBUPDATE},
{ "from", FROM},
{ "group", GROUP},
@@ -697,6 +705,7 @@ lookup(char *s)
{ "med", MED},
{ "min", YMIN},
{ "multihop", MULTIHOP},
+ { "neighbor-as", NEIGHBORAS},
{ "neighbor", NEIGHBOR},
{ "network", NETWORK},
{ "nexthop", NEXTHOP},
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 83b93321053..38444f5a210 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.87 2004/02/26 09:53:58 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.88 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -409,8 +409,8 @@ rde_update_dispatch(struct imsg *imsg)
/* parse path attributes */
attr_init(&attrs);
while (attrpath_len > 0) {
- if ((pos = attr_parse(p, attrpath_len, &attrs,
- peer->conf.ebgp)) < 0) {
+ if ((pos = attr_parse(p, attrpath_len, &attrs, peer->conf.ebgp,
+ peer->conf.enforce_as, peer->conf.remote_as)) < 0) {
emsg = attr_error(p, attrpath_len, &attrs,
&subtype, &size);
rde_update_err(peer, ERR_UPDATE, subtype, emsg, size);
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index eb12f60dae2..4b173ce7b6a 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.29 2004/02/19 23:07:00 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.30 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -213,7 +213,8 @@ u_int16_t rde_local_as(void);
/* rde_attr.c */
void attr_init(struct attr_flags *);
-int attr_parse(u_char *, u_int16_t, struct attr_flags *, int);
+int attr_parse(u_char *, u_int16_t, struct attr_flags *, int,
+ enum enforce_as, u_int16_t);
u_char *attr_error(u_char *, u_int16_t, struct attr_flags *,
u_int8_t *, u_int16_t *);
u_int8_t attr_missing(struct attr_flags *, int);
@@ -237,7 +238,7 @@ int aspath_write(void *, u_int16_t, struct aspath *, u_int16_t,
u_char *aspath_dump(struct aspath *);
u_int16_t aspath_length(struct aspath *);
u_int16_t aspath_count(struct aspath *);
-u_int16_t aspath_neighbour(struct aspath *);
+u_int16_t aspath_neighbor(struct aspath *);
u_int32_t aspath_hash(struct aspath *);
int aspath_loopfree(struct aspath *, u_int16_t);
int aspath_compare(struct aspath *, struct aspath *);
diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c
index 9cb130fa201..cc6bc77f53d 100644
--- a/usr.sbin/bgpd/rde_attr.c
+++ b/usr.sbin/bgpd/rde_attr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_attr.c,v 1.14 2004/02/24 15:44:33 claudio Exp $ */
+/* $OpenBSD: rde_attr.c,v 1.15 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -19,6 +19,8 @@
#include <sys/types.h>
#include <sys/queue.h>
+#include <netinet/in.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -59,7 +61,8 @@ attr_init(struct attr_flags *a)
}
int
-attr_parse(u_char *p, u_int16_t len, struct attr_flags *a, int ebgp)
+attr_parse(u_char *p, u_int16_t len, struct attr_flags *a, int ebgp,
+ enum enforce_as enforce_as, u_int16_t remote_as)
{
u_int32_t tmp32;
u_int16_t attr_len;
@@ -108,7 +111,10 @@ attr_parse(u_char *p, u_int16_t len, struct attr_flags *a, int ebgp)
return (-1);
WFLAG(a->wflags, F_ATTR_ASPATH);
a->aspath = aspath_create(p, attr_len);
- /* XXX enforce remote-as == left most AS if not disabled */
+ if (enforce_as == ENFORCE_AS_ON &&
+ remote_as != aspath_neighbor(a->aspath))
+ return (-1);
+
plen += attr_len;
break;
case ATTR_NEXTHOP:
@@ -118,7 +124,14 @@ attr_parse(u_char *p, u_int16_t len, struct attr_flags *a, int ebgp)
return (-1);
WFLAG(a->wflags, F_ATTR_NEXTHOP);
UPD_READ(&a->nexthop, p, plen, 4); /* network byte order */
- /* XXX check if the nexthop is a valid IP address */
+ /*
+ * Check if the nexthop is a valid IP address. We consider
+ * multicast, experimental and loopback addresses as invalid.
+ */
+ tmp32 = ntohl(a->nexthop);
+ if (IN_MULTICAST(tmp32) || IN_BADCLASS(tmp32) ||
+ (tmp32 & 0x7f000000) == 0x7f000000)
+ return (-1);
break;
case ATTR_MED:
if (attr_len != 4)
@@ -480,10 +493,6 @@ attr_optfree(struct attr_flags *attr)
/* aspath specific functions */
-/* TODO
- * aspath regexp search,
- * aspath to string converter
- */
static u_int16_t aspath_extract(void *, int);
/*
@@ -642,6 +651,7 @@ void
aspath_destroy(struct aspath *aspath)
{
/* only the aspath needs to be freed */
+ if (aspath == NULL) return;
free(aspath);
}
@@ -681,11 +691,11 @@ aspath_count(struct aspath *aspath)
}
u_int16_t
-aspath_neighbour(struct aspath *aspath)
+aspath_neighbor(struct aspath *aspath)
{
/*
* Empty aspath is OK -- internal as route.
- * But what is the neighbour? For now let's return 0 that
+ * But what is the neighbor? For now let's return 0 that
* should not break anything.
*/
diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c
index b16e2a05757..9580e9fbf42 100644
--- a/usr.sbin/bgpd/rde_decide.c
+++ b/usr.sbin/bgpd/rde_decide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_decide.c,v 1.28 2004/02/17 14:22:40 claudio Exp $ */
+/* $OpenBSD: rde_decide.c,v 1.29 2004/02/26 14:00:33 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -147,8 +147,8 @@ prefix_cmp(struct prefix *p1, struct prefix *p2)
return (asp2->flags.origin - asp1->flags.origin);
/* 5. MED decision, only comparable between the same neighboring AS */
- if (aspath_neighbour(asp1->flags.aspath) ==
- aspath_neighbour(asp2->flags.aspath))
+ if (aspath_neighbor(asp1->flags.aspath) ==
+ aspath_neighbor(asp2->flags.aspath))
/* the bigger, the better */
if ((asp1->flags.med - asp2->flags.med) != 0)
return (asp1->flags.med - asp2->flags.med);