From 076a43493378f12211626b6f876350ee092a049b Mon Sep 17 00:00:00 2001 From: hrs Date: Mon, 2 Nov 2009 07:09:37 +0000 Subject: Update to 20091022 snapshot. --- net/openbgpd/Makefile | 2 +- net/openbgpd/files/patch-bgpctl_bgpctl.c | 159 +++++++++- net/openbgpd/files/patch-bgpd_bgpd.8 | 51 ++- net/openbgpd/files/patch-bgpd_bgpd.c | 20 +- net/openbgpd/files/patch-bgpd_bgpd.conf.5 | 72 ++++- net/openbgpd/files/patch-bgpd_bgpd.h | 64 ++-- net/openbgpd/files/patch-bgpd_buffer.c | 81 +++-- net/openbgpd/files/patch-bgpd_carp.c | 26 +- net/openbgpd/files/patch-bgpd_control.c | 20 +- net/openbgpd/files/patch-bgpd_imsg.c | 17 +- net/openbgpd/files/patch-bgpd_imsg.h | 5 +- net/openbgpd/files/patch-bgpd_kroute.c | 191 +++++++---- net/openbgpd/files/patch-bgpd_mrt.c | 10 +- net/openbgpd/files/patch-bgpd_parse.y | 179 ++++++++--- net/openbgpd/files/patch-bgpd_printconf.c | 27 +- net/openbgpd/files/patch-bgpd_rde.c | 487 ++++++++++++++++++++--------- net/openbgpd/files/patch-bgpd_rde.h | 28 +- net/openbgpd/files/patch-bgpd_rde_decide.c | 28 +- net/openbgpd/files/patch-bgpd_rde_filter.c | 24 +- net/openbgpd/files/patch-bgpd_rde_rib.c | 8 +- net/openbgpd/files/patch-bgpd_rde_update.c | 39 ++- net/openbgpd/files/patch-bgpd_session.c | 306 ++++++++++++++++-- net/openbgpd/files/patch-bgpd_session.h | 19 +- 23 files changed, 1416 insertions(+), 447 deletions(-) (limited to 'net/openbgpd') diff --git a/net/openbgpd/Makefile b/net/openbgpd/Makefile index 1b567723ce9a..059bd6b3868c 100644 --- a/net/openbgpd/Makefile +++ b/net/openbgpd/Makefile @@ -6,7 +6,7 @@ # PORTNAME= openbgpd -PORTVERSION= 4.5.20090709 +PORTVERSION= 4.5.20091022 CATEGORIES= net MASTER_SITES= ${MASTER_SITE_OPENBSD} MASTER_SITE_SUBDIR= OpenBGPD diff --git a/net/openbgpd/files/patch-bgpctl_bgpctl.c b/net/openbgpd/files/patch-bgpctl_bgpctl.c index 5af61333be39..be4f91b3defe 100644 --- a/net/openbgpd/files/patch-bgpctl_bgpctl.c +++ b/net/openbgpd/files/patch-bgpctl_bgpctl.c @@ -2,13 +2,13 @@ Index: bgpctl/bgpctl.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/bgpctl.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.4 +diff -u -p -r1.1.1.1 -r1.4 --- bgpctl/bgpctl.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpctl/bgpctl.c 9 Jul 2009 17:22:12 -0000 1.3 ++++ bgpctl/bgpctl.c 10 Aug 2009 21:20:02 -0000 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpctl.c,v 1.134 2008/06/07 20:23:15 henning Exp $ */ -+/* $OpenBSD: bgpctl.c,v 1.142 2009/06/06 06:33:15 eric Exp $ */ ++/* $OpenBSD: bgpctl.c,v 1.145 2009/07/23 14:55:25 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer @@ -55,6 +55,15 @@ diff -u -p -r1.1.1.1 -r1.3 enum neighbor_views { NV_DEFAULT, NV_TIMERS +@@ -65,7 +81,7 @@ void show_interface_head(void); + int ift2ifm(int); + const char * get_media_descr(int); + const char * get_linkstate(int, int); +-void print_baudrate(u_int64_t); ++const char * get_baudrate(u_int64_t, char *); + int show_interface_msg(struct imsg *); + void show_rib_summary_head(void); + void print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t); @@ -89,8 +105,8 @@ usage(void) { extern char *__progname; @@ -142,7 +151,143 @@ diff -u -p -r1.1.1.1 -r1.3 free(p); if (!IN6_IS_ADDR_UNSPECIFIED(&k6->nexthop)) -@@ -1186,8 +1205,8 @@ show_rib_detail_msg(struct imsg *imsg, i +@@ -845,35 +864,77 @@ show_fib_msg(struct imsg *imsg) + void + show_nexthop_head(void) + { +- printf("%-20s %-10s\n", "Nexthop", "State"); ++ printf("Flags: * = nexthop valid\n"); ++ printf("\n %-15s %-19s%-4s %-15s %-20s\n", "Nexthop", "Route", ++ "Prio", "Gateway", "Iface"); + } + + int + show_nexthop_msg(struct imsg *imsg) + { + struct ctl_show_nexthop *p; ++ struct kroute *k; ++ struct kroute6 *k6; ++ char *s; + int ifms_type; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_NEXTHOP: + p = imsg->data; +- printf("%-20s %-10s", log_addr(&p->addr), +- p->valid ? "valid" : "invalid"); ++ printf("%s %-15s ", p->valid ? "*" : " ", log_addr(&p->addr)); ++ if (!p->krvalid) { ++ printf("\n"); ++ return (0); ++ } ++ switch (p->addr.af) { ++ case AF_INET: ++ k = &p->kr.kr4; ++ if (asprintf(&s, "%s/%u", inet_ntoa(k->prefix), ++ k->prefixlen) == -1) ++ err(1, NULL); ++ printf("%-20s", s); ++ free(s); ++ printf("%3i %-15s ", k->priority, ++ k->flags & F_CONNECTED ? "connected" : ++ inet_ntoa(k->nexthop)); ++ break; ++ case AF_INET6: ++ k6 = &p->kr.kr6; ++ if (asprintf(&s, "%s/%u", log_in6addr(&k6->prefix), ++ k6->prefixlen) == -1) ++ err(1, NULL); ++ printf("%-20s", s); ++ free(s); ++ printf("%3i %-15s ", k6->priority, ++ k6->flags & F_CONNECTED ? "connected" : ++ log_in6addr(&k6->nexthop)); ++ break; ++ default: ++ printf("unknown address familiy %d\n", p->addr.af); ++ return (0); ++ } + if (p->kif.ifname[0]) { +- printf("%-8s", p->kif.ifname); +- if (p->kif.flags & IFF_UP) { +- printf("UP"); +- ifms_type = ift2ifm(p->kif.media_type); +- if (ifms_type != 0) +- printf(", %s, %s", +- get_media_descr(ifms_type), +- get_linkstate(ifms_type, +- p->kif.link_state)); ++ char *s1; ++ ifms_type = ift2ifm(p->kif.media_type); ++ if (LINK_STATE_IS_UP(p->kif.link_state)) { + if (p->kif.baudrate) { +- printf(", "); +- print_baudrate(p->kif.baudrate); +- } +- } ++ if (asprintf(&s1, ", %s", ++ get_baudrate(p->kif.baudrate, ++ "bps")) == -1) ++ err(1, NULL); ++ } else if (asprintf(&s1, ", %s", get_linkstate( ++ ifms_type, p->kif.link_state)) == -1) ++ err(1, NULL); ++ } else if (ifms_type) ++ if (asprintf(&s1, ", %s", get_linkstate( ++ ifms_type, p->kif.link_state)) == -1) ++ err(1, NULL); ++ if (asprintf(&s, "%s (%s%s)", p->kif.ifname, ++ p->kif.flags & IFF_UP ? "UP" : "DOWN", s1) == -1) ++ err(1, NULL); ++ printf("%-15s", s); ++ free(s1); ++ free(s); + } + printf("\n"); + break; +@@ -952,17 +1013,25 @@ get_linkstate(int media_type, int link_s + return ("unknown link state"); + } + +-void +-print_baudrate(u_int64_t baudrate) ++const char * ++get_baudrate(u_int64_t baudrate, char *unit) + { ++ static char bbuf[16]; ++ + if (baudrate > IF_Gbps(1)) +- printf("%llu GBit/s", baudrate / IF_Gbps(1)); ++ snprintf(bbuf, sizeof(bbuf), "%llu G%s", ++ baudrate / IF_Gbps(1), unit); + else if (baudrate > IF_Mbps(1)) +- printf("%llu MBit/s", baudrate / IF_Mbps(1)); ++ snprintf(bbuf, sizeof(bbuf), "%llu M%s", ++ baudrate / IF_Mbps(1), unit); + else if (baudrate > IF_Kbps(1)) +- printf("%llu KBit/s", baudrate / IF_Kbps(1)); ++ snprintf(bbuf, sizeof(bbuf), "%llu K%s", ++ baudrate / IF_Kbps(1), unit); + else +- printf("%llu Bit/s", baudrate); ++ snprintf(bbuf, sizeof(bbuf), "%llu %s", ++ baudrate, unit); ++ ++ return (bbuf); + } + + int +@@ -987,8 +1056,7 @@ show_interface_msg(struct imsg *imsg) + printf("link state %u", k->link_state); + + if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { +- printf(", "); +- print_baudrate(k->baudrate); ++ printf(", %s", get_baudrate(k->baudrate, "Bit/s")); + } + printf("\n"); + break; +@@ -1186,8 +1254,8 @@ show_rib_detail_msg(struct imsg *imsg, i case ATTR_AGGREGATOR: memcpy(&as, data, sizeof(as)); memcpy(&id, data + sizeof(as), sizeof(id)); @@ -153,7 +298,7 @@ diff -u -p -r1.1.1.1 -r1.3 break; case ATTR_ORIGINATOR_ID: memcpy(&id, data, sizeof(id)); -@@ -1249,6 +1268,9 @@ show_rib_memory_msg(struct imsg *imsg) +@@ -1249,6 +1317,9 @@ show_rib_memory_msg(struct imsg *imsg) printf("%10lld IPv6 network entries using " "%s of memory\n", (long long)stats.pt6_cnt, fmt_mem(stats.pt6_cnt * sizeof(struct pt_entry6))); @@ -163,7 +308,7 @@ diff -u -p -r1.1.1.1 -r1.3 printf("%10lld prefix entries using %s of memory\n", (long long)stats.prefix_cnt, fmt_mem(stats.prefix_cnt * sizeof(struct prefix))); -@@ -1270,6 +1292,7 @@ show_rib_memory_msg(struct imsg *imsg) +@@ -1270,6 +1341,7 @@ show_rib_memory_msg(struct imsg *imsg) stats.pt4_cnt * sizeof(struct pt_entry4) + stats.pt6_cnt * sizeof(struct pt_entry6) + stats.prefix_cnt * sizeof(struct prefix) + diff --git a/net/openbgpd/files/patch-bgpd_bgpd.8 b/net/openbgpd/files/patch-bgpd_bgpd.8 index 6bb958544a8a..e7b5adbb402c 100644 --- a/net/openbgpd/files/patch-bgpd_bgpd.8 +++ b/net/openbgpd/files/patch-bgpd_bgpd.8 @@ -2,16 +2,25 @@ Index: bgpd/bgpd.8 =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.8,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.6 +diff -u -p -r1.1.1.1 -r1.6 --- bgpd/bgpd.8 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/bgpd.8 9 Jul 2009 17:22:14 -0000 1.4 ++++ bgpd/bgpd.8 22 Oct 2009 15:10:02 -0000 1.6 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.8,v 1.27 2007/05/31 19:20:22 jmc Exp $ -+.\" $OpenBSD: bgpd.8,v 1.28 2009/01/13 23:01:36 sthen Exp $ ++.\" $OpenBSD: bgpd.8,v 1.29 2009/08/06 08:53:11 claudio Exp $ .\" .\" Copyright (c) 2003, 2004 Henning Brauer .\" +@@ -14,7 +14,7 @@ + .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + .\" +-.Dd $Mdocdate: May 31 2007 $ ++.Dd $Mdocdate: September 2 2009 $ + .Dt BGPD 8 + .Os + .Sh NAME @@ -48,9 +48,9 @@ Please refer to that document for more i .Nm is usually started at boot time, and can be enabled by @@ -42,7 +51,29 @@ diff -u -p -r1.1.1.1 -r1.4 default .Nm configuration file -@@ -195,9 +195,9 @@ control socket +@@ -175,11 +175,6 @@ control socket + .%D September 2000 + .Re + .Rs +-.%R RFC 3392 +-.%T "Capabilities Advertisement with BGP-4" +-.%D January 1999 +-.Re +-.Rs + .%R RFC 3682 + .%T "The Generalized TTL Security Mechanism (GTSM)" + .%D February 2004 +@@ -190,14 +185,29 @@ control socket + .%D April 2004 + .Re + .Rs ++.%R RFC 4486 ++.%T "BGP Cease Notification Message Subcodes" ++.%D April 2006 ++.Re ++.Rs + .%R RFC 4760 + .%T "Multiprotocol Extensions for BGP-4" .%D January 2007 .Re .Rs @@ -51,6 +82,16 @@ diff -u -p -r1.1.1.1 -r1.4 .%T "BGP Support for Four-octet AS Number Space" -.%D February 2007 +.%D May 2007 ++.Re ++.Rs ++.%R RFC 5492 ++.%T "Capabilities Advertisement with BGP-4" ++.%D February 2009 ++.Re ++.Rs ++.%R draft-ietf-idr-optional-transitive-00 ++.%T "Error Handling for Optional Transitive BGP Attributes" ++.%D April 2009 .Re .Sh HISTORY The diff --git a/net/openbgpd/files/patch-bgpd_bgpd.c b/net/openbgpd/files/patch-bgpd_bgpd.c index 0d7c55e1054d..bdea87117a19 100644 --- a/net/openbgpd/files/patch-bgpd_bgpd.c +++ b/net/openbgpd/files/patch-bgpd_bgpd.c @@ -2,13 +2,13 @@ Index: bgpd/bgpd.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.3 +diff -u -p -r1.1.1.1 -r1.1.1.3 --- bgpd/bgpd.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/bgpd.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/bgpd.c 10 Aug 2009 21:09:57 -0000 1.1.1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.145 2008/05/12 19:15:02 pyr Exp $ */ -+/* $OpenBSD: bgpd.c,v 1.148 2009/06/07 00:30:23 claudio Exp $ */ ++/* $OpenBSD: bgpd.c,v 1.149 2009/07/20 15:00:13 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -61,7 +61,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 mrt_reconfigure(&mrt_l); -@@ -452,6 +459,7 @@ reconfigure(char *conffile, struct bgpd_ +@@ -452,10 +459,15 @@ reconfigure(char *conffile, struct bgpd_ struct peer *p; struct filter_rule *r; struct listen_addr *la; @@ -69,7 +69,15 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, rules_l)) { log_warnx("config file %s has errors, not reloading", -@@ -488,6 +496,15 @@ reconfigure(char *conffile, struct bgpd_ + conffile); ++ while ((rr = SIMPLEQ_FIRST(&ribnames))) { ++ SIMPLEQ_REMOVE_HEAD(&ribnames, entry); ++ free(rr); ++ } + return (1); + } + +@@ -488,6 +500,15 @@ reconfigure(char *conffile, struct bgpd_ la->fd = -1; } diff --git a/net/openbgpd/files/patch-bgpd_bgpd.conf.5 b/net/openbgpd/files/patch-bgpd_bgpd.conf.5 index 6d6792e545f6..bee730547c3b 100644 --- a/net/openbgpd/files/patch-bgpd_bgpd.conf.5 +++ b/net/openbgpd/files/patch-bgpd_bgpd.conf.5 @@ -2,10 +2,10 @@ Index: bgpd/bgpd.conf.5 =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.conf.5,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.5 +diff -u -p -r1.1.1.1 -r1.5 --- bgpd/bgpd.conf.5 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/bgpd.conf.5 9 Jul 2009 17:22:14 -0000 1.4 ++++ bgpd/bgpd.conf.5 22 Oct 2009 15:10:02 -0000 1.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.88 2008/03/22 08:38:38 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.94 2009/06/07 00:31:22 claudio Exp $ @@ -17,7 +17,7 @@ diff -u -p -r1.1.1.1 -r1.4 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 22 2008 $ -+.Dd $Mdocdate: June 4 2009 $ ++.Dd $Mdocdate: October 6 2009 $ .Dt BGPD.CONF 5 .Os .Sh NAME @@ -67,7 +67,7 @@ diff -u -p -r1.1.1.1 -r1.4 +.Ic rib Ar name +.Op Ic no Ic evaluate +.Xc -+Creat an additional RIB named ++Create an additional RIB named +.Ar name . +It is possible to disable the decision process per RIB with the +.Ic no Ic evaluate @@ -82,7 +82,55 @@ diff -u -p -r1.1.1.1 -r1.4 .Ic route-age .Pq Ic ignore Ns \&| Ns Ic evaluate .Xc -@@ -561,6 +589,12 @@ Inherited from the global configuration +@@ -455,6 +483,17 @@ Only routes for that address family and + announced and processed. + .Pp + .It Xo ++.Ic announce as-4byte ++.Pq Ic yes Ns \&| Ns Ic no ++.Xc ++If set to ++.Ic no , ++the 4-byte AS capability is not announced and so native 4-byte AS support is ++disabled. ++The default is ++.Ic yes . ++.Pp ++.It Xo + .Ic announce capabilities + .Pq Ic yes Ns \&| Ns Ic no + .Xc +@@ -465,6 +504,29 @@ This can be helpful to connect to old or + The default is + .Ic yes . + .Pp ++.It Xo ++.Ic announce refresh ++.Pq Ic yes Ns \&| Ns Ic no ++.Xc ++If set to ++.Ic no , ++the route refresh capability is not announced. ++The default is ++.Ic yes . ++.Pp ++.It Xo ++.Ic announce restart ++.Pq Ic yes Ns \&| Ns Ic no ++.Xc ++If set to ++.Ic yes , ++the graceful restart capability is announced. ++Currently only the End-of-RIB marker is supported and announced by the ++.Ic restart ++capability. ++The default is ++.Ic no . ++.Pp + .It Ic demote Ar group + Increase the + .Xr carp 4 +@@ -561,6 +623,12 @@ Inherited from the global configuration Set the minimal acceptable holdtime. Inherited from the global configuration if not given. .Pp @@ -95,7 +143,7 @@ diff -u -p -r1.1.1.1 -r1.4 .It Xo .Ic ipsec .Pq Ic ah Ns \&| Ns Ic esp -@@ -611,11 +645,11 @@ is responsible for managing the session +@@ -611,11 +679,11 @@ is responsible for managing the session With .Xr isakmpd 8 , it is sufficient to copy the peer's public key, found in @@ -109,17 +157,17 @@ diff -u -p -r1.1.1.1 -r1.4 The local public key must be copied to the peer in the same way. As .Xr bgpd 8 -@@ -670,6 +704,9 @@ Do not attempt to actively open a TCP co +@@ -670,6 +738,9 @@ Do not attempt to actively open a TCP co .It Ic remote-as Ar as-number Set the AS number of the remote system. .Pp -+.It rib .Ar name ++.It Ic rib Ar name +Bind the neighbor to the specified RIB. +.Pp .It Ic route-reflector Op Ar address Act as an RFC 2796 .Em route-reflector -@@ -728,6 +765,18 @@ tcp md5sig key deadbeef +@@ -728,6 +799,18 @@ tcp md5sig key deadbeef .Ed .Pp .It Xo @@ -138,7 +186,7 @@ diff -u -p -r1.1.1.1 -r1.4 .Ic ttl-security .Pq Ic yes Ns \&| Ns Ic no .Xc -@@ -1048,6 +1097,7 @@ will be adjusted by adding or subtractin +@@ -1048,6 +1131,7 @@ will be adjusted by adding or subtractin .Ar number ; otherwise it will be set to .Ar number . @@ -146,7 +194,7 @@ diff -u -p -r1.1.1.1 -r1.4 .Pp .It Ic med Ar number .It Ic metric Ar number -@@ -1137,8 +1187,8 @@ For prefixes with equally long paths, th +@@ -1137,8 +1221,8 @@ For prefixes with equally long paths, th is selected. .El .Sh FILES diff --git a/net/openbgpd/files/patch-bgpd_bgpd.h b/net/openbgpd/files/patch-bgpd_bgpd.h index 713df711b9db..74ff65d5d6b1 100644 --- a/net/openbgpd/files/patch-bgpd_bgpd.h +++ b/net/openbgpd/files/patch-bgpd_bgpd.h @@ -2,28 +2,25 @@ Index: bgpd/bgpd.h =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.h,v retrieving revision 1.1.1.1 -retrieving revision 1.5 -diff -u -p -r1.1.1.1 -r1.5 +retrieving revision 1.8 +diff -u -p -r1.1.1.1 -r1.8 --- bgpd/bgpd.h 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/bgpd.h 9 Jul 2009 17:22:14 -0000 1.5 ++++ bgpd/bgpd.h 22 Oct 2009 15:53:39 -0000 1.8 @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.222 2008/01/23 08:11:32 claudio Exp $ */ -+/* $OpenBSD: bgpd.h,v 1.241 2009/06/12 16:42:53 claudio Exp $ */ ++/* $OpenBSD: bgpd.h,v 1.243 2009/07/23 14:53:18 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer -@@ -27,12 +27,19 @@ - #include - #include +@@ -30,9 +30,16 @@ + #include + #include +#if defined(__FreeBSD__) /* compat */ +#include "openbsd-compat.h" +#endif /* defined(__FreeBSD__) */ ++#include "imsg.h" + - #include - #include -+#include - #define BGP_VERSION 4 #define BGP_PORT 179 +#ifndef CONFFILE @@ -248,7 +245,22 @@ diff -u -p -r1.1.1.1 -r1.5 }; struct kroute_nexthop { -@@ -510,7 +480,7 @@ struct ctl_show_rib { +@@ -473,8 +443,13 @@ struct pftable_msg { + + struct ctl_show_nexthop { + struct bgpd_addr addr; +- u_int8_t valid; + struct kif kif; ++ union { ++ struct kroute kr4; ++ struct kroute6 kr6; ++ } kr; ++ u_int8_t valid; ++ u_int8_t krvalid;; + }; + + struct ctl_neighbor { +@@ -510,7 +485,7 @@ struct ctl_show_rib { u_int32_t med; u_int32_t prefix_cnt; u_int32_t active_cnt; @@ -257,7 +269,7 @@ diff -u -p -r1.1.1.1 -r1.5 u_int16_t aspath_len; u_int16_t flags; u_int8_t prefixlen; -@@ -545,6 +515,7 @@ struct filter_community { +@@ -545,6 +520,7 @@ struct filter_community { }; struct ctl_show_rib_request { @@ -265,7 +277,7 @@ diff -u -p -r1.1.1.1 -r1.5 struct ctl_neighbor neighbor; struct bgpd_addr prefix; struct filter_as as; -@@ -590,6 +561,7 @@ enum comp_ops { +@@ -590,6 +566,7 @@ enum comp_ops { struct filter_peers { u_int32_t peerid; u_int32_t groupid; @@ -273,7 +285,7 @@ diff -u -p -r1.1.1.1 -r1.5 }; /* special community type */ -@@ -644,6 +616,7 @@ TAILQ_HEAD(filter_head, filter_rule); +@@ -644,6 +621,7 @@ TAILQ_HEAD(filter_head, filter_rule); struct filter_rule { TAILQ_ENTRY(filter_rule) entry; @@ -281,7 +293,7 @@ diff -u -p -r1.1.1.1 -r1.5 struct filter_peers peer; struct filter_match match; struct filter_set_head set; -@@ -697,6 +670,7 @@ struct rrefresh { +@@ -697,6 +675,7 @@ struct rrefresh { struct rde_memstats { int64_t path_cnt; int64_t prefix_cnt; @@ -289,7 +301,7 @@ diff -u -p -r1.1.1.1 -r1.5 int64_t pt4_cnt; int64_t pt6_cnt; int64_t nexthop_cnt; -@@ -709,6 +683,15 @@ struct rde_memstats { +@@ -709,6 +688,15 @@ struct rde_memstats { int64_t attr_dcnt; }; @@ -305,7 +317,13 @@ diff -u -p -r1.1.1.1 -r1.5 /* Address Family Numbers as per RFC 1700 */ #define AFI_IPv4 1 #define AFI_IPv6 2 -@@ -723,6 +706,18 @@ struct rde_memstats { +@@ -718,11 +706,24 @@ struct rde_memstats { + #define SAFI_NONE 0x00 + #define SAFI_UNICAST 0x01 + #define SAFI_MULTICAST 0x02 ++#define SAFI_MPLS 0x04 + #define SAFI_ALL 0xff + /* 4-byte magic AS number */ #define AS_TRANS 23456 @@ -324,7 +342,7 @@ diff -u -p -r1.1.1.1 -r1.5 /* prototypes */ /* bgpd.c */ void send_nexthop_update(struct kroute_nexthop *); -@@ -730,18 +725,6 @@ void send_imsg_session(int, pid_t, voi +@@ -730,18 +731,6 @@ void send_imsg_session(int, pid_t, voi int bgpd_redistribute(int, struct kroute *, struct kroute6 *); int bgpd_filternexthop(struct kroute *, struct kroute6 *); @@ -343,7 +361,7 @@ diff -u -p -r1.1.1.1 -r1.5 /* log.c */ void log_init(int); void vlog(int, const char *, va_list); -@@ -760,19 +743,6 @@ int cmdline_symset(char *); +@@ -760,19 +749,6 @@ int cmdline_symset(char *); /* config.c */ int host(const char *, struct bgpd_addr *, u_int8_t *); @@ -363,7 +381,7 @@ diff -u -p -r1.1.1.1 -r1.5 /* kroute.c */ int kr_init(int, u_int); int kr_change(struct kroute_label *); -@@ -788,10 +758,7 @@ void kr_nexthop_delete(struct bgpd_add +@@ -788,10 +764,7 @@ void kr_nexthop_delete(struct bgpd_add void kr_show_route(struct imsg *); void kr_ifinfo(char *); int kr_reload(void); @@ -374,7 +392,7 @@ diff -u -p -r1.1.1.1 -r1.5 /* control.c */ void control_cleanup(const char *); -@@ -806,6 +773,10 @@ int pftable_addr_remove(struct pftable_m +@@ -806,6 +779,10 @@ int pftable_addr_remove(struct pftable_m int pftable_commit(void); /* name2id.c */ @@ -385,7 +403,7 @@ diff -u -p -r1.1.1.1 -r1.5 u_int16_t rtlabel_name2id(const char *); const char *rtlabel_id2name(u_int16_t); void rtlabel_unref(u_int16_t); -@@ -829,5 +800,8 @@ const char *log_as(u_int32_t); +@@ -829,5 +806,8 @@ const char *log_as(u_int32_t); int aspath_snprint(char *, size_t, void *, u_int16_t); int aspath_asprint(char **, void *, u_int16_t); size_t aspath_strlen(void *, u_int16_t); diff --git a/net/openbgpd/files/patch-bgpd_buffer.c b/net/openbgpd/files/patch-bgpd_buffer.c index 371bf9ecf1f4..ccb9dc1d71bd 100644 --- a/net/openbgpd/files/patch-bgpd_buffer.c +++ b/net/openbgpd/files/patch-bgpd_buffer.c @@ -2,13 +2,13 @@ Index: bgpd/buffer.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/buffer.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.4 +diff -u -p -r1.1.1.1 -r1.1.1.4 --- bgpd/buffer.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/buffer.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/buffer.c 22 Oct 2009 14:24:02 -0000 1.1.1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.39 2008/03/24 16:11:02 deraadt Exp $ */ -+/* $OpenBSD: buffer.c,v 1.43 2009/06/06 06:33:15 eric Exp $ */ ++/* $OpenBSD: buffer.c,v 1.44 2009/07/23 18:58:42 eric Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -59,14 +59,14 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 - buf->buf = NULL; - buf->size = 0; + if (max < len) -+ return (NULL); -+ -+ if ((buf = buf_open(len)) == NULL) return (NULL); - } - buf->buf = p; - buf->size += len; ++ if ((buf = buf_open(len)) == NULL) ++ return (NULL); ++ + if (max > 0) + buf->max = max; @@ -151,7 +151,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 +buf_write(struct msgbuf *msgbuf) { + struct iovec iov[IOV_MAX]; -+ struct buf *buf, *next; ++ struct buf *buf; + unsigned int i = 0; ssize_t n; @@ -162,7 +162,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; -+ iov[i].iov_len = buf->size - buf->rpos; ++ iov[i].iov_len = buf->wpos - buf->rpos; + i++; + } + @@ -170,7 +170,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 if (errno == EAGAIN || errno == ENOBUFS || errno == EINTR) /* try later */ return (0); -@@ -116,11 +170,19 @@ buf_write(int sock, struct buf *buf) +@@ -116,11 +170,9 @@ buf_write(int sock, struct buf *buf) return (-2); } @@ -179,27 +179,44 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 - return (0); - } else - return (1); ++ msgbuf_drain(msgbuf, n); ++ ++ return (0); + } + + void +@@ -139,6 +191,24 @@ msgbuf_init(struct msgbuf *msgbuf) + } + + void ++msgbuf_drain(struct msgbuf *msgbuf, size_t n) ++{ ++ struct buf *buf, *next; ++ + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; + buf = next) { + next = TAILQ_NEXT(buf, entry); -+ if (buf->rpos + n >= buf->size) { -+ n -= buf->size - buf->rpos; ++ if (buf->rpos + n >= buf->wpos) { ++ n -= buf->wpos - buf->rpos; + buf_dequeue(msgbuf, buf); + } else { + buf->rpos += n; + n = 0; + } + } ++} + -+ return (0); - } - - void -@@ -152,13 +214,13 @@ msgbuf_write(struct msgbuf *msgbuf) ++void + msgbuf_clear(struct msgbuf *msgbuf) + { + struct buf *buf; +@@ -151,14 +221,14 @@ int + msgbuf_write(struct msgbuf *msgbuf) { struct iovec iov[IOV_MAX]; - struct buf *buf, *next; +- struct buf *buf, *next; - int i = 0; ++ struct buf *buf; + unsigned int i = 0; ssize_t n; struct msghdr msg; @@ -212,7 +229,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 } cmsgbuf; bzero(&iov, sizeof(iov)); -@@ -167,7 +229,7 @@ msgbuf_write(struct msgbuf *msgbuf) +@@ -167,7 +237,7 @@ msgbuf_write(struct msgbuf *msgbuf) if (i >= IOV_MAX) break; iov[i].iov_base = buf->buf + buf->rpos; @@ -221,14 +238,22 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 i++; if (buf->fd != -1) break; -@@ -211,8 +273,8 @@ msgbuf_write(struct msgbuf *msgbuf) - for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; - buf = next) { - next = TAILQ_NEXT(buf, entry); +@@ -208,17 +278,7 @@ msgbuf_write(struct msgbuf *msgbuf) + buf->fd = -1; + } + +- for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; +- buf = next) { +- next = TAILQ_NEXT(buf, entry); - if (buf->rpos + n >= buf->size) { - n -= buf->size - buf->rpos; -+ if (buf->rpos + n >= buf->wpos) { -+ n -= buf->wpos - buf->rpos; - buf_dequeue(msgbuf, buf); - } else { - buf->rpos += n; +- buf_dequeue(msgbuf, buf); +- } else { +- buf->rpos += n; +- n = 0; +- } +- } ++ msgbuf_drain(msgbuf, n); + + return (0); + } diff --git a/net/openbgpd/files/patch-bgpd_carp.c b/net/openbgpd/files/patch-bgpd_carp.c index 53dcacbec449..f8fdaf66b53f 100644 --- a/net/openbgpd/files/patch-bgpd_carp.c +++ b/net/openbgpd/files/patch-bgpd_carp.c @@ -2,10 +2,10 @@ Index: bgpd/carp.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/carp.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.4 +diff -u -p -r1.1.1.1 -r1.4 --- bgpd/carp.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/carp.c 9 Jul 2009 17:22:14 -0000 1.3 ++++ bgpd/carp.c 22 Oct 2009 15:10:02 -0000 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: carp.c,v 1.5 2007/04/23 14:52:28 claudio Exp $ */ +/* $OpenBSD: carp.c,v 1.6 2008/09/10 15:00:01 tobias Exp $ */ @@ -25,7 +25,19 @@ diff -u -p -r1.1.1.1 -r1.3 if (level > 0 || force) c->do_demote = 1; -@@ -102,6 +105,9 @@ carp_demote_shutdown(void) +@@ -90,9 +93,8 @@ carp_demote_shutdown(void) + + while ((c = TAILQ_FIRST(&carpgroups)) != NULL) { + TAILQ_REMOVE(&carpgroups, c, entry); +- for (; c->changed_by > 0; c->changed_by--) +- if (c->do_demote) +- carp_demote_ioctl(c->group, -1); ++ if (c->do_demote && c->changed_by > 0) ++ carp_demote_ioctl(c->group, -c->changed_by); + + free(c->group); + free(c); +@@ -102,6 +104,9 @@ carp_demote_shutdown(void) int carp_demote_get(char *group) { @@ -35,7 +47,7 @@ diff -u -p -r1.1.1.1 -r1.3 int s; struct ifgroupreq ifgr; -@@ -124,6 +130,7 @@ carp_demote_get(char *group) +@@ -124,6 +129,7 @@ carp_demote_get(char *group) close(s); return ((int)ifgr.ifgr_attrib.ifg_carp_demoted); @@ -43,7 +55,7 @@ diff -u -p -r1.1.1.1 -r1.3 } int -@@ -156,6 +163,9 @@ carp_demote_set(char *group, int demote) +@@ -156,6 +162,9 @@ carp_demote_set(char *group, int demote) int carp_demote_ioctl(char *group, int demote) { @@ -53,7 +65,7 @@ diff -u -p -r1.1.1.1 -r1.3 int s, res; struct ifgroupreq ifgr; -@@ -178,4 +188,5 @@ carp_demote_ioctl(char *group, int demot +@@ -178,4 +187,5 @@ carp_demote_ioctl(char *group, int demot close(s); return (res); diff --git a/net/openbgpd/files/patch-bgpd_control.c b/net/openbgpd/files/patch-bgpd_control.c index b858e4fd5e13..9402b5961f4b 100644 --- a/net/openbgpd/files/patch-bgpd_control.c +++ b/net/openbgpd/files/patch-bgpd_control.c @@ -2,16 +2,30 @@ Index: bgpd/control.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/control.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.3 +diff -u -p -r1.1.1.1 -r1.1.1.3 --- bgpd/control.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/control.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/control.c 22 Oct 2009 14:24:02 -0000 1.1.1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.60 2008/05/11 01:08:05 henning Exp $ */ +/* $OpenBSD: control.c,v 1.61 2009/05/05 20:09:19 sthen Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer +@@ -328,11 +328,11 @@ control_dispatch_msg(struct pollfd *pfd, + control_result(c, CTL_RES_OK); + break; + case IMSG_CTL_NEIGHBOR_DOWN: +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ERR_CEASE_ADMIN_DOWN); + control_result(c, CTL_RES_OK); + break; + case IMSG_CTL_NEIGHBOR_CLEAR: +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ERR_CEASE_ADMIN_RESET); + timer_set(p, Timer_IdleHold, + SESSION_CLEAR_DELAY); + control_result(c, CTL_RES_OK); @@ -396,6 +396,13 @@ control_dispatch_msg(struct pollfd *pfd, control_result(c, CTL_RES_NOCAP); break; diff --git a/net/openbgpd/files/patch-bgpd_imsg.c b/net/openbgpd/files/patch-bgpd_imsg.c index 32deac90e987..242a9aa8ca65 100644 --- a/net/openbgpd/files/patch-bgpd_imsg.c +++ b/net/openbgpd/files/patch-bgpd_imsg.c @@ -2,13 +2,13 @@ Index: bgpd/imsg.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/imsg.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.3 +diff -u -p -r1.1.1.1 -r1.1.1.3 --- bgpd/imsg.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/imsg.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/imsg.c 10 Aug 2009 21:09:57 -0000 1.1.1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.42 2008/03/24 16:11:02 deraadt Exp $ */ -+/* $OpenBSD: imsg.c,v 1.47 2009/06/08 08:30:06 dlg Exp $ */ ++/* $OpenBSD: imsg.c,v 1.48 2009/08/08 18:33:40 nicm Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -242,7 +242,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 } void -@@ -219,3 +250,19 @@ imsg_get_fd(struct imsgbuf *ibuf) +@@ -219,3 +250,22 @@ imsg_get_fd(struct imsgbuf *ibuf) return (fd); } @@ -259,6 +259,9 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 +void +imsg_clear(struct imsgbuf *ibuf) +{ -+ while (ibuf->w.queued) -+ msgbuf_clear(&ibuf->w); ++ int fd; ++ ++ msgbuf_clear(&ibuf->w); ++ while ((fd = imsg_get_fd(ibuf)) != -1) ++ close(fd); +} diff --git a/net/openbgpd/files/patch-bgpd_imsg.h b/net/openbgpd/files/patch-bgpd_imsg.h index a81694fd3793..d0efb9046949 100644 --- a/net/openbgpd/files/patch-bgpd_imsg.h +++ b/net/openbgpd/files/patch-bgpd_imsg.h @@ -3,8 +3,8 @@ Index: bgpd/imsg.h RCS file: bgpd/imsg.h diff -N bgpd/imsg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 -+++ bgpd/imsg.h 9 Jul 2009 16:49:54 -0000 1.1.1.1 -@@ -0,0 +1,108 @@ ++++ bgpd/imsg.h 22 Oct 2009 14:24:02 -0000 1.1.1.2 +@@ -0,0 +1,109 @@ +/* $OpenBSD: imsg.h,v 1.3 2009/06/07 05:56:24 eric Exp $ */ + +/* @@ -97,6 +97,7 @@ diff -N bgpd/imsg.h +void msgbuf_init(struct msgbuf *); +void msgbuf_clear(struct msgbuf *); +int msgbuf_write(struct msgbuf *); ++void msgbuf_drain(struct msgbuf *, size_t); + +/* imsg.c */ +void imsg_init(struct imsgbuf *, int); diff --git a/net/openbgpd/files/patch-bgpd_kroute.c b/net/openbgpd/files/patch-bgpd_kroute.c index c8df99557adb..f66f1819c955 100644 --- a/net/openbgpd/files/patch-bgpd_kroute.c +++ b/net/openbgpd/files/patch-bgpd_kroute.c @@ -2,13 +2,13 @@ Index: bgpd/kroute.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/kroute.c,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.5 +diff -u -p -r1.1.1.1 -r1.5 --- bgpd/kroute.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/kroute.c 9 Jul 2009 17:35:40 -0000 1.4 ++++ bgpd/kroute.c 10 Aug 2009 21:20:05 -0000 1.5 @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.160 2008/05/09 12:45:25 henning Exp $ */ -+/* $OpenBSD: kroute.c,v 1.169 2009/06/25 15:54:22 claudio Exp $ */ ++/* $OpenBSD: kroute.c,v 1.172 2009/07/23 14:53:20 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -180,7 +180,25 @@ diff -u -p -r1.1.1.1 -r1.4 break; case IMSG_CTL_KROUTE_ADDR: if (imsg->hdr.len != IMSG_HEADER_SIZE + -@@ -791,6 +805,14 @@ kroute_compare(struct kroute_node *a, st +@@ -573,11 +587,17 @@ kr_show_route(struct imsg *imsg) + case AF_INET: + kr = h->kroute; + snh.valid = kroute_validate(&kr->r); ++ snh.krvalid = 1; ++ memcpy(&snh.kr.kr4, &kr->r, ++ sizeof(snh.kr.kr4)); + ifindex = kr->r.ifindex; + break; + case AF_INET6: + kr6 = h->kroute; + snh.valid = kroute6_validate(&kr6->r); ++ snh.krvalid = 1; ++ memcpy(&snh.kr.kr6, &kr6->r, ++ sizeof(snh.kr.kr6)); + ifindex = kr6->r.ifindex; + break; + } +@@ -791,6 +811,14 @@ kroute_compare(struct kroute_node *a, st return (-1); if (a->r.prefixlen > b->r.prefixlen) return (1); @@ -195,7 +213,7 @@ diff -u -p -r1.1.1.1 -r1.4 return (0); } -@@ -810,6 +832,14 @@ kroute6_compare(struct kroute6_node *a, +@@ -810,32 +838,42 @@ kroute6_compare(struct kroute6_node *a, return (-1); if (a->r.prefixlen > b->r.prefixlen) return (1); @@ -210,7 +228,46 @@ diff -u -p -r1.1.1.1 -r1.4 return (0); } -@@ -853,27 +883,62 @@ kif_compare(struct kif_node *a, struct k + int + knexthop_compare(struct knexthop_node *a, struct knexthop_node *b) + { +- u_int32_t r; ++ int i; + + if (a->nexthop.af != b->nexthop.af) + return (b->nexthop.af - a->nexthop.af); + + switch (a->nexthop.af) { + case AF_INET: +- if ((r = b->nexthop.addr32[0] - a->nexthop.addr32[0]) != 0) +- return (r); ++ if (ntohl(a->nexthop.v4.s_addr) < ntohl(b->nexthop.v4.s_addr)) ++ return (-1); ++ if (ntohl(a->nexthop.v4.s_addr) > ntohl(b->nexthop.v4.s_addr)) ++ return (1); + break; + case AF_INET6: +- if ((r = b->nexthop.addr32[3] - a->nexthop.addr32[3]) != 0) +- return (r); +- if ((r = b->nexthop.addr32[2] - a->nexthop.addr32[2]) != 0) +- return (r); +- if ((r = b->nexthop.addr32[1] - a->nexthop.addr32[1]) != 0) +- return (r); +- if ((r = b->nexthop.addr32[0] - a->nexthop.addr32[0]) != 0) +- return (r); ++ for (i = 0; i < 16; i++) { ++ if (a->nexthop.v6.s6_addr[i] < b->nexthop.v6.s6_addr[i]) ++ return (-1); ++ if (a->nexthop.v6.s6_addr[i] > b->nexthop.v6.s6_addr[i]) ++ return (1); ++ } + break; ++ default: ++ fatalx("knexthop_compare: unknown AF"); + } + + return (0); +@@ -853,27 +891,62 @@ kif_compare(struct kif_node *a, struct k */ struct kroute_node * @@ -223,7 +280,8 @@ diff -u -p -r1.1.1.1 -r1.4 s.r.prefix.s_addr = prefix; s.r.prefixlen = prefixlen; + s.r.priority = prio; -+ + +- return (RB_FIND(kroute_tree, &krt, &s)); + kn = RB_FIND(kroute_tree, &krt, &s); + if (kn && prio == RTP_ANY) { + tmp = RB_PREV(kroute_tree, &krt, kn); @@ -242,8 +300,7 @@ diff -u -p -r1.1.1.1 -r1.4 +kroute_matchgw(struct kroute_node *kr, struct sockaddr_in *sa_in) +{ + in_addr_t nexthop; - -- return (RB_FIND(kroute_tree, &krt, &s)); ++ + if (sa_in == NULL) { + log_warnx("kroute_matchgw: no nexthop defined"); + return (NULL); @@ -280,7 +337,7 @@ diff -u -p -r1.1.1.1 -r1.4 } if (kr->r.flags & F_KERNEL) { -@@ -888,29 +953,61 @@ kroute_insert(struct kroute_node *kr) +@@ -888,29 +961,61 @@ kroute_insert(struct kroute_node *kr) if (kif_kr_insert(kr) == -1) return (-1); @@ -346,7 +403,7 @@ diff -u -p -r1.1.1.1 -r1.4 kr_redistribute(IMSG_NETWORK_REMOVE, &kr->r); if (kr->r.flags & F_CONNECTED) -@@ -933,27 +1030,62 @@ kroute_clear(void) +@@ -933,27 +1038,62 @@ kroute_clear(void) } struct kroute6_node * @@ -359,7 +416,8 @@ diff -u -p -r1.1.1.1 -r1.4 memcpy(&s.r.prefix, prefix, sizeof(struct in6_addr)); s.r.prefixlen = prefixlen; + s.r.priority = prio; -+ + +- return (RB_FIND(kroute6_tree, &krt6, &s)); + kn6 = RB_FIND(kroute6_tree, &krt6, &s); + if (kn6 && prio == RTP_ANY) { + tmp = RB_PREV(kroute6_tree, &krt6, kn6); @@ -390,8 +448,7 @@ diff -u -p -r1.1.1.1 -r1.4 + return (kr); + kr = kr->next; + } - -- return (RB_FIND(kroute6_tree, &krt6, &s)); ++ + return (NULL); } @@ -416,7 +473,7 @@ diff -u -p -r1.1.1.1 -r1.4 } if (kr->r.flags & F_KERNEL) { -@@ -970,7 +1102,9 @@ kroute6_insert(struct kroute6_node *kr) +@@ -970,7 +1110,9 @@ kroute6_insert(struct kroute6_node *kr) if (kif_kr6_insert(kr) == -1) return (-1); @@ -427,7 +484,7 @@ diff -u -p -r1.1.1.1 -r1.4 } return (0); -@@ -979,21 +1113,51 @@ kroute6_insert(struct kroute6_node *kr) +@@ -979,21 +1121,51 @@ kroute6_insert(struct kroute6_node *kr) int kroute6_remove(struct kroute6_node *kr) { @@ -482,7 +539,15 @@ diff -u -p -r1.1.1.1 -r1.4 kr_redistribute6(IMSG_NETWORK_REMOVE, &kr->r); if (kr->r.flags & F_CONNECTED) -@@ -1374,6 +1538,46 @@ knexthop_validate(struct knexthop_node * +@@ -1020,6 +1192,7 @@ knexthop_find(struct bgpd_addr *addr) + { + struct knexthop_node s; + ++ bzero(&s, sizeof(s)); + memcpy(&s.nexthop, addr, sizeof(s.nexthop)); + + return (RB_FIND(knexthop_tree, &knt, &s)); +@@ -1374,6 +1547,46 @@ knexthop_validate(struct knexthop_node * } } @@ -529,7 +594,7 @@ diff -u -p -r1.1.1.1 -r1.4 struct kroute_node * kroute_match(in_addr_t key, int matchall) { -@@ -1385,13 +1589,13 @@ kroute_match(in_addr_t key, int matchall +@@ -1385,13 +1598,13 @@ kroute_match(in_addr_t key, int matchall /* we will never match the default route */ for (i = 32; i > 0; i--) @@ -546,7 +611,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (matchall || bgpd_filternexthop(&kr->r, NULL) == 0) return (kr); -@@ -1408,13 +1612,13 @@ kroute6_match(struct in6_addr *key, int +@@ -1408,13 +1621,13 @@ kroute6_match(struct in6_addr *key, int /* we will never match the default route */ for (i = 128; i > 0; i--) { inet6applymask(&ina, key, i); @@ -562,7 +627,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (matchall || bgpd_filternexthop(NULL, &kr6->r) == 0) return (kr6); -@@ -1456,7 +1660,6 @@ kroute_detach_nexthop(struct knexthop_no +@@ -1456,7 +1669,6 @@ kroute_detach_nexthop(struct knexthop_no kn->kroute = NULL; } @@ -570,7 +635,7 @@ diff -u -p -r1.1.1.1 -r1.4 /* * misc helpers */ -@@ -1568,15 +1771,6 @@ mask2prefixlen6(struct sockaddr_in6 *sa_ +@@ -1568,15 +1780,6 @@ mask2prefixlen6(struct sockaddr_in6 *sa_ return (l); } @@ -586,7 +651,7 @@ diff -u -p -r1.1.1.1 -r1.4 struct in6_addr * prefixlen2mask6(u_int8_t prefixlen) { -@@ -1593,25 +1787,8 @@ prefixlen2mask6(u_int8_t prefixlen) +@@ -1593,25 +1796,8 @@ prefixlen2mask6(u_int8_t prefixlen) return (&mask); } @@ -614,7 +679,7 @@ diff -u -p -r1.1.1.1 -r1.4 void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) -@@ -1622,7 +1799,7 @@ get_rtaddrs(int addrs, struct sockaddr * +@@ -1622,7 +1808,7 @@ get_rtaddrs(int addrs, struct sockaddr * if (addrs & (1 << i)) { rti_info[i] = sa; sa = (struct sockaddr *)((char *)(sa) + @@ -623,7 +688,7 @@ diff -u -p -r1.1.1.1 -r1.4 } else rti_info[i] = NULL; } -@@ -1747,7 +1924,9 @@ send_rtmsg(int fd, int action, struct kr +@@ -1747,7 +1933,9 @@ send_rtmsg(int fd, int action, struct kr struct sockaddr_in prefix; struct sockaddr_in nexthop; struct sockaddr_in mask; @@ -633,7 +698,7 @@ diff -u -p -r1.1.1.1 -r1.4 int iovcnt = 0; if (kr_state.fib_sync == 0) -@@ -1757,9 +1936,13 @@ send_rtmsg(int fd, int action, struct kr +@@ -1757,9 +1945,13 @@ send_rtmsg(int fd, int action, struct kr bzero(&hdr, sizeof(hdr)); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = action; @@ -647,23 +712,23 @@ diff -u -p -r1.1.1.1 -r1.4 if (kroute->flags & F_BLACKHOLE) hdr.rtm_flags |= RTF_BLACKHOLE; if (kroute->flags & F_REJECT) -@@ -1809,6 +1992,7 @@ send_rtmsg(int fd, int action, struct kr +@@ -1808,6 +2000,7 @@ send_rtmsg(int fd, int action, struct kr + iov[iovcnt].iov_base = &mask; iov[iovcnt++].iov_len = sizeof(mask); - if (kroute->labelid) { +#if !defined(__FreeBSD__) /* FreeBSD has no route labeling. */ + if (kroute->labelid) { bzero(&label, sizeof(label)); label.sr_len = sizeof(label); - strlcpy(label.sr_label, rtlabel_id2name(kroute->labelid), -@@ -1819,6 +2003,7 @@ send_rtmsg(int fd, int action, struct kr - /* adjust iovec */ +@@ -1820,6 +2013,7 @@ send_rtmsg(int fd, int action, struct kr iov[iovcnt].iov_base = &label; iov[iovcnt++].iov_len = sizeof(label); -+#endif /* !defined(__FreeBSD__) */ } ++#endif /* !defined(__FreeBSD__) */ retry: -@@ -1857,10 +2042,13 @@ send_rt6msg(int fd, int action, struct k + if (writev(fd, iov, iovcnt) == -1) { +@@ -1857,10 +2051,13 @@ send_rt6msg(int fd, int action, struct k { struct iovec iov[5]; struct rt_msghdr hdr; @@ -680,7 +745,7 @@ diff -u -p -r1.1.1.1 -r1.4 int iovcnt = 0; if (kr_state.fib_sync == 0) -@@ -1870,7 +2058,9 @@ send_rt6msg(int fd, int action, struct k +@@ -1870,7 +2067,9 @@ send_rt6msg(int fd, int action, struct k bzero(&hdr, sizeof(hdr)); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = action; @@ -690,7 +755,7 @@ diff -u -p -r1.1.1.1 -r1.4 hdr.rtm_flags = RTF_PROTO1; if (kroute->flags & F_BLACKHOLE) hdr.rtm_flags |= RTF_BLACKHOLE; -@@ -1885,44 +2075,46 @@ send_rt6msg(int fd, int action, struct k +@@ -1885,44 +2084,46 @@ send_rt6msg(int fd, int action, struct k iov[iovcnt++].iov_len = sizeof(hdr); bzero(&prefix, sizeof(prefix)); @@ -752,7 +817,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (kroute->labelid) { bzero(&label, sizeof(label)); label.sr_len = sizeof(label); -@@ -1935,6 +2127,7 @@ send_rt6msg(int fd, int action, struct k +@@ -1935,6 +2136,7 @@ send_rt6msg(int fd, int action, struct k iov[iovcnt].iov_base = &label; iov[iovcnt++].iov_len = sizeof(label); } @@ -760,7 +825,7 @@ diff -u -p -r1.1.1.1 -r1.4 retry: if (writev(fd, iov, iovcnt) == -1) { -@@ -1949,7 +2142,7 @@ retry: +@@ -1949,7 +2151,7 @@ retry: kroute->prefixlen); return (0); } else { @@ -769,7 +834,7 @@ diff -u -p -r1.1.1.1 -r1.4 "prefix %s/%u: %s", hdr.rtm_type, log_in6addr(&kroute->prefix), kroute->prefixlen, strerror(errno)); -@@ -1957,7 +2150,7 @@ retry: +@@ -1957,7 +2159,7 @@ retry: } break; default: @@ -778,7 +843,7 @@ diff -u -p -r1.1.1.1 -r1.4 hdr.rtm_type, log_in6addr(&kroute->prefix), kroute->prefixlen, strerror(errno)); return (0); -@@ -1970,8 +2163,8 @@ retry: +@@ -1970,8 +2172,8 @@ retry: int fetchtable(u_int rtableid, int connected_only) { @@ -789,7 +854,7 @@ diff -u -p -r1.1.1.1 -r1.4 char *buf, *next, *lim; struct rt_msghdr *rtm; struct sockaddr *sa, *gw, *rti_info[RTAX_MAX]; -@@ -1986,9 +2179,8 @@ fetchtable(u_int rtableid, int connected +@@ -1986,9 +2188,8 @@ fetchtable(u_int rtableid, int connected mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; @@ -800,7 +865,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (rtableid != 0 && errno == EINVAL) /* table nonexistent */ return (0); log_warn("sysctl"); -@@ -1998,7 +2190,7 @@ fetchtable(u_int rtableid, int connected +@@ -1998,7 +2199,7 @@ fetchtable(u_int rtableid, int connected log_warn("fetchtable"); return (-1); } @@ -809,7 +874,7 @@ diff -u -p -r1.1.1.1 -r1.4 log_warn("sysctl"); free(buf); return (-1); -@@ -2007,7 +2199,13 @@ fetchtable(u_int rtableid, int connected +@@ -2007,7 +2208,13 @@ fetchtable(u_int rtableid, int connected lim = buf + len; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; @@ -824,7 +889,7 @@ diff -u -p -r1.1.1.1 -r1.4 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); if ((sa = rti_info[RTAX_DST]) == NULL) -@@ -2016,10 +2214,6 @@ fetchtable(u_int rtableid, int connected +@@ -2016,10 +2223,6 @@ fetchtable(u_int rtableid, int connected if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */ continue; @@ -835,27 +900,31 @@ diff -u -p -r1.1.1.1 -r1.4 switch (sa->sa_family) { case AF_INET: if ((kr = calloc(1, sizeof(struct kroute_node))) == -@@ -2030,6 +2224,9 @@ fetchtable(u_int rtableid, int connected +@@ -2030,6 +2233,11 @@ fetchtable(u_int rtableid, int connected } kr->r.flags = F_KERNEL; -+#if !defined(__FreeBSD__) /* no rtm_priority on FreeBSD */ ++#if defined(__FreeBSD__) /* no rtm_priority on FreeBSD */ + kr->r.priority = RTP_BGP; ++#else ++ kr->r.priority = rtm->rtm_priority; +#endif kr->r.ifindex = rtm->rtm_index; kr->r.prefix.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr; -@@ -2062,6 +2259,9 @@ fetchtable(u_int rtableid, int connected +@@ -2062,6 +2270,11 @@ fetchtable(u_int rtableid, int connected } kr6->r.flags = F_KERNEL; -+#if !defined(__FreeBSD__) /* no rtm_priority on FreeBSD */ -+ kr->r.priority = RTP_BGP; ++#if defined(__FreeBSD__) /* no rtm_priority on FreeBSD */ ++ kr6->r.priority = RTP_BGP; ++#else ++ kr6->r.priority = rtm->rtm_priority; +#endif kr6->r.ifindex = rtm->rtm_index; memcpy(&kr6->r.prefix, &((struct sockaddr_in6 *)sa)->sin6_addr, -@@ -2113,7 +2313,12 @@ fetchtable(u_int rtableid, int connected +@@ -2113,7 +2326,12 @@ fetchtable(u_int rtableid, int connected } if (sa->sa_family == AF_INET) { @@ -869,7 +938,7 @@ diff -u -p -r1.1.1.1 -r1.4 send_rtmsg(kr_state.fd, RTM_DELETE, &kr->r); free(kr); } else if (connected_only && -@@ -2122,7 +2327,12 @@ fetchtable(u_int rtableid, int connected +@@ -2122,7 +2340,12 @@ fetchtable(u_int rtableid, int connected else kroute_insert(kr); } else if (sa->sa_family == AF_INET6) { @@ -883,7 +952,7 @@ diff -u -p -r1.1.1.1 -r1.4 send_rt6msg(kr_state.fd, RTM_DELETE, &kr6->r); free(kr6); } else if (connected_only && -@@ -2234,12 +2444,18 @@ dispatch_rtmsg(void) +@@ -2234,12 +2457,18 @@ dispatch_rtmsg(void) lim = buf + n; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; @@ -903,7 +972,7 @@ diff -u -p -r1.1.1.1 -r1.4 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); if (rtm->rtm_pid == kr_state.pid) /* cause by us */ -@@ -2252,12 +2468,14 @@ dispatch_rtmsg(void) +@@ -2252,12 +2481,14 @@ dispatch_rtmsg(void) continue; connected_only = 0; @@ -918,7 +987,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (dispatch_rtmsg_addr(rtm, rti_info, connected_only) == -1) -@@ -2289,9 +2507,10 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2289,9 +2520,10 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt struct kroute_node *kr; struct kroute6_node *kr6; struct bgpd_addr prefix; @@ -930,7 +999,7 @@ diff -u -p -r1.1.1.1 -r1.4 flags = F_KERNEL; ifindex = 0; -@@ -2309,7 +2528,16 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2309,7 +2541,16 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt flags |= F_REJECT; if (rtm->rtm_flags & RTF_DYNAMIC) flags |= F_DYNAMIC; @@ -947,7 +1016,7 @@ diff -u -p -r1.1.1.1 -r1.4 prefix.af = sa->sa_family; switch (prefix.af) { case AF_INET: -@@ -2341,22 +2569,54 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2341,22 +2582,54 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt return (0); } @@ -1004,7 +1073,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (kroute6_remove(kr6) == -1) return (-1); break; -@@ -2364,15 +2624,6 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2364,15 +2637,6 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt return (0); } @@ -1020,7 +1089,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (connected_only && !(flags & F_CONNECTED)) return (0); -@@ -2385,8 +2636,18 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2385,8 +2649,18 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt switch (prefix.af) { case AF_INET: sa_in = (struct sockaddr_in *)sa; @@ -1040,7 +1109,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (sa_in != NULL) kr->r.nexthop.s_addr = sa_in->sin_addr.s_addr; -@@ -2409,12 +2670,15 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2409,12 +2683,15 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt kr_redistribute(IMSG_NETWORK_ADD, &kr->r); } @@ -1056,7 +1125,7 @@ diff -u -p -r1.1.1.1 -r1.4 if ((kr = calloc(1, sizeof(struct kroute_node))) == NULL) { log_warn("dispatch_rtmsg"); -@@ -2428,14 +2692,25 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2428,14 +2705,25 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt kr->r.nexthop.s_addr = 0; kr->r.flags = flags; kr->r.ifindex = ifindex; @@ -1083,7 +1152,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (sa_in6 != NULL) memcpy(&kr6->r.nexthop, &sa_in6->sin6_addr, -@@ -2461,12 +2736,15 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2461,12 +2749,15 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt kr_redistribute6(IMSG_NETWORK_ADD, &kr6->r); } @@ -1099,7 +1168,7 @@ diff -u -p -r1.1.1.1 -r1.4 if ((kr6 = calloc(1, sizeof(struct kroute6_node))) == NULL) { log_warn("dispatch_rtmsg"); -@@ -2483,6 +2761,7 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt +@@ -2483,6 +2774,7 @@ dispatch_rtmsg_addr(struct rt_msghdr *rt sizeof(struct in6_addr)); kr6->r.flags = flags; kr6->r.ifindex = ifindex; diff --git a/net/openbgpd/files/patch-bgpd_mrt.c b/net/openbgpd/files/patch-bgpd_mrt.c index 76853d017910..e7cad7121912 100644 --- a/net/openbgpd/files/patch-bgpd_mrt.c +++ b/net/openbgpd/files/patch-bgpd_mrt.c @@ -2,13 +2,13 @@ Index: bgpd/mrt.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/mrt.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.3 +diff -u -p -r1.1.1.1 -r1.1.1.3 --- bgpd/mrt.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/mrt.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/mrt.c 10 Aug 2009 21:09:57 -0000 1.1.1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: mrt.c,v 1.53 2007/04/23 13:04:24 claudio Exp $ */ -+/* $OpenBSD: mrt.c,v 1.63 2009/06/29 12:22:16 claudio Exp $ */ ++/* $OpenBSD: mrt.c,v 1.64 2009/07/12 15:36:41 jsg Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker @@ -553,7 +553,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 +fail: + if (hbuf) + buf_free(hbuf); -+ if (h2buf); ++ if (h2buf) + buf_free(h2buf); + buf_free(buf); + return (-1); diff --git a/net/openbgpd/files/patch-bgpd_parse.y b/net/openbgpd/files/patch-bgpd_parse.y index d51dda7cc8b0..ac37d5be9483 100644 --- a/net/openbgpd/files/patch-bgpd_parse.y +++ b/net/openbgpd/files/patch-bgpd_parse.y @@ -2,13 +2,13 @@ Index: bgpd/parse.y =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/parse.y,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.6 +diff -u -p -r1.1.1.1 -r1.6 --- bgpd/parse.y 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/parse.y 9 Jul 2009 17:22:14 -0000 1.4 ++++ bgpd/parse.y 22 Oct 2009 15:10:02 -0000 1.6 @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.217 2008/07/08 13:14:58 claudio Exp $ */ -+/* $OpenBSD: parse.y,v 1.231 2009/06/06 01:10:29 claudio Exp $ */ ++/* $OpenBSD: parse.y,v 1.233 2009/08/03 13:14:07 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -32,7 +32,7 @@ diff -u -p -r1.1.1.1 -r1.4 int get_id(struct peer *); int expand_rule(struct filter_rule *, struct filter_peers_l *, struct filter_match_l *, struct filter_set_head *); -@@ -155,10 +159,10 @@ typedef struct { +@@ -155,11 +159,11 @@ typedef struct { %} %token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE RTABLE @@ -41,11 +41,13 @@ diff -u -p -r1.1.1.1 -r1.4 %token GROUP NEIGHBOR NETWORK -%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART -%token ANNOUNCE DEMOTE +-%token ENFORCE NEIGHBORAS CAPABILITIES REFLECTOR DEPEND DOWN SOFTRECONFIG +%token REMOTEAS DESCR LLIFACE LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART -+%token ANNOUNCE DEMOTE CONNECTRETRY - %token ENFORCE NEIGHBORAS CAPABILITIES REFLECTOR DEPEND DOWN SOFTRECONFIG ++%token ANNOUNCE CAPABILITIES REFRESH AS4BYTE CONNECTRETRY ++%token DEMOTE ENFORCE NEIGHBORAS REFLECTOR DEPEND DOWN SOFTRECONFIG %token DUMP IN OUT %token LOG ROUTECOLL TRANSPARENT + %token TCP MD5SIG PASSWORD KEY TTLSECURITY @@ -178,7 +182,7 @@ typedef struct { %token NUMBER %type asnumber as4number optnumber yesno inout @@ -55,18 +57,31 @@ diff -u -p -r1.1.1.1 -r1.4 %type address %type prefix addrspec %type action quick direction delete -@@ -207,8 +211,8 @@ grammar : /* empty */ +@@ -207,8 +211,12 @@ grammar : /* empty */ ; asnumber : NUMBER { - if ($1 < 0 || $1 >= USHRT_MAX) { - yyerror("AS too big: max %u", USHRT_MAX - 1); -+ if ($1 < 0 || $1 >= ASNUM_MAX) { -+ yyerror("AS too big: max %u", ASNUM_MAX - 1); ++ /* ++ * Accroding to iana 65535 and 4294967295 are reserved ++ * but enforcing this is not duty of the parser. ++ */ ++ if ($1 < 0 || $1 > UINT_MAX) { ++ yyerror("AS too big: max %u", UINT_MAX); YYERROR; } } -@@ -381,6 +385,24 @@ conf_main : AS as4number { +@@ -270,6 +278,8 @@ yesno : STRING { + else if (!strcmp($1, "no")) + $$ = 0; + else { ++ yyerror("syntax error, " ++ "either yes or no expected"); + free($1); + YYERROR; + } +@@ -381,6 +391,24 @@ conf_main : AS as4number { else conf->flags &= ~BGPD_FLAG_NO_EVALUATE; } @@ -82,7 +97,7 @@ diff -u -p -r1.1.1.1 -r1.4 + free($3); + YYERROR; + } -+ if (!add_rib($3, F_RIB_NOEVALUATE)) { ++ if (!add_rib($3, F_RIB_NOFIB | F_RIB_NOEVALUATE)) { + free($3); + YYERROR; + } @@ -91,7 +106,7 @@ diff -u -p -r1.1.1.1 -r1.4 | TRANSPARENT yesno { if ($2 == 1) conf->flags |= BGPD_FLAG_DECISION_TRANS_AS; -@@ -469,12 +491,42 @@ conf_main : AS as4number { +@@ -469,12 +497,42 @@ conf_main : AS as4number { YYERROR; } free($2); @@ -135,7 +150,7 @@ diff -u -p -r1.1.1.1 -r1.4 | mrtdump | RDE STRING EVALUATE { if (!strcmp($2, "route-age")) -@@ -523,11 +575,23 @@ conf_main : AS as4number { +@@ -523,11 +581,23 @@ conf_main : AS as4number { free($4); } | RTABLE NUMBER { @@ -159,7 +174,7 @@ diff -u -p -r1.1.1.1 -r1.4 } ; -@@ -550,7 +614,8 @@ mrtdump : DUMP STRING inout STRING optn +@@ -550,7 +620,8 @@ mrtdump : DUMP STRING inout STRING optn free($4); YYERROR; } @@ -169,7 +184,28 @@ diff -u -p -r1.1.1.1 -r1.4 free($2); free($4); YYERROR; -@@ -742,6 +807,17 @@ peeropts : REMOTEAS as4number { +@@ -653,6 +724,20 @@ neighbor : { curpeer = new_peer(); } + if (($3.prefix.af == AF_INET && $3.len != 32) || + ($3.prefix.af == AF_INET6 && $3.len != 128)) + curpeer->conf.template = 1; ++ switch (curpeer->conf.remote_addr.af) { ++ case AF_INET: ++ if (curpeer->conf.capabilities.mp_v4 != ++ SAFI_ALL) ++ break; ++ curpeer->conf.capabilities.mp_v4 = SAFI_UNICAST; ++ break; ++ case AF_INET6: ++ if (curpeer->conf.capabilities.mp_v6 != ++ SAFI_ALL) ++ break; ++ curpeer->conf.capabilities.mp_v6 = SAFI_UNICAST; ++ break; ++ } + if (get_id(curpeer)) { + yyerror("get_id failed"); + YYERROR; +@@ -742,6 +827,17 @@ peeropts : REMOTEAS as4number { } free($2); } @@ -187,7 +223,7 @@ diff -u -p -r1.1.1.1 -r1.4 | LOCALADDR address { memcpy(&curpeer->conf.local_addr, &$2, sizeof(curpeer->conf.local_addr)); -@@ -759,6 +835,22 @@ peeropts : REMOTEAS as4number { +@@ -759,6 +855,22 @@ peeropts : REMOTEAS as4number { | DOWN { curpeer->conf.down = 1; } @@ -210,7 +246,31 @@ diff -u -p -r1.1.1.1 -r1.4 | HOLDTIME NUMBER { if ($2 < MIN_HOLDTIME || $2 > USHRT_MAX) { yyerror("holdtime must be between %u and %u", -@@ -1058,6 +1150,12 @@ peeropts : REMOTEAS as4number { +@@ -804,11 +916,22 @@ peeropts : REMOTEAS as4number { + | ANNOUNCE CAPABILITIES yesno { + curpeer->conf.announce_capa = $3; + } ++ | ANNOUNCE REFRESH yesno { ++ curpeer->conf.capabilities.refresh = $3; ++ } ++ | ANNOUNCE RESTART yesno { ++ curpeer->conf.capabilities.restart = $3; ++ } ++ | ANNOUNCE AS4BYTE yesno { ++ curpeer->conf.capabilities.as4byte = $3; ++ } + | ANNOUNCE SELF { + curpeer->conf.announce_type = ANNOUNCE_SELF; + } + | ANNOUNCE STRING { +- if (!strcmp($2, "none")) ++ if (!strcmp($2, "self")) ++ curpeer->conf.announce_type = ANNOUNCE_SELF; ++ else if (!strcmp($2, "none")) + curpeer->conf.announce_type = ANNOUNCE_NONE; + else if (!strcmp($2, "all")) + curpeer->conf.announce_type = ANNOUNCE_ALL; +@@ -1058,6 +1181,12 @@ peeropts : REMOTEAS as4number { else curpeer->conf.softreconfig_out = $3; } @@ -223,7 +283,7 @@ diff -u -p -r1.1.1.1 -r1.4 ; restart : /* nada */ { $$ = 0; } -@@ -1115,16 +1213,37 @@ encspec : /* nada */ { +@@ -1115,16 +1244,37 @@ encspec : /* nada */ { } ; @@ -265,7 +325,7 @@ diff -u -p -r1.1.1.1 -r1.4 YYERROR; } ; -@@ -1142,6 +1261,9 @@ direction : FROM { $$ = DIR_IN; } +@@ -1142,6 +1292,9 @@ direction : FROM { $$ = DIR_IN; } | TO { $$ = DIR_OUT; } ; @@ -275,7 +335,7 @@ diff -u -p -r1.1.1.1 -r1.4 filter_peer_h : filter_peer | '{' filter_peer_l '}' { $$ = $2; } ; -@@ -1396,7 +1518,7 @@ prefixlenop : unaryop NUMBER { +@@ -1396,7 +1549,7 @@ prefixlenop : unaryop NUMBER { YYERROR; } if ($1 >= $3) { @@ -284,7 +344,12 @@ diff -u -p -r1.1.1.1 -r1.4 YYERROR; } $$.op = $2; -@@ -1771,6 +1893,7 @@ lookup(char *s) +@@ -1767,10 +1920,12 @@ lookup(char *s) + { "allow", ALLOW}, + { "announce", ANNOUNCE}, + { "any", ANY}, ++ { "as-4byte", AS4BYTE }, + { "blackhole", BLACKHOLE}, { "capabilities", CAPABILITIES}, { "community", COMMUNITY}, { "compare", COMPARE}, @@ -292,7 +357,7 @@ diff -u -p -r1.1.1.1 -r1.4 { "connected", CONNECTED}, { "delete", DELETE}, { "demote", DEMOTE}, -@@ -1792,6 +1915,9 @@ lookup(char *s) +@@ -1792,6 +1947,9 @@ lookup(char *s) { "include", INCLUDE}, { "inet", IPV4}, { "inet6", IPV6}, @@ -302,7 +367,11 @@ diff -u -p -r1.1.1.1 -r1.4 { "ipsec", IPSEC}, { "key", KEY}, { "listen", LISTEN}, -@@ -1826,6 +1952,7 @@ lookup(char *s) +@@ -1823,9 +1981,11 @@ lookup(char *s) + { "qualify", QUALIFY}, + { "quick", QUICK}, + { "rde", RDE}, ++ { "refresh", REFRESH }, { "reject", REJECT}, { "remote-as", REMOTEAS}, { "restart", RESTART}, @@ -310,7 +379,7 @@ diff -u -p -r1.1.1.1 -r1.4 { "route-collector", ROUTECOLL}, { "route-reflector", REFLECTOR}, { "router-id", ROUTERID}, -@@ -1933,11 +2060,13 @@ findeol(void) +@@ -1933,11 +2093,13 @@ findeol(void) int c; parsebuf = NULL; @@ -326,23 +395,25 @@ diff -u -p -r1.1.1.1 -r1.4 if (c == '\n') { file->lineno++; break; -@@ -2118,9 +2247,13 @@ pushfile(const char *name, int secret) +@@ -2118,11 +2280,15 @@ pushfile(const char *name, int secret) { struct file *nfile; - if ((nfile = calloc(1, sizeof(struct file))) == NULL || - (nfile->name = strdup(name)) == NULL) { + if ((nfile = calloc(1, sizeof(struct file))) == NULL) { -+ log_warn("malloc"); -+ return (NULL); -+ } -+ if ((nfile->name = strdup(name)) == NULL) { log_warn("malloc"); -+ free(nfile); return (NULL); } ++ if ((nfile->name = strdup(name)) == NULL) { ++ log_warn("malloc"); ++ free(nfile); ++ return (NULL); ++ } if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { -@@ -2207,6 +2340,9 @@ parse_config(char *filename, struct bgpd + log_warn("%s", nfile->name); + free(nfile->name); +@@ -2207,6 +2373,9 @@ parse_config(char *filename, struct bgpd /* init the empty filter list for later */ TAILQ_INIT(xfilter_l); @@ -352,16 +423,24 @@ diff -u -p -r1.1.1.1 -r1.4 yyparse(); errors = file->errors; popfile(); -@@ -2452,6 +2588,8 @@ alloc_peer(void) +@@ -2447,11 +2616,13 @@ alloc_peer(void) + p->conf.distance = 1; + p->conf.announce_type = ANNOUNCE_UNDEF; + p->conf.announce_capa = 1; +- p->conf.capabilities.mp_v4 = SAFI_UNICAST; +- p->conf.capabilities.mp_v6 = SAFI_NONE; ++ p->conf.capabilities.mp_v4 = SAFI_ALL; ++ p->conf.capabilities.mp_v6 = SAFI_ALL; p->conf.capabilities.refresh = 1; p->conf.capabilities.restart = 0; - p->conf.capabilities.as4byte = 0; +- p->conf.capabilities.as4byte = 0; ++ p->conf.capabilities.as4byte = 1; + p->conf.local_as = conf->as; + p->conf.local_short_as = conf->short_as; p->conf.softreconfig_in = 1; p->conf.softreconfig_out = 1; -@@ -2473,10 +2611,16 @@ new_peer(void) +@@ -2473,10 +2644,16 @@ new_peer(void) if (strlcpy(p->conf.descr, curgroup->conf.descr, sizeof(p->conf.descr)) >= sizeof(p->conf.descr)) fatalx("new_peer descr strlcpy"); @@ -379,7 +458,7 @@ diff -u -p -r1.1.1.1 -r1.4 return (p); } -@@ -2487,11 +2631,15 @@ new_group(void) +@@ -2487,11 +2664,15 @@ new_group(void) } int @@ -396,7 +475,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (p == NULL) { if (m->peer_id != 0 || m->group_id != 0) continue; -@@ -2527,6 +2675,20 @@ add_mrtconfig(enum mrt_type type, char * +@@ -2527,6 +2708,20 @@ add_mrtconfig(enum mrt_type type, char * n->group_id = 0; } } @@ -417,7 +496,7 @@ diff -u -p -r1.1.1.1 -r1.4 LIST_INSERT_HEAD(mrtconf, n, entry); -@@ -2534,6 +2696,42 @@ add_mrtconfig(enum mrt_type type, char * +@@ -2534,6 +2729,42 @@ add_mrtconfig(enum mrt_type type, char * } int @@ -460,3 +539,27 @@ diff -u -p -r1.1.1.1 -r1.4 get_id(struct peer *newpeer) { struct peer *p; +@@ -2713,10 +2944,6 @@ neighbor_consistent(struct peer *p) + return (-1); + } + +- /* for testing: enable 4-byte AS number capability if necessary */ +- if (conf->as > USHRT_MAX || p->conf.remote_as > USHRT_MAX) +- p->conf.capabilities.as4byte = 1; +- + /* set default values if they where undefined */ + p->conf.ebgp = (p->conf.remote_as != conf->as); + if (p->conf.announce_type == ANNOUNCE_UNDEF) +@@ -2733,6 +2960,12 @@ neighbor_consistent(struct peer *p) + return (-1); + } + ++ /* the default MP capability is NONE */ ++ if (p->conf.capabilities.mp_v4 == SAFI_ALL) ++ p->conf.capabilities.mp_v4 = SAFI_NONE; ++ if (p->conf.capabilities.mp_v6 == SAFI_ALL) ++ p->conf.capabilities.mp_v6 = SAFI_NONE; ++ + return (0); + } + diff --git a/net/openbgpd/files/patch-bgpd_printconf.c b/net/openbgpd/files/patch-bgpd_printconf.c index a341234905a5..ae33630ad4bf 100644 --- a/net/openbgpd/files/patch-bgpd_printconf.c +++ b/net/openbgpd/files/patch-bgpd_printconf.c @@ -2,10 +2,10 @@ Index: bgpd/printconf.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/printconf.c,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.5 +diff -u -p -r1.1.1.1 -r1.5 --- bgpd/printconf.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/printconf.c 9 Jul 2009 17:22:14 -0000 1.4 ++++ bgpd/printconf.c 22 Oct 2009 15:10:02 -0000 1.5 @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.65 2007/11/22 11:37:25 henning Exp $ */ +/* $OpenBSD: printconf.c,v 1.70 2009/06/06 01:10:29 claudio Exp $ */ @@ -55,7 +55,20 @@ diff -u -p -r1.1.1.1 -r1.4 if (p->remote_as) printf("%s\tremote-as %s\n", c, log_as(p->remote_as)); if (p->down) -@@ -320,6 +325,12 @@ print_peer(struct peer_config *p, struct +@@ -293,6 +298,12 @@ print_peer(struct peer_config *p, struct + printf("%s\tholdtime min %u\n", c, p->min_holdtime); + if (p->announce_capa == 0) + printf("%s\tannounce capabilities no\n", c); ++ if (p->capabilities.refresh == 0) ++ printf("%s\tannounce refresh no\n", c); ++ if (p->capabilities.restart == 1) ++ printf("%s\tannounce restart yes\n", c); ++ if (p->capabilities.as4byte == 0) ++ printf("%s\tannounce as4byte no\n", c); + if (p->announce_type == ANNOUNCE_SELF) + printf("%s\tannounce self\n", c); + else if (p->announce_type == ANNOUNCE_NONE) +@@ -320,6 +331,12 @@ print_peer(struct peer_config *p, struct printf("%s\tdemote %s\n", c, p->demote_group); if (p->if_depend[0]) printf("%s\tdepend on \"%s\"\n", c, p->if_depend); @@ -68,7 +81,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (p->auth.method == AUTH_MD5SIG) printf("%s\ttcp md5sig\n", c); -@@ -419,10 +430,12 @@ print_rule(struct peer *peer_l, struct f +@@ -419,10 +436,12 @@ print_rule(struct peer *peer_l, struct f printf("deny "); else printf("match "); @@ -82,7 +95,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (r->dir == DIR_IN) printf("from "); else if (r->dir == DIR_OUT) -@@ -532,12 +545,14 @@ print_mrt(u_int32_t pid, u_int32_t gid, +@@ -532,12 +551,14 @@ print_mrt(u_int32_t pid, u_int32_t gid, LIST_FOREACH(m, xmrt_l, entry) if ((gid != 0 && m->group_id == gid) || (m->peer_id == pid && m->group_id == gid)) { @@ -101,7 +114,7 @@ diff -u -p -r1.1.1.1 -r1.4 MRT2MC(m)->name, MRT2MC(m)->ReopenTimerInterval); } -@@ -602,16 +617,25 @@ peer_compare(const void *aa, const void +@@ -602,16 +623,25 @@ peer_compare(const void *aa, const void } void diff --git a/net/openbgpd/files/patch-bgpd_rde.c b/net/openbgpd/files/patch-bgpd_rde.c index 2575431261c4..f31d1d4c5ec2 100644 --- a/net/openbgpd/files/patch-bgpd_rde.c +++ b/net/openbgpd/files/patch-bgpd_rde.c @@ -2,13 +2,13 @@ Index: bgpd/rde.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde.c,v retrieving revision 1.1.1.1 -retrieving revision 1.4 -diff -u -p -r1.1.1.1 -r1.4 +retrieving revision 1.6 +diff -u -p -r1.1.1.1 -r1.6 --- bgpd/rde.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde.c 9 Jul 2009 17:26:41 -0000 1.4 ++++ bgpd/rde.c 22 Oct 2009 15:10:02 -0000 1.6 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.232.2.1 2009/01/30 22:37:34 claudio Exp $ */ -+/* $OpenBSD: rde.c,v 1.264 2009/06/29 12:22:16 claudio Exp $ */ ++/* $OpenBSD: rde.c,v 1.265 2009/08/06 08:53:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -44,7 +44,7 @@ diff -u -p -r1.1.1.1 -r1.4 const struct rde_peer *, const struct bgpd_addr *, const struct bgpd_addr *, u_int8_t); void rde_as4byte_fixup(struct rde_peer *, struct rde_aspath *); -@@ -67,19 +71,16 @@ void rde_dump_filter(struct prefix *, +@@ -67,19 +71,17 @@ void rde_dump_filter(struct prefix *, struct ctl_show_rib_request *); void rde_dump_filterout(struct rde_peer *, struct prefix *, struct ctl_show_rib_request *); @@ -68,10 +68,11 @@ diff -u -p -r1.1.1.1 -r1.4 +void rde_up_dump_upcall(struct rib_entry *, void *); +void rde_softreconfig_out(struct rib_entry *, void *); +void rde_softreconfig_in(struct rib_entry *, void *); ++void rde_softreconfig_load(struct rib_entry *, void *); void rde_update_queue_runner(void); void rde_update6_queue_runner(void); -@@ -96,8 +97,7 @@ void peer_send_eor(struct rde_peer *, +@@ -96,8 +98,7 @@ void peer_send_eor(struct rde_peer *, void network_init(struct network_head *); void network_add(struct network_config *, int); void network_delete(struct network_config *, int); @@ -81,7 +82,7 @@ diff -u -p -r1.1.1.1 -r1.4 void rde_shutdown(void); int sa_cmp(struct bgpd_addr *, struct sockaddr *); -@@ -106,23 +106,26 @@ volatile sig_atomic_t rde_quit = 0; +@@ -106,23 +107,26 @@ volatile sig_atomic_t rde_quit = 0; struct bgpd_config *conf, *nconf; time_t reloadtime; struct rde_peer_head peerlist; @@ -114,7 +115,7 @@ diff -u -p -r1.1.1.1 -r1.4 void rde_sighdlr(int sig) -@@ -143,18 +146,22 @@ u_int32_t nexthophashsize = 64; +@@ -143,18 +147,22 @@ u_int32_t nexthophashsize = 64; pid_t rde_main(struct bgpd_config *config, struct peer *peer_l, struct network_head *net_l, struct filter_head *rules, @@ -141,7 +142,7 @@ diff -u -p -r1.1.1.1 -r1.4 switch (pid = fork()) { case -1: -@@ -213,7 +220,6 @@ rde_main(struct bgpd_config *config, str +@@ -213,7 +221,6 @@ rde_main(struct bgpd_config *config, str LIST_REMOVE(mrt, entry); free(mrt); } @@ -149,7 +150,7 @@ diff -u -p -r1.1.1.1 -r1.4 while ((la = TAILQ_FIRST(config->listen_addrs)) != NULL) { TAILQ_REMOVE(config->listen_addrs, la, entry); -@@ -223,6 +229,11 @@ rde_main(struct bgpd_config *config, str +@@ -223,6 +230,11 @@ rde_main(struct bgpd_config *config, str free(config->listen_addrs); pt_init(); @@ -161,7 +162,7 @@ diff -u -p -r1.1.1.1 -r1.4 path_init(pathhashsize); aspath_init(pathhashsize); attr_init(attrhashsize); -@@ -234,6 +245,7 @@ rde_main(struct bgpd_config *config, str +@@ -234,6 +246,7 @@ rde_main(struct bgpd_config *config, str log_info("route decision engine ready"); TAILQ_FOREACH(f, rules, entry) { @@ -169,7 +170,7 @@ diff -u -p -r1.1.1.1 -r1.4 TAILQ_FOREACH(set, &f->set, entry) { if (set->type == ACTION_SET_NEXTHOP) { nh = nexthop_get(&set->action.nexthop); -@@ -243,8 +255,20 @@ rde_main(struct bgpd_config *config, str +@@ -243,8 +256,20 @@ rde_main(struct bgpd_config *config, str } while (rde_quit == 0) { @@ -191,7 +192,7 @@ diff -u -p -r1.1.1.1 -r1.4 pfd[PFD_PIPE_MAIN].fd = ibuf_main->fd; pfd[PFD_PIPE_MAIN].events = POLLIN; if (ibuf_main->w.queued > 0) -@@ -259,14 +283,16 @@ rde_main(struct bgpd_config *config, str +@@ -259,14 +284,16 @@ rde_main(struct bgpd_config *config, str pfd[PFD_PIPE_SESSION_CTL].events = POLLIN; if (ibuf_se_ctl->w.queued > 0) pfd[PFD_PIPE_SESSION_CTL].events |= POLLOUT; @@ -214,7 +215,7 @@ diff -u -p -r1.1.1.1 -r1.4 } if (poll(pfd, i, timeout) == -1) { -@@ -299,24 +325,39 @@ rde_main(struct bgpd_config *config, str +@@ -299,24 +326,39 @@ rde_main(struct bgpd_config *config, str if (pfd[PFD_PIPE_SESSION_CTL].revents & POLLIN) rde_dispatch_imsg_session(ibuf_se_ctl); @@ -260,7 +261,7 @@ diff -u -p -r1.1.1.1 -r1.4 msgbuf_clear(&ibuf_se->w); free(ibuf_se); msgbuf_clear(&ibuf_se_ctl->w); -@@ -344,7 +385,6 @@ rde_dispatch_imsg_session(struct imsgbuf +@@ -344,7 +386,6 @@ rde_dispatch_imsg_session(struct imsgbuf struct filter_set *s; struct nexthop *nh; int n; @@ -268,7 +269,7 @@ diff -u -p -r1.1.1.1 -r1.4 if ((n = imsg_read(ibuf)) == -1) fatal("rde_dispatch_imsg_session: imsg_read error"); -@@ -438,7 +478,8 @@ badnet: +@@ -438,7 +479,8 @@ badnet: log_warnx("rde_dispatch: wrong imsg len"); break; } @@ -278,7 +279,7 @@ diff -u -p -r1.1.1.1 -r1.4 break; case IMSG_FILTER_SET: if (imsg.hdr.len - IMSG_HEADER_SIZE != -@@ -462,54 +503,16 @@ badnet: +@@ -462,54 +504,16 @@ badnet: } break; case IMSG_CTL_SHOW_NETWORK: @@ -335,7 +336,7 @@ diff -u -p -r1.1.1.1 -r1.4 break; case IMSG_CTL_SHOW_NEIGHBOR: if (imsg.hdr.len - IMSG_HEADER_SIZE != -@@ -552,12 +555,14 @@ void +@@ -552,12 +556,14 @@ void rde_dispatch_imsg_parent(struct imsgbuf *ibuf) { struct imsg imsg; @@ -352,7 +353,7 @@ diff -u -p -r1.1.1.1 -r1.4 if ((n = imsg_read(ibuf)) == -1) fatal("rde_dispatch_imsg_parent: imsg_read error"); -@@ -581,6 +586,8 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -581,6 +587,8 @@ rde_dispatch_imsg_parent(struct imsgbuf NULL) fatal(NULL); memcpy(nconf, imsg.data, sizeof(struct bgpd_config)); @@ -361,7 +362,7 @@ diff -u -p -r1.1.1.1 -r1.4 break; case IMSG_NETWORK_ADD: memcpy(&netconf_p, imsg.data, sizeof(netconf_p)); -@@ -601,6 +608,17 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -601,6 +609,17 @@ rde_dispatch_imsg_parent(struct imsgbuf TAILQ_INIT(&netconf_p.attrset); network_delete(&netconf_p, 1); break; @@ -379,7 +380,7 @@ diff -u -p -r1.1.1.1 -r1.4 case IMSG_RECONF_FILTER: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(struct filter_rule)) -@@ -609,6 +627,7 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -609,6 +628,7 @@ rde_dispatch_imsg_parent(struct imsgbuf fatal(NULL); memcpy(r, imsg.data, sizeof(struct filter_rule)); TAILQ_INIT(&r->set); @@ -387,7 +388,7 @@ diff -u -p -r1.1.1.1 -r1.4 parent_set = &r->set; TAILQ_INSERT_TAIL(newrules, r, entry); break; -@@ -628,10 +647,12 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -628,10 +648,12 @@ rde_dispatch_imsg_parent(struct imsgbuf free(nconf); nconf = NULL; parent_set = NULL; @@ -401,11 +402,19 @@ diff -u -p -r1.1.1.1 -r1.4 peer->reconf_out = 0; peer->reconf_in = 0; if (peer->conf.softreconfig_out && -@@ -647,12 +668,18 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -647,12 +669,30 @@ rde_dispatch_imsg_parent(struct imsgbuf reconf_in = 1; } } -+ /* XXX this needs rework anyway */ ++ /* bring ribs in sync before softreconfig dance */ ++ for (rid = 0; rid < rib_size; rid++) { ++ if (ribs[rid].state == RIB_DELETE) ++ rib_free(&ribs[rid]); ++ else if (ribs[rid].state == RIB_NEW) ++ rib_dump(&ribs[0], ++ rde_softreconfig_load, &ribs[rid], ++ AF_UNSPEC); ++ } /* sync local-RIB first */ if (reconf_in) - pt_dump(rde_softreconfig_in, NULL, AF_UNSPEC); @@ -416,25 +425,18 @@ diff -u -p -r1.1.1.1 -r1.4 - pt_dump(rde_softreconfig_out, NULL, AF_UNSPEC); + if (reconf_out) { + int i; -+ for (i = 1; i < rib_size; i++) ++ for (i = 1; i < rib_size; i++) { ++ if (ribs[i].state == RIB_NEW) ++ /* already synced by _load */ ++ continue; + rib_dump(&ribs[i], rde_softreconfig_out, + NULL, AF_UNSPEC); ++ } + } while ((r = TAILQ_FIRST(rules_l)) != NULL) { TAILQ_REMOVE(rules_l, r, entry); -@@ -661,6 +688,10 @@ rde_dispatch_imsg_parent(struct imsgbuf - } - free(rules_l); - rules_l = newrules; -+ for (rid = 0; rid < rib_size; rid++) { -+ if (ribs[rid].state == RIB_DELETE) -+ rib_free(&ribs[rid]); -+ } - log_info("RDE reconfigured"); - break; - case IMSG_NEXTHOP_UPDATE: -@@ -689,30 +720,15 @@ rde_dispatch_imsg_parent(struct imsgbuf +@@ -689,30 +729,15 @@ rde_dispatch_imsg_parent(struct imsgbuf log_warnx("wrong imsg len"); break; } @@ -472,7 +474,7 @@ diff -u -p -r1.1.1.1 -r1.4 break; case IMSG_MRT_CLOSE: /* ignore end message because a dump is atomic */ -@@ -729,7 +745,7 @@ int +@@ -729,7 +754,7 @@ int rde_update_dispatch(struct imsg *imsg) { struct rde_peer *peer; @@ -481,16 +483,22 @@ diff -u -p -r1.1.1.1 -r1.4 u_char *p, *mpp = NULL; int error = -1, pos = 0; u_int16_t afi, len, mplen; -@@ -795,7 +811,7 @@ rde_update_dispatch(struct imsg *imsg) +@@ -794,20 +819,15 @@ rde_update_dispatch(struct imsg *imsg) + goto done; } - /* +- /* - * if either ATTR_NEW_AGGREGATOR or ATTR_NEW_ASPATH is present -+ * if either ATTR_AS4_AGGREGATOR or ATTR_AS4_PATH is present - * try to fixup the attributes. - * XXX do not fixup if F_ATTR_LOOP is set. - */ -@@ -808,6 +824,8 @@ rde_update_dispatch(struct imsg *imsg) +- * try to fixup the attributes. +- * XXX do not fixup if F_ATTR_LOOP is set. +- */ +- if (asp->flags & F_ATTR_AS4BYTE_NEW && +- !(asp->flags & F_ATTR_LOOP)) +- rde_as4byte_fixup(peer, asp); ++ rde_as4byte_fixup(peer, asp); + + /* enforce remote AS if requested */ + if (asp->flags & F_ATTR_ASPATH && peer->conf.enforce_as == ENFORCE_AS_ON) if (peer->conf.remote_as != aspath_neighbor(asp->aspath)) { @@ -499,7 +507,7 @@ diff -u -p -r1.1.1.1 -r1.4 rde_update_err(peer, ERR_UPDATE, ERR_UPD_ASPATH, NULL, 0); goto done; -@@ -850,14 +868,19 @@ rde_update_dispatch(struct imsg *imsg) +@@ -850,14 +870,19 @@ rde_update_dispatch(struct imsg *imsg) goto done; } @@ -524,7 +532,7 @@ diff -u -p -r1.1.1.1 -r1.4 /* withdraw MP_UNREACH_NLRI if available */ if (mpa.unreach_len != 0) { -@@ -900,13 +923,7 @@ rde_update_dispatch(struct imsg *imsg) +@@ -900,13 +925,7 @@ rde_update_dispatch(struct imsg *imsg) mpp += pos; mplen -= pos; @@ -539,7 +547,7 @@ diff -u -p -r1.1.1.1 -r1.4 } break; default: -@@ -954,17 +971,7 @@ rde_update_dispatch(struct imsg *imsg) +@@ -954,17 +973,7 @@ rde_update_dispatch(struct imsg *imsg) goto done; } @@ -558,7 +566,7 @@ diff -u -p -r1.1.1.1 -r1.4 /* max prefix checker */ if (peer->conf.max_prefix && -@@ -972,20 +979,9 @@ rde_update_dispatch(struct imsg *imsg) +@@ -972,20 +981,9 @@ rde_update_dispatch(struct imsg *imsg) log_peer_warnx(&peer->conf, "prefix limit reached"); rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0); @@ -579,7 +587,7 @@ diff -u -p -r1.1.1.1 -r1.4 } /* add MP_REACH_NLRI if available */ -@@ -1008,7 +1004,7 @@ rde_update_dispatch(struct imsg *imsg) +@@ -1008,7 +1006,7 @@ rde_update_dispatch(struct imsg *imsg) (void)nexthop_delete(asp->nexthop); asp->nexthop = NULL; } @@ -588,7 +596,7 @@ diff -u -p -r1.1.1.1 -r1.4 log_peer_warnx(&peer->conf, "bad IPv6 nlri prefix"); rde_update_err(peer, ERR_UPDATE, ERR_UPD_OPTATTR, mpa.reach, mpa.reach_len); -@@ -1047,19 +1043,8 @@ rde_update_dispatch(struct imsg *imsg) +@@ -1047,19 +1045,8 @@ rde_update_dispatch(struct imsg *imsg) mpp += pos; mplen -= pos; @@ -610,7 +618,7 @@ diff -u -p -r1.1.1.1 -r1.4 /* max prefix checker */ if (peer->conf.max_prefix && -@@ -1068,22 +1053,9 @@ rde_update_dispatch(struct imsg *imsg) +@@ -1068,22 +1055,9 @@ rde_update_dispatch(struct imsg *imsg) "prefix limit reached"); rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0); @@ -633,7 +641,7 @@ diff -u -p -r1.1.1.1 -r1.4 } break; default: -@@ -1106,6 +1078,67 @@ done: +@@ -1106,6 +1080,76 @@ done: return (error); } @@ -644,7 +652,8 @@ diff -u -p -r1.1.1.1 -r1.4 + struct bgpd_addr *prefix, u_int8_t prefixlen) +{ + struct rde_aspath *fasp; -+ int r = 0; ++ enum filter_actions action; ++ int r = 0, f = 0; + u_int16_t i; + + peer->prefix_rcvd_update++; @@ -654,18 +663,24 @@ diff -u -p -r1.1.1.1 -r1.4 + + for (i = 1; i < rib_size; i++) { + /* input filter */ -+ if (rde_filter(i, &fasp, rules_l, peer, asp, prefix, prefixlen, -+ peer, DIR_IN) == ACTION_DENY) -+ goto done; ++ action = rde_filter(i, &fasp, rules_l, peer, asp, prefix, ++ prefixlen, peer, DIR_IN); + + if (fasp == NULL) + fasp = asp; + -+ rde_update_log("update", i, peer, &fasp->nexthop->exit_nexthop, -+ prefix, prefixlen); -+ r += path_update(&ribs[i], peer, fasp, prefix, prefixlen); ++ if (action == ACTION_ALLOW) { ++ rde_update_log("update", i, peer, ++ &fasp->nexthop->exit_nexthop, prefix, prefixlen); ++ r += path_update(&ribs[i], peer, fasp, prefix, ++ prefixlen); ++ } else if (prefix_remove(&ribs[i], peer, prefix, prefixlen, ++ 0)) { ++ rde_update_log("filtered withdraw", i, peer, ++ NULL, prefix, prefixlen); ++ f++; ++ } + -+done: + /* free modified aspath */ + if (fasp != asp) + path_put(fasp); @@ -673,6 +688,8 @@ diff -u -p -r1.1.1.1 -r1.4 + + if (r) + peer->prefix_cnt++; ++ else if (f) ++ peer->prefix_cnt--; +} + +void @@ -701,16 +718,67 @@ diff -u -p -r1.1.1.1 -r1.4 /* * BGP UPDATE parser functions */ -@@ -1336,7 +1369,7 @@ bad_flags: +@@ -1272,9 +1316,19 @@ bad_flags: + goto optattr; + case ATTR_AGGREGATOR: + if ((!rde_as4byte(peer) && attr_len != 6) || +- (rde_as4byte(peer) && attr_len != 8)) +- goto bad_len; +- if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, 0)) ++ (rde_as4byte(peer) && attr_len != 8)) { ++ /* ++ * ignore attribute in case of error as per ++ * draft-ietf-idr-optional-transitive-00.txt ++ * but only if partial bit is set ++ */ ++ if ((flags & ATTR_PARTIAL) == 0) ++ goto bad_len; ++ plen += attr_len; ++ break; ++ } ++ if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, ++ ATTR_PARTIAL)) + goto bad_flags; + if (!rde_as4byte(peer)) { + /* need to inflate aggregator AS to 4-byte */ +@@ -1290,8 +1344,17 @@ bad_flags: + /* 4-byte ready server take the default route */ + goto optattr; + case ATTR_COMMUNITIES: +- if ((attr_len & 0x3) != 0) +- goto bad_len; ++ if ((attr_len & 0x3) != 0) { ++ /* ++ * mark update as bad and withdraw all routes as per ++ * draft-ietf-idr-optional-transitive-00.txt ++ * but only if partial bit is set ++ */ ++ if ((flags & ATTR_PARTIAL) == 0) ++ goto bad_len; ++ else ++ a->flags |= F_ATTR_PARSE_ERR; ++ } + if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, + ATTR_PARTIAL)) + goto bad_flags; +@@ -1336,15 +1399,21 @@ bad_flags: mpa->unreach_len = attr_len; plen += attr_len; break; - case ATTR_NEW_AGGREGATOR: +- if (attr_len != 8) +- goto bad_len; + case ATTR_AS4_AGGREGATOR: - if (attr_len != 8) - goto bad_len; ++ if (attr_len != 8) { ++ /* see ATTR_AGGREGATOR ... */ ++ if ((flags & ATTR_PARTIAL) == 0) ++ goto bad_len; ++ /* we should add a warning here */ ++ plen += attr_len; ++ break; ++ } if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, -@@ -1344,7 +1377,7 @@ bad_flags: + ATTR_PARTIAL)) goto bad_flags; a->flags |= F_ATTR_AS4BYTE_NEW; goto optattr; @@ -719,7 +787,35 @@ diff -u -p -r1.1.1.1 -r1.4 if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, ATTR_PARTIAL)) goto bad_flags; -@@ -1408,7 +1441,7 @@ rde_attr_missing(struct rde_aspath *a, i +@@ -1352,13 +1421,21 @@ bad_flags: + /* + * XXX RFC does not specify how to handle errors. + * XXX Instead of dropping the session because of a +- * XXX bad path just mark the full update as not +- * XXX loop-free the update is no longer eligible and +- * XXX will not be considered for routing or +- * XXX redistribution. Something better is needed. ++ * XXX bad path just mark the full update as having ++ * XXX a parse error which makes the update no longer ++ * XXX eligible and will not be considered for routing ++ * XXX or redistribution. ++ * XXX We follow draft-ietf-idr-optional-transitive ++ * XXX by looking at the partial bit. + */ +- a->flags |= F_ATTR_LOOP; +- goto optattr; ++ if (flags & ATTR_PARTIAL) { ++ a->flags |= F_ATTR_PARSE_ERR; ++ goto optattr; ++ } else { ++ rde_update_err(peer, ERR_UPDATE, ERR_UPD_ASPATH, ++ NULL, 0); ++ return (-1); ++ } + } + a->flags |= F_ATTR_AS4BYTE_NEW; + goto optattr; +@@ -1408,7 +1485,7 @@ rde_attr_missing(struct rde_aspath *a, i int rde_get_mp_nexthop(u_char *data, u_int16_t len, u_int16_t afi, @@ -728,7 +824,7 @@ diff -u -p -r1.1.1.1 -r1.4 { struct bgpd_addr nexthop; u_int8_t totlen, nhlen; -@@ -1440,6 +1473,18 @@ rde_get_mp_nexthop(u_char *data, u_int16 +@@ -1440,6 +1517,18 @@ rde_get_mp_nexthop(u_char *data, u_int16 } nexthop.af = AF_INET6; memcpy(&nexthop.v6.s6_addr, data, 16); @@ -747,7 +843,7 @@ diff -u -p -r1.1.1.1 -r1.4 asp->nexthop = nexthop_get(&nexthop); /* * lock the nexthop because it is not yet linked else -@@ -1540,13 +1585,12 @@ rde_update_err(struct rde_peer *peer, u_ +@@ -1540,13 +1629,12 @@ rde_update_err(struct rde_peer *peer, u_ imsg_add(wbuf, &suberr, sizeof(suberr)) == -1 || imsg_add(wbuf, data, size) == -1) fatal("imsg_add error"); @@ -763,7 +859,7 @@ diff -u -p -r1.1.1.1 -r1.4 const struct rde_peer *peer, const struct bgpd_addr *next, const struct bgpd_addr *prefix, u_int8_t prefixlen) { -@@ -1563,7 +1607,7 @@ rde_update_log(const char *message, +@@ -1563,7 +1651,7 @@ rde_update_log(const char *message, if (asprintf(&p, "%s/%u", log_addr(prefix), prefixlen) == -1) p = NULL; l = log_fmt_peer(&peer->conf); @@ -772,9 +868,18 @@ diff -u -p -r1.1.1.1 -r1.4 l, log_as(peer->conf.remote_as), message, p ? p : "out of memory", n ? n : ""); -@@ -1585,8 +1629,8 @@ rde_as4byte_fixup(struct rde_peer *peer, +@@ -1584,9 +1672,17 @@ rde_as4byte_fixup(struct rde_peer *peer, + struct attr *nasp, *naggr, *oaggr; u_int32_t as; ++ /* ++ * if either ATTR_AS4_AGGREGATOR or ATTR_AS4_PATH is present ++ * try to fixup the attributes. ++ * Do not fixup if F_ATTR_PARSE_ERR is set. ++ */ ++ if (!(a->flags & F_ATTR_AS4BYTE_NEW) || a->flags & F_ATTR_PARSE_ERR) ++ return; ++ /* first get the attributes */ - nasp = attr_optget(a, ATTR_NEW_ASPATH); - naggr = attr_optget(a, ATTR_NEW_AGGREGATOR); @@ -783,7 +888,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (rde_as4byte(peer)) { /* NEW session using 4-byte ASNs */ -@@ -1601,7 +1645,7 @@ rde_as4byte_fixup(struct rde_peer *peer, +@@ -1601,7 +1697,7 @@ rde_as4byte_fixup(struct rde_peer *peer, if ((oaggr = attr_optget(a, ATTR_AGGREGATOR))) { memcpy(&as, oaggr->data, sizeof(as)); if (ntohl(as) != AS_TRANS) { @@ -792,7 +897,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (nasp) attr_free(a, nasp); if (naggr) -@@ -1616,11 +1660,11 @@ rde_as4byte_fixup(struct rde_peer *peer, +@@ -1616,11 +1712,11 @@ rde_as4byte_fixup(struct rde_peer *peer, fatalx("attr_optadd failed but impossible"); } } @@ -806,7 +911,18 @@ diff -u -p -r1.1.1.1 -r1.4 if (nasp) aspath_merge(a, nasp); } -@@ -1703,7 +1747,6 @@ rde_dump_rib_as(struct prefix *p, struct +@@ -1637,6 +1733,10 @@ rde_reflector(struct rde_peer *peer, str + u_int16_t len; + u_int32_t id; + ++ /* do not consider updates with parse errors */ ++ if (asp->flags & F_ATTR_PARSE_ERR) ++ return; ++ + /* check for originator id if eq router_id drop */ + if ((a = attr_optget(asp, ATTR_ORIGINATOR_ID)) != NULL) { + if (memcmp(&conf->bgpid, a->data, sizeof(conf->bgpid)) == 0) { +@@ -1703,7 +1803,6 @@ rde_dump_rib_as(struct prefix *p, struct rib.med = asp->med; rib.prefix_cnt = asp->prefix_cnt; rib.active_cnt = asp->active_cnt; @@ -814,7 +930,7 @@ diff -u -p -r1.1.1.1 -r1.4 strlcpy(rib.descr, asp->peer->conf.descr, sizeof(rib.descr)); memcpy(&rib.remote_addr, &asp->peer->remote_addr, sizeof(rib.remote_addr)); -@@ -1724,7 +1767,7 @@ rde_dump_rib_as(struct prefix *p, struct +@@ -1724,7 +1823,7 @@ rde_dump_rib_as(struct prefix *p, struct rib.prefixlen = p->prefix->prefixlen; rib.origin = asp->origin; rib.flags = 0; @@ -823,7 +939,7 @@ diff -u -p -r1.1.1.1 -r1.4 rib.flags |= F_RIB_ACTIVE; if (asp->peer->conf.ebgp == 0) rib.flags |= F_RIB_INTERNAL; -@@ -1743,8 +1786,7 @@ rde_dump_rib_as(struct prefix *p, struct +@@ -1743,8 +1842,7 @@ rde_dump_rib_as(struct prefix *p, struct imsg_add(wbuf, aspath_dump(asp->aspath), rib.aspath_len) == -1) return; @@ -833,7 +949,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (flags & F_CTL_DETAIL) for (l = 0; l < asp->others_len; l++) { -@@ -1763,8 +1805,7 @@ rde_dump_rib_as(struct prefix *p, struct +@@ -1763,8 +1861,7 @@ rde_dump_rib_as(struct prefix *p, struct buf_free(wbuf); return; } @@ -843,7 +959,7 @@ diff -u -p -r1.1.1.1 -r1.4 } } -@@ -1780,7 +1821,7 @@ rde_dump_filterout(struct rde_peer *peer +@@ -1780,7 +1877,7 @@ rde_dump_filterout(struct rde_peer *peer return; pt_getaddr(p->prefix, &addr); @@ -852,7 +968,7 @@ diff -u -p -r1.1.1.1 -r1.4 p->prefix->prefixlen, p->aspath->peer, DIR_OUT); if (asp) asp->peer = p->aspath->peer; -@@ -1799,108 +1840,57 @@ rde_dump_filter(struct prefix *p, struct +@@ -1799,108 +1896,57 @@ rde_dump_filter(struct prefix *p, struct { struct rde_peer *peer; @@ -894,18 +1010,15 @@ diff -u -p -r1.1.1.1 -r1.4 { struct prefix *p; - struct ctl_show_rib_request *req = ptr; -+ struct rde_dump_ctx *ctx = ptr; - +- - LIST_FOREACH(p, &pt->prefix_h, prefix_l) - rde_dump_filter(p, req); -+ LIST_FOREACH(p, &re->prefix_h, rib_l) -+ rde_dump_filter(p, &ctx->req); - } +-} ++ struct rde_dump_ctx *ctx = ptr; - void +-void -rde_dump_as(struct ctl_show_rib_request *req) -+rde_dump_prefix_upcall(struct rib_entry *re, void *ptr) - { +-{ - extern struct path_table pathtable; - struct rde_aspath *asp; - struct prefix *p; @@ -921,11 +1034,14 @@ diff -u -p -r1.1.1.1 -r1.4 - rde_dump_filter(p, req); - } - } --} -- --void ++ LIST_FOREACH(p, &re->prefix_h, rib_l) ++ rde_dump_filter(p, &ctx->req); + } + + void -rde_dump_prefix_upcall(struct pt_entry *pt, void *ptr) --{ ++rde_dump_prefix_upcall(struct rib_entry *re, void *ptr) + { - struct ctl_show_rib_request *req = ptr; - struct prefix *p; - struct bgpd_addr addr; @@ -987,7 +1103,7 @@ diff -u -p -r1.1.1.1 -r1.4 } void -@@ -1908,7 +1898,9 @@ rde_dump_ctx_new(struct ctl_show_rib_req +@@ -1908,7 +1954,9 @@ rde_dump_ctx_new(struct ctl_show_rib_req enum imsg_type type) { struct rde_dump_ctx *ctx; @@ -997,7 +1113,7 @@ diff -u -p -r1.1.1.1 -r1.4 if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_warn("rde_dump_ctx_new"); -@@ -1917,52 +1909,89 @@ rde_dump_ctx_new(struct ctl_show_rib_req +@@ -1917,52 +1965,89 @@ rde_dump_ctx_new(struct ctl_show_rib_req sizeof(error)); return; } @@ -1122,7 +1238,24 @@ diff -u -p -r1.1.1.1 -r1.4 } /* -@@ -2100,9 +2129,10 @@ rde_send_nexthop(struct bgpd_addr *next, +@@ -2081,7 +2166,6 @@ rde_send_pftable_commit(void) + void + rde_send_nexthop(struct bgpd_addr *next, int valid) + { +- size_t size; + int type; + + if (valid) +@@ -2089,8 +2173,6 @@ rde_send_nexthop(struct bgpd_addr *next, + else + type = IMSG_NEXTHOP_REMOVE; + +- size = sizeof(struct bgpd_addr); +- + if (imsg_compose(ibuf_main, type, 0, 0, -1, next, + sizeof(struct bgpd_addr)) == -1) + fatal("imsg_compose error"); +@@ -2100,9 +2182,10 @@ rde_send_nexthop(struct bgpd_addr *next, * soft reconfig specific functions */ void @@ -1135,7 +1268,7 @@ diff -u -p -r1.1.1.1 -r1.4 struct rde_peer *peer; struct rde_aspath *oasp, *nasp; enum filter_actions oa, na; -@@ -2111,17 +2141,22 @@ rde_softreconfig_out(struct pt_entry *pt +@@ -2111,17 +2194,22 @@ rde_softreconfig_out(struct pt_entry *pt if (p == NULL) return; @@ -1162,7 +1295,7 @@ diff -u -p -r1.1.1.1 -r1.4 oasp = oasp != NULL ? oasp : p->aspath; nasp = nasp != NULL ? nasp : p->aspath; -@@ -2154,60 +2189,67 @@ done: +@@ -2154,58 +2242,103 @@ done: } void @@ -1198,10 +1331,11 @@ diff -u -p -r1.1.1.1 -r1.4 - oa = rde_filter(&oasp, rules_l, peer, asp, &addr, - pt->prefixlen, peer, DIR_IN); - na = rde_filter(&nasp, newrules, peer, asp, &addr, -- pt->prefixlen, peer, DIR_IN); -- oasp = oasp != NULL ? oasp : asp; -- nasp = nasp != NULL ? nasp : asp; + for (i = 1; i < rib_size; i++) { ++ /* only active ribs need a softreconfig rerun */ ++ if (ribs[i].state != RIB_ACTIVE) ++ continue; ++ + /* check if prefix changed */ + oa = rde_filter(i, &oasp, rules_l, peer, asp, &addr, + pt->prefixlen, peer, DIR_IN); @@ -1209,28 +1343,10 @@ diff -u -p -r1.1.1.1 -r1.4 + pt->prefixlen, peer, DIR_IN); + oasp = oasp != NULL ? oasp : asp; + nasp = nasp != NULL ? nasp : asp; - -- if (oa == ACTION_DENY && na == ACTION_DENY) -- /* nothing todo */ -- goto done; -- if (oa == ACTION_DENY && na == ACTION_ALLOW) { -- /* update Local-RIB */ -- path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); -- goto done; -- } -- if (oa == ACTION_ALLOW && na == ACTION_DENY) { -- /* remove from Local-RIB */ -- prefix_remove(peer, &addr, pt->prefixlen, F_LOCAL); -- goto done; -- } -- if (oa == ACTION_ALLOW && na == ACTION_ALLOW) { -- if (path_compare(nasp, oasp) == 0) ++ + if (oa == ACTION_DENY && na == ACTION_DENY) + /* nothing todo */ - goto done; -- /* send update */ -- path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); -- } ++ goto done; + if (oa == ACTION_DENY && na == ACTION_ALLOW) { + /* update Local-RIB */ + path_update(&ribs[i], peer, nasp, &addr, @@ -1247,24 +1363,73 @@ diff -u -p -r1.1.1.1 -r1.4 + if (path_compare(nasp, oasp) == 0) + goto done; + /* send update */ -+ path_update(&ribs[1], peer, nasp, &addr, ++ path_update(&ribs[i], peer, nasp, &addr, + pt->prefixlen); + } - - done: -- if (oasp != asp) -- path_put(oasp); -- if (nasp != asp) -- path_put(nasp); ++ ++done: + if (oasp != asp) + path_put(oasp); + if (nasp != asp) + path_put(nasp); + } - } - } ++ } ++} ++ ++void ++rde_softreconfig_load(struct rib_entry *re, void *ptr) ++{ ++ struct rib *rib = ptr; ++ struct prefix *p, *np; ++ struct pt_entry *pt; ++ struct rde_peer *peer; ++ struct rde_aspath *asp, *nasp; ++ enum filter_actions action; ++ struct bgpd_addr addr; ++ ++ pt = re->prefix; ++ pt_getaddr(pt, &addr); ++ for (p = LIST_FIRST(&re->prefix_h); p != NULL; p = np) { ++ np = LIST_NEXT(p, rib_l); ++ ++ /* store aspath as prefix may change till we're done */ ++ asp = p->aspath; ++ peer = asp->peer; ++ ++ action = rde_filter(rib->id, &nasp, newrules, peer, asp, &addr, + pt->prefixlen, peer, DIR_IN); +- oasp = oasp != NULL ? oasp : asp; + nasp = nasp != NULL ? nasp : asp; -@@ -2217,17 +2259,19 @@ done: +- if (oa == ACTION_DENY && na == ACTION_DENY) +- /* nothing todo */ +- goto done; +- if (oa == ACTION_DENY && na == ACTION_ALLOW) { ++ if (action == ACTION_ALLOW) { + /* update Local-RIB */ +- path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); +- goto done; +- } +- if (oa == ACTION_ALLOW && na == ACTION_DENY) { +- /* remove from Local-RIB */ +- prefix_remove(peer, &addr, pt->prefixlen, F_LOCAL); +- goto done; +- } +- if (oa == ACTION_ALLOW && na == ACTION_ALLOW) { +- if (path_compare(nasp, oasp) == 0) +- goto done; +- /* send update */ +- path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); ++ path_update(rib, peer, nasp, &addr, pt->prefixlen); + } + +-done: +- if (oasp != asp) +- path_put(oasp); + if (nasp != asp) + path_put(nasp); + } +@@ -2217,17 +2350,19 @@ done: u_char queue_buf[4096]; void @@ -1288,7 +1453,7 @@ diff -u -p -r1.1.1.1 -r1.4 { struct rde_peer *peer; -@@ -2240,6 +2284,10 @@ rde_generate_updates(struct prefix *new, +@@ -2240,6 +2375,10 @@ rde_generate_updates(struct prefix *new, return; LIST_FOREACH(peer, &peerlist, peer_l) { @@ -1299,7 +1464,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (peer->state != PEER_UP) continue; up_generate_updates(rules_l, peer, new, old); -@@ -2257,6 +2305,8 @@ rde_update_queue_runner(void) +@@ -2257,6 +2396,8 @@ rde_update_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { @@ -1308,7 +1473,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (peer->state != PEER_UP) continue; /* first withdraws */ -@@ -2303,6 +2353,8 @@ rde_update6_queue_runner(void) +@@ -2303,6 +2444,8 @@ rde_update6_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { @@ -1317,7 +1482,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (peer->state != PEER_UP) continue; len = sizeof(queue_buf) - MSGSIZE_HEADER; -@@ -2324,6 +2376,8 @@ rde_update6_queue_runner(void) +@@ -2324,6 +2467,8 @@ rde_update6_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { @@ -1326,7 +1491,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (peer->state != PEER_UP) continue; len = sizeof(queue_buf) - MSGSIZE_HEADER; -@@ -2386,6 +2440,8 @@ struct peer_table { +@@ -2386,6 +2531,8 @@ struct peer_table { void peer_init(u_int32_t hashsize) { @@ -1335,7 +1500,7 @@ diff -u -p -r1.1.1.1 -r1.4 u_int32_t hs, i; for (hs = 1; hs < hashsize; hs <<= 1) -@@ -2399,6 +2455,19 @@ peer_init(u_int32_t hashsize) +@@ -2399,6 +2546,19 @@ peer_init(u_int32_t hashsize) LIST_INIT(&peerlist); peertable.peer_hashmask = hs - 1; @@ -1355,7 +1520,7 @@ diff -u -p -r1.1.1.1 -r1.4 } void -@@ -2444,6 +2513,7 @@ peer_add(u_int32_t id, struct peer_confi +@@ -2444,6 +2604,7 @@ peer_add(u_int32_t id, struct peer_confi LIST_INIT(&peer->path_h); memcpy(&peer->conf, p_conf, sizeof(struct peer_config)); peer->remote_bgpid = 0; @@ -1363,7 +1528,7 @@ diff -u -p -r1.1.1.1 -r1.4 peer->state = PEER_NONE; up_init(peer); -@@ -2573,6 +2643,7 @@ peer_down(u_int32_t id) +@@ -2573,6 +2734,7 @@ peer_down(u_int32_t id) path_remove(asp); } LIST_INIT(&peer->path_h); @@ -1371,33 +1536,59 @@ diff -u -p -r1.1.1.1 -r1.4 /* Deletions are performed in path_remove() */ rde_send_pftable_commit(); -@@ -2595,19 +2666,19 @@ peer_dump(u_int32_t id, u_int16_t afi, u +@@ -2589,32 +2751,38 @@ peer_dump(u_int32_t id, u_int16_t afi, u + + peer = peer_get(id); + if (peer == NULL) { +- log_warnx("peer_down: unknown peer id %d", id); ++ log_warnx("peer_dump: unknown peer id %d", id); + return; + } if (afi == AFI_ALL || afi == AFI_IPv4) - if (safi == SAFI_ALL || safi == SAFI_UNICAST) { +- if (safi == SAFI_ALL || safi == SAFI_UNICAST) { - if (peer->conf.announce_type == - ANNOUNCE_DEFAULT_ROUTE) ++ if ((safi == SAFI_ALL || safi == SAFI_UNICAST) && ++ peer->conf.capabilities.mp_v4 != SAFI_NONE) { + if (peer->conf.announce_type == ANNOUNCE_DEFAULT_ROUTE) up_generate_default(rules_l, peer, AF_INET); else - pt_dump(rde_up_dump_upcall, peer, AF_INET); + rib_dump(&ribs[peer->ribid], rde_up_dump_upcall, + peer, AF_INET); ++ if (peer->capa_received.restart && ++ peer->capa_announced.restart) ++ peer_send_eor(peer, AFI_IPv4, SAFI_UNICAST); } if (afi == AFI_ALL || afi == AFI_IPv6) - if (safi == SAFI_ALL || safi == SAFI_UNICAST) { +- if (safi == SAFI_ALL || safi == SAFI_UNICAST) { - if (peer->conf.announce_type == - ANNOUNCE_DEFAULT_ROUTE) ++ if ((safi == SAFI_ALL || safi == SAFI_UNICAST) && ++ peer->capa_announced.mp_v6 != SAFI_NONE && ++ peer->capa_received.mp_v6 != SAFI_NONE) { + if (peer->conf.announce_type == ANNOUNCE_DEFAULT_ROUTE) up_generate_default(rules_l, peer, AF_INET6); else - pt_dump(rde_up_dump_upcall, peer, AF_INET6); + rib_dump(&ribs[peer->ribid], rde_up_dump_upcall, + peer, AF_INET6); ++ if (peer->capa_received.restart && ++ peer->capa_announced.restart) ++ peer_send_eor(peer, AFI_IPv6, SAFI_UNICAST); } +- +- if (peer->capa_received.restart && peer->capa_announced.restart) +- peer_send_eor(peer, afi, safi); + } - if (peer->capa_received.restart && peer->capa_announced.restart) -@@ -2653,24 +2724,8 @@ void +-/* End-of-RIB marker, draft-ietf-idr-restart-13.txt */ ++/* End-of-RIB marker, RFC 4724 */ + void + peer_send_eor(struct rde_peer *peer, u_int16_t afi, u_int16_t safi) + { +@@ -2653,24 +2821,8 @@ void network_init(struct network_head *net_l) { struct network *n; @@ -1422,7 +1613,7 @@ diff -u -p -r1.1.1.1 -r1.4 while ((n = TAILQ_FIRST(net_l)) != NULL) { TAILQ_REMOVE(net_l, n, entry); -@@ -2683,7 +2738,7 @@ void +@@ -2683,7 +2835,7 @@ void network_add(struct network_config *nc, int flagstatic) { struct rde_aspath *asp; @@ -1431,7 +1622,7 @@ diff -u -p -r1.1.1.1 -r1.4 asp = path_get(); asp->aspath = aspath_get(NULL, 0); -@@ -2691,15 +2746,13 @@ network_add(struct network_config *nc, i +@@ -2691,15 +2843,13 @@ network_add(struct network_config *nc, i asp->flags = F_ATTR_ORIGIN | F_ATTR_ASPATH | F_ATTR_LOCALPREF | F_PREFIX_ANNOUNCED; /* the nexthop is unset unless a default set overrides it */ @@ -1453,7 +1644,7 @@ diff -u -p -r1.1.1.1 -r1.4 path_put(asp); filterset_free(&nc->attrset); -@@ -2708,29 +2761,27 @@ network_add(struct network_config *nc, i +@@ -2708,29 +2858,27 @@ network_add(struct network_config *nc, i void network_delete(struct network_config *nc, int flagstatic) { @@ -1493,7 +1684,7 @@ diff -u -p -r1.1.1.1 -r1.4 if (!(p->aspath->flags & F_PREFIX_ANNOUNCED)) continue; if (p->prefix->af == AF_INET) { -@@ -2738,10 +2789,10 @@ network_dump_upcall(struct pt_entry *pt, +@@ -2738,10 +2886,10 @@ network_dump_upcall(struct pt_entry *pt, pt_getaddr(p->prefix, &addr); k.prefix.s_addr = addr.v4.s_addr; k.prefixlen = p->prefix->prefixlen; @@ -1506,7 +1697,7 @@ diff -u -p -r1.1.1.1 -r1.4 log_warnx("network_dump_upcall: " "imsg_compose error"); } -@@ -2750,31 +2801,21 @@ network_dump_upcall(struct pt_entry *pt, +@@ -2750,31 +2898,21 @@ network_dump_upcall(struct pt_entry *pt, pt_getaddr(p->prefix, &addr); memcpy(&k6.prefix, &addr.v6, sizeof(k6.prefix)); k6.prefixlen = p->prefix->prefixlen; @@ -1540,7 +1731,7 @@ diff -u -p -r1.1.1.1 -r1.4 struct filter_rule *r; u_int32_t i; -@@ -2790,21 +2831,6 @@ rde_shutdown(void) +@@ -2790,21 +2928,6 @@ rde_shutdown(void) while ((p = LIST_FIRST(&peertable.peer_hashtbl[i])) != NULL) peer_down(p->conf.id); @@ -1562,7 +1753,7 @@ diff -u -p -r1.1.1.1 -r1.4 /* free filters */ while ((r = TAILQ_FIRST(rules_l)) != NULL) { TAILQ_REMOVE(rules_l, r, entry); -@@ -2819,7 +2845,6 @@ rde_shutdown(void) +@@ -2819,7 +2942,6 @@ rde_shutdown(void) attr_shutdown(); pt_shutdown(); peer_shutdown(); diff --git a/net/openbgpd/files/patch-bgpd_rde.h b/net/openbgpd/files/patch-bgpd_rde.h index cd84a23a1523..e8fd5aaa7e0a 100644 --- a/net/openbgpd/files/patch-bgpd_rde.h +++ b/net/openbgpd/files/patch-bgpd_rde.h @@ -2,13 +2,13 @@ Index: bgpd/rde.h =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde.h,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.4 +diff -u -p -r1.1.1.1 -r1.1.1.4 --- bgpd/rde.h 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde.h 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/rde.h 22 Oct 2009 14:24:02 -0000 1.1.1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.102 2008/01/23 08:11:32 claudio Exp $ */ -+/* $OpenBSD: rde.h,v 1.120 2009/06/06 01:10:29 claudio Exp $ */ ++/* $OpenBSD: rde.h,v 1.121 2009/08/06 08:53:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -46,7 +46,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 }; /* attribute flags. 4 low order bits reserved */ -@@ -154,16 +155,15 @@ LIST_HEAD(prefix_head, prefix); +@@ -154,16 +155,16 @@ LIST_HEAD(prefix_head, prefix); #define F_ATTR_MED_ANNOUNCE 0x00020 #define F_ATTR_MP_REACH 0x00040 #define F_ATTR_MP_UNREACH 0x00080 @@ -61,13 +61,14 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 #define F_NEXTHOP_BLACKHOLE 0x04000 #define F_NEXTHOP_NOMODIFY 0x08000 -#define F_NEXTHOP_SELF 0x10000 ++#define F_ATTR_PARSE_ERR 0x10000 #define F_ATTR_LINKED 0x20000 -#define F_LOCAL 0x40000 /* Local-RIB */ -#define F_ORIGINAL 0x80000 /* Adj-RIB-In */ #define ORIGIN_IGP 0 -@@ -184,7 +184,6 @@ struct rde_aspath { +@@ -184,7 +185,6 @@ struct rde_aspath { u_int32_t weight; /* low prio lpref */ u_int32_t prefix_cnt; /* # of prefixes */ u_int32_t active_cnt; /* # of active prefixes */ @@ -75,7 +76,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 u_int32_t flags; /* internally used */ u_int16_t rtlabelid; /* route label id */ u_int16_t pftableid; /* pf table id */ -@@ -223,53 +222,71 @@ struct pt_entry { +@@ -223,53 +223,72 @@ struct pt_entry { RB_ENTRY(pt_entry) pt_e; sa_family_t af; u_int8_t prefixlen; @@ -145,6 +146,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 + +enum rib_state { + RIB_NONE, ++ RIB_NEW, + RIB_ACTIVE, + RIB_DELETE +}; @@ -173,7 +175,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 }; extern struct rde_memstats rdemem; -@@ -282,7 +299,8 @@ void rde_send_pftable(u_int16_t, struc +@@ -282,7 +301,8 @@ void rde_send_pftable(u_int16_t, struc u_int8_t, int); void rde_send_pftable_commit(void); @@ -183,7 +185,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 u_int32_t rde_local_as(void); int rde_noevaluate(void); int rde_decisionflags(void); -@@ -291,6 +309,8 @@ int rde_as4byte(struct rde_peer *); +@@ -291,6 +311,8 @@ int rde_as4byte(struct rde_peer *); /* rde_attr.c */ int attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *, u_int16_t); @@ -192,7 +194,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 void attr_init(u_int32_t); void attr_shutdown(void); int attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t, -@@ -327,10 +347,24 @@ int community_set(struct rde_aspath *, +@@ -327,10 +349,24 @@ int community_set(struct rde_aspath *, void community_delete(struct rde_aspath *, int, int); /* rde_rib.c */ @@ -219,7 +221,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 int path_compare(struct rde_aspath *, struct rde_aspath *); struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *); void path_remove(struct rde_aspath *); -@@ -343,18 +377,20 @@ void path_put(struct rde_aspath *); +@@ -343,18 +379,20 @@ void path_put(struct rde_aspath *); #define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) int prefix_compare(const struct bgpd_addr *, const struct bgpd_addr *, int); @@ -250,7 +252,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 void nexthop_init(u_int32_t); void nexthop_shutdown(void); -@@ -368,7 +404,7 @@ struct nexthop *nexthop_get(struct bgpd_ +@@ -368,7 +406,7 @@ struct nexthop *nexthop_get(struct bgpd_ int nexthop_compare(struct nexthop *, struct nexthop *); /* rde_decide.c */ @@ -259,7 +261,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 /* rde_update.c */ void up_init(struct rde_peer *); -@@ -387,24 +423,34 @@ u_char *up_dump_mp_unreach(u_char *, u_ +@@ -387,24 +425,34 @@ u_char *up_dump_mp_unreach(u_char *, u_ u_char *up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *); /* rde_prefix.c */ diff --git a/net/openbgpd/files/patch-bgpd_rde_decide.c b/net/openbgpd/files/patch-bgpd_rde_decide.c index 425007c3f95b..68fa6768d8ea 100644 --- a/net/openbgpd/files/patch-bgpd_rde_decide.c +++ b/net/openbgpd/files/patch-bgpd_rde_decide.c @@ -2,17 +2,17 @@ Index: bgpd/rde_decide.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_decide.c,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.2 +diff -u -p -r1.1.1.1 -r1.2 --- bgpd/rde_decide.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde_decide.c 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/rde_decide.c 22 Oct 2009 15:12:21 -0000 1.2 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_decide.c,v 1.51 2008/05/08 09:51:46 henning Exp $ */ -+/* $OpenBSD: rde_decide.c,v 1.58 2009/06/29 14:10:13 claudio Exp $ */ ++/* $OpenBSD: rde_decide.c,v 1.59 2009/08/06 08:53:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker -@@ -115,12 +115,6 @@ prefix_cmp(struct prefix *p1, struct pre +@@ -115,15 +115,15 @@ prefix_cmp(struct prefix *p1, struct pre if (p2 == NULL) return (1); @@ -25,7 +25,16 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 asp1 = p1->aspath; asp2 = p2->aspath; -@@ -201,9 +195,16 @@ prefix_cmp(struct prefix *p1, struct pre ++ /* pathes with errors are not eligible */ ++ if (asp1->flags & F_ATTR_PARSE_ERR) ++ return (-1); ++ if (asp2->flags & F_ATTR_PARSE_ERR) ++ return (1); ++ + /* only loop free pathes are eligible */ + if (asp1->flags & F_ATTR_LOOP) + return (-1); +@@ -201,9 +201,16 @@ prefix_cmp(struct prefix *p1, struct pre &p2->aspath->peer->remote_addr, sizeof(p1->aspath->peer->remote_addr))); @@ -38,12 +47,13 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 + } + fatalx("Uh, oh a politician in the decision process"); - /* NOTREACHED */ +- /* NOTREACHED */ - return (0); ++ return(0); /* NOTREACHED */ } /* -@@ -212,59 +213,59 @@ prefix_cmp(struct prefix *p1, struct pre +@@ -212,59 +219,59 @@ prefix_cmp(struct prefix *p1, struct pre * The to evaluate prefix must not be in the prefix list. */ void @@ -94,7 +104,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 - if (xp == NULL || !(xp->flags & F_LOCAL) || - xp->aspath->flags & F_ATTR_LOOP || + xp = LIST_FIRST(&re->prefix_h); -+ if (xp == NULL || xp->aspath->flags & F_ATTR_LOOP || ++ if (xp == NULL || xp->aspath->flags & (F_ATTR_LOOP|F_ATTR_PARSE_ERR) || (xp->aspath->nexthop != NULL && xp->aspath->nexthop->state != NEXTHOP_REACH)) /* xp is ineligible */ diff --git a/net/openbgpd/files/patch-bgpd_rde_filter.c b/net/openbgpd/files/patch-bgpd_rde_filter.c index a9004869e8b4..b22c6b36efc2 100644 --- a/net/openbgpd/files/patch-bgpd_rde_filter.c +++ b/net/openbgpd/files/patch-bgpd_rde_filter.c @@ -2,13 +2,13 @@ Index: bgpd/rde_filter.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_filter.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.4 +diff -u -p -r1.1.1.1 -r1.4 --- bgpd/rde_filter.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde_filter.c 9 Jul 2009 17:22:14 -0000 1.3 ++++ bgpd/rde_filter.c 10 Aug 2009 21:20:05 -0000 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.54 2008/06/15 10:19:21 claudio Exp $ */ -+/* $OpenBSD: rde_filter.c,v 1.56 2009/06/06 01:10:29 claudio Exp $ */ ++/* $OpenBSD: rde_filter.c,v 1.57 2009/08/06 08:53:11 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -21,7 +21,17 @@ diff -u -p -r1.1.1.1 -r1.3 struct rde_peer *peer, struct rde_aspath *asp, struct bgpd_addr *prefix, u_int8_t prefixlen, struct rde_peer *from, enum directions dir) { -@@ -43,6 +43,8 @@ rde_filter(struct rde_aspath **new, stru +@@ -40,9 +40,18 @@ rde_filter(struct rde_aspath **new, stru + if (new != NULL) + *new = NULL; + ++ if (asp->flags & F_ATTR_PARSE_ERR) ++ /* ++ * don't try to filter bad updates but let them through ++ * so they act as implicit withdraws ++ */ ++ return (action); ++ TAILQ_FOREACH(f, rules, entry) { if (dir != f->dir) continue; @@ -30,7 +40,7 @@ diff -u -p -r1.1.1.1 -r1.3 if (f->peer.groupid != 0 && f->peer.groupid != peer->conf.groupid) continue; -@@ -283,8 +285,11 @@ rde_filter_match(struct filter_rule *f, +@@ -283,8 +292,11 @@ rde_filter_match(struct filter_rule *f, return (0); } @@ -44,7 +54,7 @@ diff -u -p -r1.1.1.1 -r1.3 if (prefix_compare(prefix, &f->match.prefix.addr, f->match.prefix.len)) return (0); -@@ -614,4 +619,5 @@ filterset_name(enum action_types type) +@@ -614,4 +626,5 @@ filterset_name(enum action_types type) } fatalx("filterset_name: got lost"); diff --git a/net/openbgpd/files/patch-bgpd_rde_rib.c b/net/openbgpd/files/patch-bgpd_rde_rib.c index 6bd5c74700ce..b97227681b84 100644 --- a/net/openbgpd/files/patch-bgpd_rde_rib.c +++ b/net/openbgpd/files/patch-bgpd_rde_rib.c @@ -2,10 +2,10 @@ Index: bgpd/rde_rib.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_rib.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.4 +diff -u -p -r1.1.1.1 -r1.4 --- bgpd/rde_rib.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde_rib.c 9 Jul 2009 17:22:14 -0000 1.3 ++++ bgpd/rde_rib.c 22 Oct 2009 15:10:02 -0000 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_rib.c,v 1.96 2007/06/01 04:17:30 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.116 2009/06/29 14:13:48 claudio Exp $ */ @@ -73,7 +73,7 @@ diff -u -p -r1.1.1.1 -r1.3 + bzero(&ribs[id], sizeof(struct rib)); + strlcpy(ribs[id].name, name, sizeof(ribs[id].name)); + RB_INIT(&ribs[id].rib); -+ ribs[id].state = RIB_ACTIVE; ++ ribs[id].state = RIB_NEW; + ribs[id].id = id; + ribs[id].flags = flags; + diff --git a/net/openbgpd/files/patch-bgpd_rde_update.c b/net/openbgpd/files/patch-bgpd_rde_update.c index 8a611da33d96..fc034a3f7429 100644 --- a/net/openbgpd/files/patch-bgpd_rde_update.c +++ b/net/openbgpd/files/patch-bgpd_rde_update.c @@ -2,13 +2,13 @@ Index: bgpd/rde_update.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_update.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.4 +diff -u -p -r1.1.1.1 -r1.4 --- bgpd/rde_update.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde_update.c 9 Jul 2009 17:22:14 -0000 1.3 ++++ bgpd/rde_update.c 10 Aug 2009 21:20:05 -0000 1.4 @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_update.c,v 1.61 2007/11/27 01:13:54 claudio Exp $ */ -+/* $OpenBSD: rde_update.c,v 1.68 2009/06/06 01:10:29 claudio Exp $ */ ++/* $OpenBSD: rde_update.c,v 1.69 2009/08/06 08:53:11 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -30,7 +30,16 @@ diff -u -p -r1.1.1.1 -r1.3 #include "bgpd.h" #include "rde.h" -@@ -360,7 +367,7 @@ up_generate(struct rde_peer *peer, struc +@@ -270,6 +277,8 @@ up_test_update(struct rde_peer *peer, st + /* Do not send routes back to sender */ + return (0); + ++ if (p->aspath->flags & F_ATTR_PARSE_ERR) ++ fatalx("try to send out a botched path"); + if (p->aspath->flags & F_ATTR_LOOP) + fatalx("try to send out a looped path"); + +@@ -360,7 +369,7 @@ up_generate(struct rde_peer *peer, struc if (asp) { ua = calloc(1, sizeof(struct update_attr)); if (ua == NULL) @@ -39,7 +48,7 @@ diff -u -p -r1.1.1.1 -r1.3 if (up_generate_attr(peer, ua, asp, addr->af) == -1) { log_warnx("generation of bgp path attributes failed"); -@@ -379,7 +386,7 @@ up_generate(struct rde_peer *peer, struc +@@ -379,7 +388,7 @@ up_generate(struct rde_peer *peer, struc up = calloc(1, sizeof(struct update_prefix)); if (up == NULL) @@ -48,7 +57,7 @@ diff -u -p -r1.1.1.1 -r1.3 up->prefix = *addr; up->prefixlen = prefixlen; -@@ -404,9 +411,9 @@ up_generate_updates(struct filter_head * +@@ -404,9 +413,9 @@ up_generate_updates(struct filter_head * return; pt_getaddr(old->prefix, &addr); @@ -61,7 +70,7 @@ diff -u -p -r1.1.1.1 -r1.3 return; /* withdraw prefix */ -@@ -423,9 +430,9 @@ up_generate_updates(struct filter_head * +@@ -423,9 +432,9 @@ up_generate_updates(struct filter_head * } pt_getaddr(new->prefix, &addr); @@ -74,7 +83,7 @@ diff -u -p -r1.1.1.1 -r1.3 path_put(asp); up_generate_updates(rules, peer, NULL, old); return; -@@ -473,8 +480,8 @@ up_generate_default(struct filter_head * +@@ -473,8 +482,8 @@ up_generate_default(struct filter_head * bzero(&addr, sizeof(addr)); addr.af = af; @@ -85,7 +94,7 @@ diff -u -p -r1.1.1.1 -r1.3 path_put(fasp); path_put(asp); return; -@@ -617,7 +624,7 @@ up_generate_attr(struct rde_peer *peer, +@@ -617,7 +626,7 @@ up_generate_attr(struct rde_peer *peer, u_char *pdata; u_int32_t tmp32; in_addr_t nexthop; @@ -94,7 +103,7 @@ diff -u -p -r1.1.1.1 -r1.3 u_int16_t len = sizeof(up_attr_buf), wlen = 0, plen; u_int8_t l; -@@ -629,7 +636,7 @@ up_generate_attr(struct rde_peer *peer, +@@ -629,7 +638,7 @@ up_generate_attr(struct rde_peer *peer, /* aspath */ if (!peer->conf.ebgp || @@ -103,7 +112,7 @@ diff -u -p -r1.1.1.1 -r1.3 pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen); else pdata = aspath_prepend(a->aspath, rde_local_as(), 1, &plen); -@@ -762,25 +769,29 @@ up_generate_attr(struct rde_peer *peer, +@@ -762,25 +771,29 @@ up_generate_attr(struct rde_peer *peer, /* NEW to OLD conversion when going sending stuff to a 2byte AS peer */ if (neednewpath) { if (!peer->conf.ebgp || @@ -140,7 +149,7 @@ diff -u -p -r1.1.1.1 -r1.3 return (-1); wlen += r; len -= r; } -@@ -913,13 +924,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_ +@@ -913,13 +926,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_ return (NULL); datalen += 3; /* afi + safi */ @@ -155,7 +164,7 @@ diff -u -p -r1.1.1.1 -r1.3 /* prepend header, need to do it reverse */ /* safi & afi */ buf[--wpos] = SAFI_UNICAST; -@@ -929,11 +934,15 @@ up_dump_mp_unreach(u_char *buf, u_int16_ +@@ -929,11 +936,15 @@ up_dump_mp_unreach(u_char *buf, u_int16_ /* attribute length */ if (datalen > 255) { @@ -172,7 +181,7 @@ diff -u -p -r1.1.1.1 -r1.3 /* mp attribute */ buf[--wpos] = (u_char)ATTR_MP_UNREACH_NLRI; -@@ -954,7 +963,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_ +@@ -954,7 +965,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_ /* total length includes the two 2-bytes length fields. */ *len = attrlen + 2 * sizeof(u_int16_t); diff --git a/net/openbgpd/files/patch-bgpd_session.c b/net/openbgpd/files/patch-bgpd_session.c index 8abb370a3ac3..5b7b15c9f99b 100644 --- a/net/openbgpd/files/patch-bgpd_session.c +++ b/net/openbgpd/files/patch-bgpd_session.c @@ -2,13 +2,13 @@ Index: bgpd/session.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/session.c,v retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 +retrieving revision 1.5 +diff -u -p -r1.1.1.1 -r1.5 --- bgpd/session.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/session.c 9 Jul 2009 17:22:14 -0000 1.3 ++++ bgpd/session.c 22 Oct 2009 15:10:02 -0000 1.5 @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.282 2008/06/26 00:01:51 claudio Exp $ */ -+/* $OpenBSD: session.c,v 1.293 2009/06/07 05:56:24 eric Exp $ */ ++/* $OpenBSD: session.c,v 1.294 2009/07/24 13:09:29 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -23,7 +23,17 @@ diff -u -p -r1.1.1.1 -r1.3 void session_sighdlr(int); int setup_listeners(u_int *); void init_conf(struct bgpd_config *); -@@ -177,8 +181,8 @@ setup_listeners(u_int *la_cnt) +@@ -65,8 +69,7 @@ void session_accept(int); + int session_connect(struct peer *); + void session_tcp_established(struct peer *); + void session_capa_ann_none(struct peer *); +-int session_capa_add(struct peer *, struct buf *, u_int8_t, u_int8_t, +- u_int8_t *); ++int session_capa_add(struct buf *, u_int8_t, u_int8_t); + int session_capa_add_mp(struct buf *, u_int16_t, u_int8_t); + struct bgp_msg *session_newmsg(enum msg_type, u_int16_t); + int session_sendmsg(struct bgp_msg *, struct peer *); +@@ -177,8 +180,8 @@ setup_listeners(u_int *la_cnt) pid_t session_main(struct bgpd_config *config, struct peer *cpeers, struct network_head *net_l, struct filter_head *rules, @@ -34,7 +44,7 @@ diff -u -p -r1.1.1.1 -r1.3 { int nfds, timeout; unsigned int i, j, idx_peers, idx_listeners, idx_mrts; -@@ -195,6 +199,7 @@ session_main(struct bgpd_config *config, +@@ -195,6 +198,7 @@ session_main(struct bgpd_config *config, struct pollfd *pfd = NULL; struct ctl_conn *ctl_conn; struct listen_addr *la; @@ -42,7 +52,7 @@ diff -u -p -r1.1.1.1 -r1.3 void *newp; short events; -@@ -283,6 +288,11 @@ session_main(struct bgpd_config *config, +@@ -283,6 +287,11 @@ session_main(struct bgpd_config *config, LIST_REMOVE(m, entry); free(m); } @@ -54,7 +64,25 @@ diff -u -p -r1.1.1.1 -r1.3 while (session_quit == 0) { /* check for peers to be initialized or deleted */ -@@ -341,7 +351,7 @@ session_main(struct bgpd_config *config, +@@ -302,7 +311,7 @@ session_main(struct bgpd_config *config, + + /* reinit due? */ + if (p->conf.reconf_action == RECONF_REINIT) { +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ERR_CEASE_ADMIN_RESET); + timer_set(p, Timer_IdleHold, 0); + } + +@@ -311,7 +320,7 @@ session_main(struct bgpd_config *config, + if (p->demoted) + session_demote(p, -1); + p->conf.demote_group[0] = 0; +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ERR_CEASE_PEER_UNCONF); + log_peer_warnx(&p->conf, "removed"); + if (last != NULL) + last->next = next; +@@ -341,7 +350,7 @@ session_main(struct bgpd_config *config, mrt_cnt = 0; LIST_FOREACH(m, &mrthead, entry) @@ -63,7 +91,7 @@ diff -u -p -r1.1.1.1 -r1.3 mrt_cnt++; if (mrt_cnt > mrt_l_elms) { -@@ -438,6 +448,12 @@ session_main(struct bgpd_config *config, +@@ -438,6 +447,12 @@ session_main(struct bgpd_config *config, Timer_IdleHoldReset, p->IdleHoldTime); break; @@ -76,7 +104,7 @@ diff -u -p -r1.1.1.1 -r1.3 default: fatalx("King Bula lost in time"); } -@@ -446,17 +462,6 @@ session_main(struct bgpd_config *config, +@@ -446,17 +461,6 @@ session_main(struct bgpd_config *config, nextaction < timeout) timeout = nextaction; @@ -94,7 +122,7 @@ diff -u -p -r1.1.1.1 -r1.3 /* are we waiting for a write? */ events = POLLIN; if (p->wbuf.queued > 0 || p->state == STATE_CONNECT) -@@ -474,8 +479,8 @@ session_main(struct bgpd_config *config, +@@ -474,8 +478,8 @@ session_main(struct bgpd_config *config, idx_peers = i; LIST_FOREACH(m, &mrthead, entry) @@ -105,7 +133,16 @@ diff -u -p -r1.1.1.1 -r1.3 pfd[i].events = POLLOUT; mrt_l[i - idx_peers] = m; i++; -@@ -594,6 +599,8 @@ init_conf(struct bgpd_config *c) +@@ -556,7 +560,7 @@ session_main(struct bgpd_config *config, + + while ((p = peers) != NULL) { + peers = p->next; +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ERR_CEASE_ADMIN_DOWN); + pfkey_remove(p); + free(p); + } +@@ -594,6 +598,8 @@ init_conf(struct bgpd_config *c) { if (!c->holdtime) c->holdtime = INTERVAL_HOLD; @@ -114,7 +151,7 @@ diff -u -p -r1.1.1.1 -r1.3 } void -@@ -668,7 +675,7 @@ bgp_fsm(struct peer *peer, enum session_ +@@ -668,7 +674,7 @@ bgp_fsm(struct peer *peer, enum session_ } else { change_state(peer, STATE_CONNECT, event); timer_set(peer, Timer_ConnectRetry, @@ -123,7 +160,7 @@ diff -u -p -r1.1.1.1 -r1.3 session_connect(peer); } peer->passive = 0; -@@ -693,13 +700,13 @@ bgp_fsm(struct peer *peer, enum session_ +@@ -693,13 +699,13 @@ bgp_fsm(struct peer *peer, enum session_ break; case EVNT_CON_OPENFAIL: timer_set(peer, Timer_ConnectRetry, @@ -139,7 +176,7 @@ diff -u -p -r1.1.1.1 -r1.3 session_connect(peer); break; default: -@@ -722,7 +729,7 @@ bgp_fsm(struct peer *peer, enum session_ +@@ -722,7 +728,7 @@ bgp_fsm(struct peer *peer, enum session_ break; case EVNT_CON_OPENFAIL: timer_set(peer, Timer_ConnectRetry, @@ -148,7 +185,13 @@ diff -u -p -r1.1.1.1 -r1.3 session_close_connection(peer); change_state(peer, STATE_ACTIVE, event); break; -@@ -749,7 +756,7 @@ bgp_fsm(struct peer *peer, enum session_ +@@ -743,13 +749,12 @@ bgp_fsm(struct peer *peer, enum session_ + /* ignore */ + break; + case EVNT_STOP: +- session_notification(peer, ERR_CEASE, 0, NULL, 0); + change_state(peer, STATE_IDLE, event); + break; case EVNT_CON_CLOSED: session_close_connection(peer); timer_set(peer, Timer_ConnectRetry, @@ -157,7 +200,23 @@ diff -u -p -r1.1.1.1 -r1.3 change_state(peer, STATE_ACTIVE, event); break; case EVNT_CON_FATAL: -@@ -953,6 +960,9 @@ change_state(struct peer *peer, enum ses +@@ -788,7 +793,6 @@ bgp_fsm(struct peer *peer, enum session_ + /* ignore */ + break; + case EVNT_STOP: +- session_notification(peer, ERR_CEASE, 0, NULL, 0); + change_state(peer, STATE_IDLE, event); + break; + case EVNT_CON_CLOSED: +@@ -823,7 +827,6 @@ bgp_fsm(struct peer *peer, enum session_ + /* ignore */ + break; + case EVNT_STOP: +- session_notification(peer, ERR_CEASE, 0, NULL, 0); + change_state(peer, STATE_IDLE, event); + break; + case EVNT_CON_CLOSED: +@@ -953,6 +956,9 @@ change_state(struct peer *peer, enum ses break; case STATE_ESTABLISHED: timer_set(peer, Timer_IdleHoldReset, peer->IdleHoldTime); @@ -167,7 +226,7 @@ diff -u -p -r1.1.1.1 -r1.3 session_up(peer); break; default: /* something seriously fucked */ -@@ -961,13 +971,12 @@ change_state(struct peer *peer, enum ses +@@ -961,13 +967,12 @@ change_state(struct peer *peer, enum ses log_statechange(peer, state, event); LIST_FOREACH(mrt, &mrthead, entry) { @@ -185,16 +244,31 @@ diff -u -p -r1.1.1.1 -r1.3 } peer->prev_state = peer->state; peer->state = state; -@@ -1255,8 +1264,6 @@ session_capa_add(struct peer *p, struct - op_type = OPT_PARAM_CAPABILITIES; - op_len = sizeof(capa_code) + sizeof(capa_len) + capa_len; - tot_len = sizeof(op_type) + sizeof(op_len) + op_len; +@@ -1247,21 +1252,12 @@ session_capa_ann_none(struct peer *peer) + } + + int +-session_capa_add(struct peer *p, struct buf *opb, u_int8_t capa_code, +- u_int8_t capa_len, u_int8_t *optparamlen) ++session_capa_add(struct buf *opb, u_int8_t capa_code, u_int8_t capa_len) + { +- u_int8_t op_type, op_len, tot_len, errs = 0; ++ int errs = 0; + +- op_type = OPT_PARAM_CAPABILITIES; +- op_len = sizeof(capa_code) + sizeof(capa_len) + capa_len; +- tot_len = sizeof(op_type) + sizeof(op_len) + op_len; - if (buf_grow(opb, tot_len) == NULL) - return (1); - errs += buf_add(opb, &op_type, sizeof(op_type)); - errs += buf_add(opb, &op_len, sizeof(op_len)); +- errs += buf_add(opb, &op_type, sizeof(op_type)); +- errs += buf_add(opb, &op_len, sizeof(op_len)); errs += buf_add(opb, &capa_code, sizeof(capa_code)); -@@ -1317,22 +1324,16 @@ session_sendmsg(struct bgp_msg *msg, str + errs += buf_add(opb, &capa_len, sizeof(capa_len)); +- *optparamlen += tot_len; + return (errs); + } + +@@ -1317,22 +1313,16 @@ session_sendmsg(struct bgp_msg *msg, str struct mrt *mrt; LIST_FOREACH(mrt, &mrthead, entry) { @@ -223,16 +297,69 @@ diff -u -p -r1.1.1.1 -r1.3 free(msg); return (0); } -@@ -1348,7 +1349,7 @@ session_open(struct peer *p) +@@ -1344,36 +1334,37 @@ session_open(struct peer *p) + struct buf *opb; + struct msg_open msg; + u_int16_t len; +- u_int8_t optparamlen = 0; ++ u_int8_t op_type, optparamlen = 0; u_int errs = 0; - if ((opb = buf_open(0)) == NULL) { -+ if ((opb = buf_dynamic(0, MAX_PKTSIZE - MSGSIZE_OPEN_MIN)) == NULL) { ++ if ((opb = buf_dynamic(0, UCHAR_MAX - sizeof(op_type) - ++ sizeof(optparamlen))) == NULL) { bgp_fsm(p, EVNT_CON_FATAL); return; } -@@ -1394,10 +1395,7 @@ session_open(struct peer *p) + + /* multiprotocol extensions, RFC 4760 */ + if (p->capa.ann.mp_v4) { /* 4 bytes data */ +- errs += session_capa_add(p, opb, CAPA_MP, 4, &optparamlen); ++ errs += session_capa_add(opb, CAPA_MP, 4); + errs += session_capa_add_mp(opb, AFI_IPv4, p->capa.ann.mp_v4); + } + if (p->capa.ann.mp_v6) { /* 4 bytes data */ +- errs += session_capa_add(p, opb, CAPA_MP, 4, &optparamlen); ++ errs += session_capa_add(opb, CAPA_MP, 4); + errs += session_capa_add_mp(opb, AFI_IPv6, p->capa.ann.mp_v6); + } + + /* route refresh, RFC 2918 */ + if (p->capa.ann.refresh) /* no data */ +- errs += session_capa_add(p, opb, CAPA_REFRESH, 0, &optparamlen); ++ errs += session_capa_add(opb, CAPA_REFRESH, 0); + + /* End-of-RIB marker, RFC 4724 */ + if (p->capa.ann.restart) { /* 2 bytes data */ + u_char c[2]; + +- bzero(&c, 2); + c[0] = 0x80; /* we're always restarting */ +- errs += session_capa_add(p, opb, CAPA_RESTART, 2, &optparamlen); ++ c[1] = 0; ++ errs += session_capa_add(opb, CAPA_RESTART, 2); + errs += buf_add(opb, &c, 2); + } + +@@ -1382,10 +1373,14 @@ session_open(struct peer *p) + u_int32_t nas; + + nas = htonl(conf->as); +- errs += session_capa_add(p, opb, CAPA_AS4BYTE, 4, &optparamlen); +- errs += buf_add(opb, &nas, 4); ++ errs += session_capa_add(opb, CAPA_AS4BYTE, sizeof(nas)); ++ errs += buf_add(opb, &nas, sizeof(nas)); + } + ++ if (buf_size(opb)) ++ optparamlen = buf_size(opb) + sizeof(op_type) + ++ sizeof(optparamlen); ++ + len = MSGSIZE_OPEN_MIN + optparamlen; + if (errs || (buf = session_newmsg(OPEN, len)) == NULL) { + buf_free(opb); +@@ -1394,10 +1389,7 @@ session_open(struct peer *p) } msg.version = 4; @@ -244,7 +371,43 @@ diff -u -p -r1.1.1.1 -r1.3 if (p->conf.holdtime) msg.holdtime = htons(p->conf.holdtime); else -@@ -1809,13 +1807,13 @@ parse_header(struct peer *peer, u_char * +@@ -1411,8 +1403,13 @@ session_open(struct peer *p) + errs += buf_add(buf->buf, &msg.bgpid, sizeof(msg.bgpid)); + errs += buf_add(buf->buf, &msg.optparamlen, sizeof(msg.optparamlen)); + +- if (optparamlen) +- errs += buf_add(buf->buf, opb->buf, optparamlen); ++ if (optparamlen) { ++ op_type = OPT_PARAM_CAPABILITIES; ++ optparamlen = buf_size(opb); ++ errs += buf_add(buf->buf, &op_type, sizeof(op_type)); ++ errs += buf_add(buf->buf, &optparamlen, sizeof(optparamlen)); ++ errs += buf_add(buf->buf, opb->buf, buf_size(opb)); ++ } + + buf_free(opb); + +@@ -1487,7 +1484,6 @@ session_notification(struct peer *p, u_i + { + struct bgp_msg *buf; + u_int errs = 0; +- u_int8_t null8 = 0; + + if (p->stats.last_sent_errcode) /* some notification already sent */ + return; +@@ -1499,10 +1495,7 @@ session_notification(struct peer *p, u_i + } + + errs += buf_add(buf->buf, &errcode, sizeof(errcode)); +- if (errcode == ERR_CEASE) +- errs += buf_add(buf->buf, &null8, sizeof(null8)); +- else +- errs += buf_add(buf->buf, &subcode, sizeof(subcode)); ++ errs += buf_add(buf->buf, &subcode, sizeof(subcode)); + + if (datalen > 0) + errs += buf_add(buf->buf, data, datalen); +@@ -1809,13 +1802,13 @@ parse_header(struct peer *peer, u_char * return (-1); } LIST_FOREACH(mrt, &mrthead, entry) { @@ -263,7 +426,36 @@ diff -u -p -r1.1.1.1 -r1.3 } return (0); } -@@ -2193,22 +2191,20 @@ parse_capabilities(struct peer *peer, u_ +@@ -1859,12 +1852,6 @@ parse_open(struct peer *peer) + p += sizeof(short_as); + as = peer->short_as = ntohs(short_as); + +- /* if remote-as is zero and it's a cloned neighbor, accept any */ +- if (peer->conf.cloned && !peer->conf.remote_as && as != AS_TRANS) { +- peer->conf.remote_as = as; +- peer->conf.ebgp = (peer->conf.remote_as != conf->as); +- } +- + memcpy(&oholdtime, p, sizeof(oholdtime)); + p += sizeof(oholdtime); + +@@ -1972,6 +1959,15 @@ parse_open(struct peer *peer) + } + } + ++ /* if remote-as is zero and it's a cloned neighbor, accept any */ ++ if (peer->conf.cloned && !peer->conf.remote_as && as != AS_TRANS) { ++ peer->conf.remote_as = as; ++ peer->conf.ebgp = (peer->conf.remote_as != conf->as); ++ if (!peer->conf.ebgp) ++ /* force enforce_as off for iBGP sessions */ ++ peer->conf.enforce_as = ENFORCE_AS_OFF; ++ } ++ + if (peer->conf.remote_as != as) { + log_peer_warnx(&peer->conf, "peer sent wrong AS %s", + log_as(as)); +@@ -2193,22 +2189,20 @@ parse_capabilities(struct peer *peer, u_ memcpy(&mp_safi, capa_val + 3, sizeof(mp_safi)); switch (mp_afi) { case AFI_IPv4: @@ -294,7 +486,7 @@ diff -u -p -r1.1.1.1 -r1.3 break; default: /* ignore */ break; -@@ -2318,7 +2314,7 @@ session_dispatch_imsg(struct imsgbuf *ib +@@ -2318,7 +2312,7 @@ session_dispatch_imsg(struct imsgbuf *ib fatalx("king bula sez: " "expected REINIT"); @@ -303,7 +495,17 @@ diff -u -p -r1.1.1.1 -r1.3 log_warnx("expected to receive fd for " "%s but didn't receive any", log_sockaddr((struct sockaddr *) -@@ -2429,7 +2425,7 @@ session_dispatch_imsg(struct imsgbuf *ib +@@ -2416,7 +2410,8 @@ session_dispatch_imsg(struct imsgbuf *ib + bgp_fsm(p, EVNT_START); + } else if (!depend_ok && p->depend_ok) { + p->depend_ok = depend_ok; +- bgp_fsm(p, EVNT_STOP); ++ session_stop(p, ++ ERR_CEASE_OTHER_CHANGE); + } + } + break; +@@ -2429,7 +2424,7 @@ session_dispatch_imsg(struct imsgbuf *ib } memcpy(&xmrt, imsg.data, sizeof(struct mrt)); @@ -312,7 +514,7 @@ diff -u -p -r1.1.1.1 -r1.3 log_warnx("expected to receive fd for mrt dump " "but didn't receive any"); -@@ -2440,12 +2436,12 @@ session_dispatch_imsg(struct imsgbuf *ib +@@ -2440,12 +2435,12 @@ session_dispatch_imsg(struct imsgbuf *ib if (mrt == NULL) fatal("session_dispatch_imsg"); memcpy(mrt, &xmrt, sizeof(struct mrt)); @@ -328,3 +530,41 @@ diff -u -p -r1.1.1.1 -r1.3 } break; case IMSG_MRT_CLOSE: +@@ -2667,7 +2662,7 @@ getpeerbyip(struct sockaddr *ip) + newpeer->conf.remote_masklen = 32; + } + if (newpeer->conf.remote_addr.af == AF_INET6) { +- memcpy(&p->conf.remote_addr.v6, ++ memcpy(&newpeer->conf.remote_addr.v6, + &((struct sockaddr_in6 *)ip)->sin6_addr, + sizeof(newpeer->conf.remote_addr.v6)); + newpeer->conf.remote_masklen = 128; +@@ -2675,7 +2670,7 @@ getpeerbyip(struct sockaddr *ip) + newpeer->conf.template = 0; + newpeer->conf.cloned = 1; + newpeer->state = newpeer->prev_state = STATE_NONE; +- newpeer->conf.reconf_action = RECONF_REINIT; ++ newpeer->conf.reconf_action = RECONF_KEEP; + newpeer->rbuf = NULL; + init_peer(newpeer); + bgp_fsm(newpeer, EVNT_START); +@@ -2845,3 +2840,19 @@ session_demote(struct peer *p, int level + + p->demoted += level; + } ++ ++void ++session_stop(struct peer *peer, u_int8_t subcode) ++{ ++ switch (peer->state) { ++ case STATE_OPENSENT: ++ case STATE_OPENCONFIRM: ++ case STATE_ESTABLISHED: ++ session_notification(peer, ERR_CEASE, subcode, NULL, 0); ++ break; ++ default: ++ /* session not open, no need to send notification */ ++ break; ++ } ++ bgp_fsm(peer, EVNT_STOP); ++} diff --git a/net/openbgpd/files/patch-bgpd_session.h b/net/openbgpd/files/patch-bgpd_session.h index ddd590114c1f..b7d84da0b6d2 100644 --- a/net/openbgpd/files/patch-bgpd_session.h +++ b/net/openbgpd/files/patch-bgpd_session.h @@ -2,10 +2,10 @@ Index: bgpd/session.h =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/session.h,v retrieving revision 1.1.1.1 -retrieving revision 1.1.1.2 -diff -u -p -r1.1.1.1 -r1.1.1.2 +retrieving revision 1.1.1.3 +diff -u -p -r1.1.1.1 -r1.1.1.3 --- bgpd/session.h 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/session.h 9 Jul 2009 16:49:54 -0000 1.1.1.2 ++++ bgpd/session.h 22 Oct 2009 14:24:02 -0000 1.1.1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.98 2008/05/08 09:53:12 henning Exp $ */ +/* $OpenBSD: session.h,v 1.101 2009/06/05 20:26:38 claudio Exp $ */ @@ -20,7 +20,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 Timer_Max }; -@@ -227,7 +228,8 @@ struct ctl_timer { +@@ -227,13 +228,15 @@ struct ctl_timer { void session_socket_blockmode(int, enum blockmodes); pid_t session_main(struct bgpd_config *, struct peer *, struct network_head *, struct filter_head *, @@ -30,7 +30,14 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 void bgp_fsm(struct peer *, enum session_events); int session_neighbor_rrefresh(struct peer *p); struct peer *getpeerbyaddr(struct bgpd_addr *); -@@ -254,8 +256,8 @@ void prepare_listeners(struct bgpd_conf + struct peer *getpeerbydesc(const char *); + int imsg_compose_parent(int, pid_t, void *, u_int16_t); + int imsg_compose_rde(int, pid_t, void *, u_int16_t); ++void session_stop(struct peer *, u_int8_t); + + /* log.c */ + char *log_fmt_peer(const struct peer_config *); +@@ -254,8 +257,8 @@ void prepare_listeners(struct bgpd_conf /* rde.c */ pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *, @@ -41,7 +48,7 @@ diff -u -p -r1.1.1.1 -r1.1.1.2 /* control.c */ int control_init(int, char *); -@@ -270,8 +272,9 @@ int pfkey_remove(struct peer *); +@@ -270,8 +273,9 @@ int pfkey_remove(struct peer *); int pfkey_init(struct bgpd_sysdep *); /* printconf.c */ -- cgit