'backport' asn validation in -f/-G

This commit is contained in:
Alexandre Snarskii
2018-09-05 14:47:30 +03:00
parent 51e27a7292
commit 7d2a9f185b
4 changed files with 56 additions and 4 deletions

View File

@@ -7,6 +7,10 @@ untagged yet (2018-09-05)
- fix ipv6 prefix-ranges. Reported by Jay Ford. - fix ipv6 prefix-ranges. Reported by Jay Ford.
- OpenBGPd change: -E now generates prefix-set instead of prefix-list. - OpenBGPd change: -E now generates prefix-set instead of prefix-list.
Based on submission by Denis Fondras Based on submission by Denis Fondras
- new option -w, allowing to 'validate' AS numbers included in as-path
access-lists: only those AS having registered route-objects are allowed.
By default checks route[4] presence, to check route6 objects shall be
used together with -6.
0.1.35-rc2 (2017-06-14) 0.1.35-rc2 (2017-06-14)
- OpenBSD need <sys/select.h>. Reported by Denis Fondras. - OpenBSD need <sys/select.h>. Reported by Denis Fondras.

16
bgpq3.c
View File

@@ -27,7 +27,7 @@ int
usage(int ecode) usage(int ecode)
{ {
printf("\nUsage: bgpq3 [-h host[:port]] [-S sources] [-P|E|G <num>|f <num>]" printf("\nUsage: bgpq3 [-h host[:port]] [-S sources] [-P|E|G <num>|f <num>]"
" [-2346ABbDJjXd] [-R len] <OBJECTS>...\n"); " [-2346ABbDdJjwXz] [-R len] <OBJECTS>...\n");
printf(" -2 : allow routes belonging to as23456 (transition-as) " printf(" -2 : allow routes belonging to as23456 (transition-as) "
"(default: false)\n"); "(default: false)\n");
printf(" -3 : assume that your device is asn32-safe\n"); printf(" -3 : assume that your device is asn32-safe\n");
@@ -69,6 +69,8 @@ usage(int ecode)
printf(" -U : generate config for Huawei (Cisco IOS by default)\n"); printf(" -U : generate config for Huawei (Cisco IOS by default)\n");
printf(" -W len : specify max-entries on as-path line (use 0 for " printf(" -W len : specify max-entries on as-path line (use 0 for "
"infinity)\n"); "infinity)\n");
printf(" -w : 'validate' AS numbers: accept only ones with "
"registered routes\n");
printf(" -X : generate config for IOS XR (Cisco IOS by default)\n"); printf(" -X : generate config for IOS XR (Cisco IOS by default)\n");
printf("\n" PACKAGE_NAME " version: " PACKAGE_VERSION "\n"); printf("\n" PACKAGE_NAME " version: " PACKAGE_VERSION "\n");
printf("Copyright(c) Alexandre Snarskii <snar@snar.spb.ru> 2007-2018\n\n"); printf("Copyright(c) Alexandre Snarskii <snar@snar.spb.ru> 2007-2018\n\n");
@@ -140,7 +142,7 @@ main(int argc, char* argv[])
if (getenv("IRRD_SOURCES")) if (getenv("IRRD_SOURCES"))
expander.sources=getenv("IRRD_SOURCES"); expander.sources=getenv("IRRD_SOURCES");
while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJf:l:L:m:M:NW:Ppr:R:G:Th:UXsz")) while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJf:l:L:m:M:NW:Ppr:R:G:Th:UwXsz"))
!=EOF) { !=EOF) {
switch(c) { switch(c) {
case '2': case '2':
@@ -312,6 +314,8 @@ main(int argc, char* argv[])
}; };
widthSet=1; widthSet=1;
break; break;
case 'w': expander.validate_asns=1;
break;
case 'X': if(expander.vendor) vendor_exclusive(); case 'X': if(expander.vendor) vendor_exclusive();
expander.vendor=V_CISCO_XR; expander.vendor=V_CISCO_XR;
break; break;
@@ -530,11 +534,17 @@ main(int argc, char* argv[])
}; };
if((expander.generation==T_ASPATH || expander.generation==T_OASPATH) && if((expander.generation==T_ASPATH || expander.generation==T_OASPATH) &&
af != AF_INET) { af != AF_INET && !expander.validate_asns) {
sx_report(SX_FATAL, "Sorry, -6 makes no sense with as-path (-f/-G) " sx_report(SX_FATAL, "Sorry, -6 makes no sense with as-path (-f/-G) "
"generation\n"); "generation\n");
}; };
if (expander.validate_asns && expander.generation != T_ASPATH &&
expander.generation != T_OASPATH) {
sx_report(SX_FATAL, "Sorry, -w makes sense only for as-path (-f/-G) "
"generation\n");
};
if(!argv[0]) if(!argv[0])
usage(1); usage(1);

