Found while looking for something else. We did not fully implement RFC7607
the AGGREGATOR and AS4_AGGREGATOR could slip through a AS 0. This fixes
the issue. While there also change the check in parse.y to only allow AS 0
for templates (the only case where remote-as can be 0 aka uninitalized).
Last but not least, order the RFC by numbers.
OK?
--
:wq Claudio
Index: bgpd.8
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.8,v
retrieving revision 1.60
diff -u -p -r1.60 bgpd.8
--- bgpd.8 4 Dec 2018 14:13:40 -0000 1.60
+++ bgpd.8 5 Aug 2019 17:06:51 -0000
@@ -353,16 +353,6 @@ control socket
.Re
.Pp
.Rs
-.%A W. Kumari
-.%A R. Bush
-.%A H. Schiller
-.%A K. Patel
-.%D August 2015
-.%R RFC 7607
-.%T Codification of AS 0 Processing
-.Re
-.Pp
-.Rs
.%A L. Blunk
.%A M. Karir
.%A C. Labovitz
@@ -378,6 +368,16 @@ control socket
.%D May 2012
.%R RFC 6608
.%T Subcodes for BGP Finite State Machine Error
+.Re
+.Pp
+.Rs
+.%A W. Kumari
+.%A R. Bush
+.%A H. Schiller
+.%A K. Patel
+.%D August 2015
+.%R RFC 7607
+.%T Codification of AS 0 Processing
.Re
.Pp
.Rs
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.397
diff -u -p -r1.397 parse.y
--- parse.y 5 Aug 2019 08:46:55 -0000 1.397
+++ parse.y 6 Aug 2019 09:39:56 -0000
@@ -4211,7 +4211,7 @@ neighbor_consistent(struct peer *p)
if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF)
p->conf.enforce_local_as = ENFORCE_AS_ON;
- if (p->conf.remote_as == 0 && p->conf.enforce_as != ENFORCE_AS_OFF) {
+ if (p->conf.remote_as == 0 && !p->conf.template) {
yyerror("peer AS may not be zero");
return (-1);
}
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.481
diff -u -p -r1.481 rde.c
--- rde.c 5 Aug 2019 08:46:55 -0000 1.481
+++ rde.c 6 Aug 2019 15:36:04 -0000
@@ -1508,7 +1508,7 @@ rde_attr_parse(u_char *p, u_int16_t len,
struct bgpd_addr nexthop;
struct rde_aspath *a = &state->aspath;
u_char *op = p, *npath;
- u_int32_t tmp32;
+ u_int32_t tmp32, zero = 0;
int error;
u_int16_t attr_len, nlen;
u_int16_t plen = 0;
@@ -1682,12 +1682,25 @@ bad_flags:
t[0] = t[1] = 0;
UPD_READ(&t[2], p, plen, 2);
UPD_READ(&t[4], p, plen, 4);
+ if (memcmp(t, &zero, sizeof(u_int32_t)) == 0) {
+ /* As per RFC7606 use "attribute discard". */
+ log_peer_warnx(&peer->conf, "bad AGGREGATOR, "
+ "AS 0 not allowed, attribute discarded");
+ break;
+ }
if (attr_optadd(a, flags, type, t,
sizeof(t)) == -1)
goto bad_list;
break;
}
/* 4-byte ready server take the default route */
+ if (memcmp(p, &zero, sizeof(u_int32_t)) == 0) {
+ /* As per RFC7606 use "attribute discard" here. */
+ log_peer_warnx(&peer->conf, "bad AGGREGATOR, "
+ "AS 0 not allowed, attribute discarded");
+ plen += attr_len;
+ break;
+ }
goto optattr;
case ATTR_COMMUNITIES:
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
@@ -1793,6 +1806,13 @@ bad_flags:
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL))
goto bad_flags;
+ if (memcmp(p, &zero, sizeof(u_int32_t)) == 0) {
+ /* As per RFC6793 use "attribute discard" here. */
+ log_peer_warnx(&peer->conf, "bad AS4_AGGREGATOR, "
+ "AS 0 not allowed, attribute discarded");
+ plen += attr_len;
+ break;
+ }
a->flags |= F_ATTR_AS4BYTE_NEW;
goto optattr;
case ATTR_AS4_PATH: