Allow the AS path of a received route to contain the recipient BGP speaker's
AS number any number of times, avoiding Route Decision Engine loop prevention
for this peer. This is a feature that should rarely be needed. Usually the
need for this feature suggests something wrong on the current BGP setup.
However in some particular setups it's just needed, and can be used without
breaking BGP or adding loops. Cisco, Juniper and other BGP routing daemons do
offer the same feature, sometimes with explicit control of how many times the
AS number is accepted in the as-path. It does not help, the wrong setup will
loop anyway, therefore we just allow it any number of times.

On bgpd.conf(5), use it on a per neighbor/group basis:

	group "my_peers" {
		allowas-in
		(...)
		neighbor $a_peer {
			(...)
			allowas-in
		}
	}

Shamely, I didn't patch bgpd.conf(5), therefore it's more than welcome.
-- Patrick Tracanelli <patrick@serveru.us>

diff -ur bgpctl/parser.h ~proapps/bgpctl/parser.h
--- bgpctl/parser.h	2015-01-23 23:31:01.577342975 -0200
+++ bgpctl/parser.h	2015-01-23 23:24:28.597360000 -0200
@@ -44,6 +44,7 @@
 	NEIGHBOR,
 	NEIGHBOR_UP,
 	NEIGHBOR_DOWN,
+	ASIN,
 	NEIGHBOR_CLEAR,
 	NEIGHBOR_RREFRESH,
 	NETWORK_ADD,
diff -ur bgpd/bgpd.h ~proapps/bgpd/bgpd.h
--- bgpd/bgpd.h	2015-01-23 23:31:01.607382547 -0200
+++ ~proapps/bgpd/bgpd.h	2015-01-23 23:33:55.404600629 -0200
@@ -88,6 +88,7 @@
 #define	F_CTL_ADJ_IN		0x2000
 #define	F_CTL_ADJ_OUT		0x4000
 #define	F_CTL_ACTIVE		0x8000
+#define	F_ASIN			0x9000
 
 /*
  * Limit the number of control messages generated by the RDE and queued in
@@ -307,6 +308,7 @@
 	u_int8_t		 distance;	/* 1 = direct, >1 = multihop */
 	u_int8_t		 passive;
 	u_int8_t		 down;
+	u_int8_t		 asin;
 	u_int8_t		 announce_capa;
 	u_int8_t		 reflector_client;
 	u_int8_t		 softreconfig_in;
diff -ur bgpd/parse.y ~proapps/bgpd/parse.y
--- bgpd/parse.y	2015-01-23 23:31:01.678126734 -0200
+++ ~proapps/bgpd/parse.y	2015-01-23 23:20:44.100628000 -0200
@@ -174,7 +174,7 @@
 %token	GROUP NEIGHBOR NETWORK
 %token	REMOTEAS DESCR LLIFACE LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART
 %token	ANNOUNCE CAPABILITIES REFRESH AS4BYTE CONNECTRETRY
-%token	DEMOTE ENFORCE NEIGHBORAS REFLECTOR DEPEND DOWN SOFTRECONFIG
+%token	DEMOTE ENFORCE NEIGHBORAS REFLECTOR DEPEND DOWN ASIN SOFTRECONFIG
 %token	DUMP IN OUT SOCKET RESTRICTED
 %token	LOG ROUTECOLL TRANSPARENT
 %token	TCP MD5SIG PASSWORD KEY TTLSECURITY
@@ -995,6 +995,9 @@
 		| DOWN		{
 			curpeer->conf.down = 1;
 		}
+		| ASIN		{
+			curpeer->conf.asin = 1;
+		}
 		| RIB STRING	{
 			if (!find_rib($2)) {
 				yyerror("rib \"%s\" does not exist.", $2);
@@ -2149,6 +2152,7 @@
 		{ "IPv6",		IPV6},
 		{ "ah",			AH},
 		{ "allow",		ALLOW},
+		{ "allowas-in",		ASIN},
 		{ "announce",		ANNOUNCE},
 		{ "any",		ANY},
 		{ "as-4byte",		AS4BYTE },
diff -ur bgpd/printconf.c ~proapps/bgpd/printconf.c
--- bgpd/printconf.c	2015-01-23 23:31:01.697349009 -0200
+++ ~proapps/bgpd/printconf.c	2015-01-23 23:21:45.037370000 -0200
@@ -360,6 +360,8 @@
 		printf("%s\tremote-as %s\n", c, log_as(p->remote_as));
 	if (p->down)
 		printf("%s\tdown\n", c);
+	if (p->asin)
+		printf("%s\tallowas-in\n", c);
 	if (p->distance > 1)
 		printf("%s\tmultihop %u\n", c, p->distance);
 	if (p->passive)
diff -ur bgpd/rde.c ~proapps/bgpd/rde.c
--- bgpd/rde.c	2015-01-23 23:31:01.707337429 -0200
+++ ~proapps/bgpd/rde.c	2015-01-23 23:26:54.317349000 -0200
@@ -1177,8 +1177,8 @@
 	/* shift to NLRI information */
 	p += 2 + attrpath_len;
 
-	/* aspath needs to be loop free nota bene this is not a hard error */
-	if (peer->conf.ebgp && !aspath_loopfree(asp->aspath, conf->as))
+	/* unless allowas-in, aspath needs to be loop free nota bene this is not a hard error */
+	if (peer->conf.ebgp && !peer->conf.asin && !aspath_loopfree(asp->aspath, conf->as))
 		asp->flags |= F_ATTR_LOOP;
 
 	/* parse nlri prefix */