View File

@@ -56,6 +56,7 @@ struct bgpq_expander {
int identify; int identify;
int sequence; int sequence;
int maxdepth; int maxdepth;
int validate_asns;
unsigned char asn32; unsigned char asn32;
unsigned char* asn32s[65536]; unsigned char* asn32s[65536];
struct bgpq_prequest* firstpipe, *lastpipe; struct bgpq_prequest* firstpipe, *lastpipe;

View File

@@ -13,6 +13,7 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <stdarg.h> #include <stdarg.h>
@@ -380,6 +381,38 @@ bgpq_pipeline(struct bgpq_expander* b,
return bp; return bp;
}; };
static void
bgpq_expander_invalidate_asn(struct bgpq_expander* b, const char* q)
{
if (!strncmp(q, "!gas", 4) || !strncmp(q, "!6as", 4)) {
char* eptr;
unsigned long asn = strtoul(q+4, &eptr, 10), asn0, asn1 = 0;
if (!asn || asn == ULONG_MAX || asn >= 4294967295 ||
(eptr && *eptr != '\n' && *eptr != '\r' && *eptr != '.')) {
sx_report(SX_ERROR, "some problem invalidating asn %s\n", q);
return;
};
if (eptr && (*eptr == '\r' || *eptr == '\n')) {
asn1 = asn;
asn0 = 0;
} else if (eptr && *eptr == '.') {
asn0 = asn;
asn1 = strtoul(eptr+1, &eptr, 10);
};
if (asn >= 65536) {
asn1 = asn % 65536;
asn0 = asn / 65536;
};
if (!b->asn32s[asn0] ||
!(b->asn32s[asn0][asn1/8] & (0x80 >> (asn1 % 8)))) {
sx_report(SX_NOTICE, "strange, invalidating inactive asn %lu(%s)\n",
asn, q);
} else {
b->asn32s[asn0][asn1/8] &= ~(0x80 >> (asn1 % 8));
};
};
};
static void static void
bgpq_write(struct bgpq_expander* b) bgpq_write(struct bgpq_expander* b)
{ {
@@ -561,10 +594,12 @@ have3:
} else if(response[0]=='C') { } else if(response[0]=='C') {
/* No data */ /* No data */
SX_DEBUG(debug_expander,"No data expanding %s\n", req->request); SX_DEBUG(debug_expander,"No data expanding %s\n", req->request);
if (b->validate_asns) bgpq_expander_invalidate_asn(b, req->request);
} else if(response[0]=='D') { } else if(response[0]=='D') {
/* .... */ /* .... */
SX_DEBUG(debug_expander,"Key not found expanding %s\n", SX_DEBUG(debug_expander,"Key not found expanding %s\n",
req->request); req->request);
if (b->validate_asns) bgpq_expander_invalidate_asn(b, req->request);
} else if(response[0]=='E') { } else if(response[0]=='E') {
sx_report(SX_ERROR, "Multiple keys expanding %s: %s\n", sx_report(SX_ERROR, "Multiple keys expanding %s: %s\n",
req->request, response); req->request, response);
@@ -707,8 +742,10 @@ have3:
free(recvbuffer); free(recvbuffer);
} else if(response[0]=='C') { } else if(response[0]=='C') {
/* no data */ /* no data */
if (b->validate_asns) bgpq_expander_invalidate_asn(b, request);
} else if(response[0]=='D') { } else if(response[0]=='D') {
/* ... */ /* ... */
if (b->validate_asns) bgpq_expander_invalidate_asn(b, request);
} else if(response[0]=='E') { } else if(response[0]=='E') {
/* XXXXXX */ /* XXXXXX */
} else if(response[0]=='F') { } else if(response[0]=='F') {
@@ -831,7 +868,7 @@ bgpq_expand(struct bgpq_expander* b)
bgpq_read(b); bgpq_read(b);
}; };
if(b->generation>=T_PREFIXLIST) { if(b->generation>=T_PREFIXLIST || b->validate_asns) {
unsigned i, j, k; unsigned i, j, k;
STAILQ_FOREACH(mc, &b->rsets, next) { STAILQ_FOREACH(mc, &b->rsets, next) {
if(b->family==AF_INET) { if(b->family==AF_INET) {