From 0c6f15423dbbf6b9e1edba3e80bfdb7401771231 Mon Sep 17 00:00:00 2001 From: Henning Brauer Date: Mon, 5 Jul 2004 16:54:54 +0000 Subject: implement "set nexthop blackhole" and "set nexthop reject" blackhole/reject routes will be entered to the kernel for matching ones. this is intended to be used with the Cymru Bogon Route Server Project (http://www.cymru.com/BGP/bogon-rs.html) and similar services, claudio ok --- usr.sbin/bgpd/bgpd.h | 94 ++++++++++++++++++++++++---------------------- usr.sbin/bgpd/kroute.c | 25 ++++++++++-- usr.sbin/bgpd/parse.y | 12 +++++- usr.sbin/bgpd/printconf.c | 6 ++- usr.sbin/bgpd/rde.c | 9 ++++- usr.sbin/bgpd/rde.h | 4 +- usr.sbin/bgpd/rde_filter.c | 6 ++- 7 files changed, 100 insertions(+), 56 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 4f7fa993347..d1fc7b70dd4 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.134 2004/07/05 02:13:44 henning Exp $ */ +/* $OpenBSD: bgpd.h,v 1.135 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -37,7 +37,7 @@ #define PFTABLE_LEN 16 #define TCP_MD5_KEY_LEN 80 #define IPSEC_ENC_KEY_LEN 32 -#define IPSEC_AUTH_KEY_LEN 20 +#define IPSEC_AUTH_KEY_LEN 20 #define MAX_PKTSIZE 4096 #define MIN_HOLDTIME 3 @@ -52,17 +52,19 @@ #define BGPD_FLAG_NO_EVALUATE 0x0002 #define BGPD_FLAG_REFLECTOR 0x0004 -#define BGPD_LOG_UPDATES 0x0001 +#define BGPD_LOG_UPDATES 0x0001 #define SOCKET_NAME "/var/run/bgpd.sock" -#define F_BGPD_INSERTED 0x01 -#define F_KERNEL 0x02 -#define F_CONNECTED 0x04 -#define F_NEXTHOP 0x08 -#define F_DOWN 0x10 -#define F_STATIC 0x20 -#define F_LONGER 0x40 +#define F_BGPD_INSERTED 0x0001 +#define F_KERNEL 0x0002 +#define F_CONNECTED 0x0004 +#define F_NEXTHOP 0x0008 +#define F_DOWN 0x0010 +#define F_STATIC 0x0020 +#define F_LONGER 0x0040 +#define F_REJECT 0x0080 +#define F_BLACKHOLE 0x0100 enum { PROC_MAIN, @@ -102,15 +104,15 @@ struct bgpd_addr { u_int32_t addr32[4]; } ba; /* 128-bit address */ u_int32_t scope_id; /* iface scope id for v6 */ -#define v4 ba.v4 -#define v6 ba.v6 -#define addr8 ba.addr8 -#define addr16 ba.addr16 -#define addr32 ba.addr32 +#define v4 ba.v4 +#define v6 ba.v6 +#define addr8 ba.addr8 +#define addr16 ba.addr16 +#define addr32 ba.addr32 }; -#define DEFAULT_LISTENER 0x01 -#define LISTENER_LISTENING 0x02 +#define DEFAULT_LISTENER 0x01 +#define LISTENER_LISTENING 0x02 struct listen_addr { TAILQ_ENTRY(listen_addr) entry; @@ -154,7 +156,7 @@ enum enforce_as { }; struct filter_set { - u_int8_t flags; + u_int16_t flags; u_int32_t localpref; u_int32_t med; struct in_addr nexthop; @@ -351,7 +353,7 @@ struct kroute { struct in_addr prefix; u_int8_t prefixlen; struct in_addr nexthop; - u_int8_t flags; + u_int16_t flags; u_short ifindex; }; @@ -359,7 +361,7 @@ struct kroute6 { struct in6_addr prefix; u_int8_t prefixlen; struct in6_addr nexthop; - u_int8_t flags; + u_int16_t flags; u_short ifindex; }; @@ -402,10 +404,10 @@ struct ctl_show_nexthop { u_int8_t valid; }; -#define F_RIB_ELIGIBLE 0x01 -#define F_RIB_ACTIVE 0x02 -#define F_RIB_INTERNAL 0x04 -#define F_RIB_ANNOUNCE 0x08 +#define F_RIB_ELIGIBLE 0x01 +#define F_RIB_ACTIVE 0x02 +#define F_RIB_INTERNAL 0x04 +#define F_RIB_ANNOUNCE 0x08 struct ctl_show_rib { time_t lastchange; @@ -473,13 +475,15 @@ enum comp_ops { }; /* set flags */ -#define SET_LOCALPREF 0x01 -#define SET_MED 0x02 -#define SET_NEXTHOP 0x04 -#define SET_NEXTHOP6 0x08 -#define SET_PREPEND 0x10 -#define SET_PFTABLE 0x20 -#define SET_COMMUNITY 0x40 +#define SET_LOCALPREF 0x0001 +#define SET_MED 0x0002 +#define SET_NEXTHOP 0x0004 +#define SET_NEXTHOP6 0x0008 +#define SET_PREPEND 0x0010 +#define SET_PFTABLE 0x0020 +#define SET_COMMUNITY 0x0040 +#define SET_NEXTHOP_REJECT 0x0080 +#define SET_NEXTHOP_BLACKHOLE 0x0100 struct filter_peers { u_int32_t peerid; @@ -487,13 +491,13 @@ struct filter_peers { }; /* special community type */ -#define COMMUNITY_ERROR -1 -#define COMMUNITY_ANY -2 -#define COMMUNITY_WELLKNOWN 0xffff -#define COMMUNITY_NO_EXPORT 0xff01 -#define COMMUNITY_NO_ADVERTISE 0xff02 -#define COMMUNITY_NO_EXPSUBCONFED 0xff03 -#define COMMUNITY_NO_PEER 0xff04 /* rfc3765 */ +#define COMMUNITY_ERROR -1 +#define COMMUNITY_ANY -2 +#define COMMUNITY_WELLKNOWN 0xffff +#define COMMUNITY_NO_EXPORT 0xff01 +#define COMMUNITY_NO_ADVERTISE 0xff02 +#define COMMUNITY_NO_EXPSUBCONFED 0xff03 +#define COMMUNITY_NO_PEER 0xff04 /* rfc3765 */ struct filter_match { struct { @@ -531,15 +535,15 @@ struct rrefresh { }; /* Address Family Numbers as per rfc1700 */ -#define AFI_IPv4 1 -#define AFI_IPv6 2 -#define AFI_ALL 0xffff +#define AFI_IPv4 1 +#define AFI_IPv6 2 +#define AFI_ALL 0xffff /* Subsequent Address Family Identifier as per rfc2858 */ -#define SAFI_UNICAST 1 -#define SAFI_MULTICAST 2 -#define SAFI_BOTH 3 -#define SAFI_ALL 0xff +#define SAFI_UNICAST 1 +#define SAFI_MULTICAST 2 +#define SAFI_BOTH 3 +#define SAFI_ALL 0xff /* prototypes */ /* bgpd.c */ diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index a8ac95ae124..7f78c51df36 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.102 2004/07/05 02:13:44 henning Exp $ */ +/* $OpenBSD: kroute.c,v 1.103 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -200,12 +200,21 @@ kr_change(struct kroute *kroute) 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 = F_BGPD_INSERTED; + kr->r.flags = kroute->flags | F_BGPD_INSERTED; if (kroute_insert(kr) == -1) free(kr); - } else + } else { kr->r.nexthop.s_addr = kroute->nexthop.s_addr; + if (kroute->flags & F_BLACKHOLE) + kr->r.flags |= F_BLACKHOLE; + else + kr->r.flags &= ~F_BLACKHOLE; + if (kroute->flags & F_REJECT) + kr->r.flags |= F_REJECT; + else + kr->r.flags &= ~F_REJECT; + } return (0); } @@ -1061,15 +1070,23 @@ send_rtmsg(int fd, int action, struct kroute *kroute) r.hdr.rtm_msglen = sizeof(r); r.hdr.rtm_version = RTM_VERSION; r.hdr.rtm_type = action; - r.hdr.rtm_flags = RTF_GATEWAY|RTF_PROTO1; + r.hdr.rtm_flags = RTF_PROTO1; + if (kroute->flags & F_BLACKHOLE) + r.hdr.rtm_flags |= RTF_BLACKHOLE; + 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.prefix.sin_len = sizeof(r.prefix); r.prefix.sin_family = AF_INET; r.prefix.sin_addr.s_addr = kroute->prefix.s_addr; + r.nexthop.sin_len = sizeof(r.nexthop); r.nexthop.sin_family = AF_INET; r.nexthop.sin_addr.s_addr = kroute->nexthop.s_addr; + if (kroute->nexthop.s_addr != 0) + r.hdr.rtm_flags |= RTF_GATEWAY; + r.mask.sin_len = sizeof(r.mask); r.mask.sin_family = AF_INET; r.mask.sin_addr.s_addr = htonl(prefixlen2mask(kroute->prefixlen)); diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index d970903d46c..f64bd1083f8 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.117 2004/07/03 17:19:59 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.118 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -122,7 +122,7 @@ typedef struct { %token QUICK %token FROM TO ANY %token PREFIX PREFIXLEN SOURCEAS TRANSITAS COMMUNITY -%token SET LOCALPREF MED NEXTHOP PREPEND PFTABLE +%token SET LOCALPREF MED NEXTHOP PREPEND PFTABLE REJECT BLACKHOLE %token ERROR %token IPSEC ESP AH SPI IKE %token STRING @@ -929,6 +929,12 @@ filter_set_opt : LOCALPREF number { YYERROR; } } + | NEXTHOP BLACKHOLE { + $$.flags |= SET_NEXTHOP_BLACKHOLE; + } + | NEXTHOP REJECT { + $$.flags |= SET_NEXTHOP_REJECT; + } | PREPEND number { $$.flags = SET_PREPEND; $$.prepend = $2; @@ -1038,6 +1044,7 @@ lookup(char *s) { "allow", ALLOW}, { "announce", ANNOUNCE}, { "any", ANY}, + { "blackhole", BLACKHOLE}, { "capabilities", CAPABILITIES}, { "community", COMMUNITY}, { "deny", DENY}, @@ -1076,6 +1083,7 @@ lookup(char *s) { "prefixlen", PREFIXLEN}, { "prepend-self", PREPEND}, { "quick", QUICK}, + { "reject", REJECT}, { "remote-as", REMOTEAS}, { "route-collector", ROUTECOLL}, { "route-reflector", REFLECTOR}, diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 8f592d246b3..61528ed7cfa 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.23 2004/07/03 17:19:59 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.24 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -79,6 +79,10 @@ print_set(struct filter_set *set) printf("med %u ", set->med); if (set->flags & SET_NEXTHOP) printf("nexthop %s ", inet_ntoa(set->nexthop)); + if (set->flags & SET_NEXTHOP_REJECT) + printf("nexthop reject "); + if (set->flags & SET_NEXTHOP_BLACKHOLE) + printf("nexthop blackhole "); if (set->flags & SET_PREPEND) printf("prepend-self %u ", set->prepend); printf("}"); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index e335315f409..9669aff4141 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.125 2004/07/05 02:13:44 henning Exp $ */ +/* $OpenBSD: rde.c,v 1.126 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1109,12 +1109,13 @@ rde_send_kroute(struct prefix *new, struct prefix *old) new->aspath->nexthop->flags & NEXTHOP_ANNOUNCE)) return; + bzero(&kr, sizeof(kr)); + if (new == NULL || new->aspath->nexthop == NULL || new->aspath->nexthop->state != NEXTHOP_REACH || new->aspath->nexthop->flags & NEXTHOP_ANNOUNCE) { type = IMSG_KROUTE_DELETE; p = old; - kr.nexthop.s_addr = 0; } else { type = IMSG_KROUTE_CHANGE; p = new; @@ -1124,6 +1125,10 @@ rde_send_kroute(struct prefix *new, struct prefix *old) pt_getaddr(p->prefix, &addr); kr.prefix.s_addr = addr.v4.s_addr; kr.prefixlen = p->prefix->prefixlen; + if (p->aspath->flags.nexthop_reject) + kr.flags |= F_REJECT; + if (p->aspath->flags.nexthop_blackhole) + kr.flags |= F_BLACKHOLE; if (imsg_compose(&ibuf_main, type, 0, &kr, sizeof(kr)) == -1) fatal("imsg_compose error"); diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 7170224de9f..4061a42ab74 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.43 2004/06/24 23:15:58 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.44 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -130,6 +130,8 @@ TAILQ_HEAD(attr_list, attr); struct attr_flags { struct aspath *aspath; struct in_addr nexthop; /* exit nexthop */ + u_int8_t nexthop_reject; + u_int8_t nexthop_blackhole; char pftable[PFTABLE_LEN]; u_int32_t med; /* multi exit disc */ u_int32_t lpref; /* local pref */ diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index cd01ce65082..3aab373ab35 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.11 2004/06/24 23:15:58 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.12 2004/07/05 16:54:53 henning Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -67,6 +67,10 @@ rde_apply_set(struct attr_flags *attrs, struct filter_set *set) attrs->med = set->med; if (set->flags & SET_NEXTHOP) attrs->nexthop = set->nexthop; + if (set->flags & SET_NEXTHOP_REJECT) + attrs->nexthop_reject = 1; + if (set->flags & SET_NEXTHOP_BLACKHOLE) + attrs->nexthop_blackhole = 1; if (set->flags & SET_PREPEND) { /* * The actual prepending is done afterwards because -- cgit v1.2.3