Commit a15dab76 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Implements 'allow local as' option.

Similar to allowas-in option on other routers.
parent f8cc7396
......@@ -1486,6 +1486,16 @@ for each neighbor using the following configuration parameters:
This option requires that the connected routing table is
<ref id="dsc-sorted" name="sorted">. Default: off.
<tag>allow local as [<m/number/]</tag>
BGP prevents routing loops by rejecting received routes with
the local AS number in the AS path. This option allows to
loose or disable the check. Optional <cf/number/ argument can
be used to specify the maximum number of local ASNs in the AS
path that is allowed for received routes. When the option is
used without the argument, the check is completely disabled
and you should ensure loop-free behavior by some other means.
Default: 0 (no local AS number allowed).
<tag>enable route refresh <m/switch/</tag> When BGP speaker
changes its import filter, it has to re-examine all routes
received from its neighbor against the new filter. As these
......
......@@ -392,7 +392,7 @@ val_in_range(struct f_val v1, struct f_val v2)
return as_path_match(v1.val.ad, v2.val.path_mask);
if ((v1.type == T_INT) && (v2.type == T_PATH))
return as_path_is_member(v2.val.ad, v1.val.i);
return as_path_contains(v2.val.ad, v1.val.i, 1);
if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
return int_set_contains(v2.val.ad, v1.val.i);
......
......@@ -244,10 +244,11 @@ as_path_get_first(struct adata *path, u32 *last_as)
}
int
as_path_is_member(struct adata *path, u32 as)
as_path_contains(struct adata *path, u32 as, int min)
{
u8 *p = path->data;
u8 *q = p+path->length;
int num = 0;
int i, n;
while (p<q)
......@@ -257,7 +258,8 @@ as_path_is_member(struct adata *path, u32 as)
for(i=0; i<n; i++)
{
if (get_as(p) == as)
return 1;
if (++num == min)
return 1;
p += BS;
}
}
......
......@@ -35,7 +35,7 @@ int as_path_getlen(struct adata *path);
int as_path_getlen_int(struct adata *path, int bs);
int as_path_get_first(struct adata *path, u32 *orig_as);
int as_path_get_last(struct adata *path, u32 *last_as);
int as_path_is_member(struct adata *path, u32 as);
int as_path_contains(struct adata *path, u32 as, int min);
int as_path_match_set(struct adata *path, struct f_tree *set);
struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos);
......
......@@ -950,8 +950,9 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
static inline int
bgp_as_path_loopy(struct bgp_proto *p, rta *a)
{
int num = p->cf->allow_local_as + 1;
eattr *e = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH));
return (e && as_path_is_member(e->u.ptr, p->local_as));
return (e && (num > 0) && as_path_contains(e->u.ptr, p->local_as, num));
}
static inline int
......
......@@ -44,6 +44,7 @@ struct bgp_config {
int passive; /* Do not initiate outgoing connection */
int interpret_communities; /* Hardwired handling of well-known communities */
int secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */
unsigned connect_retry_time;
unsigned hold_time, initial_hold_time;
unsigned keepalive_time;
......
......@@ -26,7 +26,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
PREFER, OLDER, MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH,
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
SECONDARY)
SECONDARY, ALLOW)
CF_GRAMMAR
......@@ -108,6 +108,8 @@ bgp_proto:
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
| bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
| bgp_proto ALLOW LOCAL AS ';' { BGP_CFG->allow_local_as = -1; }
| bgp_proto ALLOW LOCAL AS expr ';' { BGP_CFG->allow_local_as = $5; }
| bgp_proto IGP TABLE rtable ';' { BGP_CFG->igp_table = $4; }
| bgp_proto TTL SECURITY bool ';' { BGP_CFG->ttl_security = $4; }
;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment