From cc31b75a8fd7949533c12db2c3e9d67eeaf46d10 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 9 Jul 2013 23:27:10 +0200 Subject: Implements 'bgppath ~ int set' filter op. --- nest/attrs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nest/attrs.h') diff --git a/nest/attrs.h b/nest/attrs.h index 42f81a10..12f2fcf4 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -25,6 +25,8 @@ * to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details */ +struct f_tree; + struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, u32 as); int as_path_convert_to_old(struct adata *path, byte *dst, int *new_used); int as_path_convert_to_new(struct adata *path, byte *dst, int req_as); @@ -34,6 +36,7 @@ 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_match_set(struct adata *path, struct f_tree *set); #define PM_ASN 0 #define PM_QUESTION 1 -- cgit v1.2.3 From bff9ce5130d16af2fd802d42bdb2bff00980c9ae Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 15 Aug 2013 01:06:47 +0200 Subject: Extends delete/filter operators to work no bgp_paths. --- doc/bird.sgml | 17 +++++++++++++-- filter/filter.c | 29 +++++++++++++++++++++++++- filter/test.conf | 4 ++++ nest/a-path.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nest/attrs.h | 2 ++ 5 files changed, 112 insertions(+), 3 deletions(-) (limited to 'nest/attrs.h') diff --git a/doc/bird.sgml b/doc/bird.sgml index 7db9fad2..3cd80c32 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1033,10 +1033,23 @@ incompatible with each other (that is to prevent you from shooting in the foot). returns the length of path prepend( prepends ASN prepend( prepends ASN delete( deletes all instances of ASN + filter( deletes all ASNs from path + can be shortened to if from.type == T_INT)) + set = v2.val.t; + else + runtime("Can't delete non-integer (set)"); + + switch (what->aux) + { + case 'a': runtime("Can't add to path"); + case 'd': pos = 0; break; + case 'f': pos = 1; break; + default: bug("unknown Ca operation"); + } + + if (pos && !set) + runtime("Can't filter integer"); + + res.type = T_PATH; + res.val.ad = as_path_filter(f_pool, v1.val.ad, set, key, pos); + } + else if (v1.type == T_CLIST) { /* Community (or cluster) list */ struct f_val dummy; diff --git a/filter/test.conf b/filter/test.conf index 4f40abff..048983b5 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -104,6 +104,8 @@ eclist el2; print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4); print "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1; print "5 = ", p2.len; + print "Delete 3: ", delete(p2, 3); + print "Filter 1-3: ", filter(p2, [1..3]); pm1 = [= 1 2 * 3 4 5 =]; p2 = prepend( + empty +, 5 ); @@ -113,6 +115,8 @@ eclist el2; p2 = prepend( p2, 2 ); p2 = prepend( p2, 1 ); print "Should be true: ", p2 ~ pm1, " ", p2, " ", pm1; + print "Delete 3: ", delete(p2, 3); + print "Delete 4-5: ", delete(p2, [4..5]); l = - empty -; print "Should be false in this special case: ", l ~ [(*,*)]; diff --git a/nest/a-path.c b/nest/a-path.c index 712e77a3..b1812981 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -287,6 +287,69 @@ as_path_match_set(struct adata *path, struct f_tree *set) return 0; } +struct adata * +as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos) +{ + if (!path) + return NULL; + + int len = path->length; + u8 *p = path->data; + u8 *q = path->data + len; + u8 *d, *d2; + int i, bt, sn, dn; + u8 buf[len]; + + d = buf; + while (p 0) + { + /* Nonempty block, set block header and advance */ + d[0] = bt; + d[1] = dn; + d = d2; + } + } + + int nl = d - buf; + if (nl == path->length) + return path; + + struct adata *res = lp_alloc(pool, sizeof(struct adata) + nl); + res->length = nl; + memcpy(res->data, buf, nl); + + return res; +} + struct pm_pos { diff --git a/nest/attrs.h b/nest/attrs.h index 12f2fcf4..44a23e18 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -37,6 +37,8 @@ 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_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); + #define PM_ASN 0 #define PM_QUESTION 1 -- cgit v1.2.3 From 7ccb36d3308ef57d340e663f0cabd24663f4f62a Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 2 Oct 2013 14:57:29 +0200 Subject: Implements C.len operator for clist and eclist types. Thanks to Sergey Popovich for the original patch. --- doc/bird.sgml | 2 ++ filter/filter.c | 4 +++- filter/test.conf | 5 +++-- nest/attrs.h | 3 +++ 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'nest/attrs.h') diff --git a/doc/bird.sgml b/doc/bird.sgml index f43eb4bf..050acf33 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1077,6 +1077,8 @@ incompatible with each other (that is to prevent you from shooting in the foot). no literals of this type. There are three special operators on clists: + returns the length of clist add( adds pair (or quad) length / 4; } +static inline int ec_set_get_size(struct adata *list) +{ return list->length / 8; } + static inline u32 *int_set_get_data(struct adata *list) { return (u32 *) list->data; } -- cgit v1.2.3 From a15dab76f93337b07b4b03a64ac3bac26285dfd9 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 21 Oct 2013 14:58:32 +0200 Subject: Implements 'allow local as' option. Similar to allowas-in option on other routers. --- doc/bird.sgml | 10 ++++++++++ filter/filter.c | 2 +- nest/a-path.c | 6 ++++-- nest/attrs.h | 2 +- proto/bgp/attrs.c | 3 ++- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 4 +++- 7 files changed, 22 insertions(+), 6 deletions(-) (limited to 'nest/attrs.h') diff --git a/doc/bird.sgml b/doc/bird.sgml index 2b9ffa02..63890031 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1486,6 +1486,16 @@ for each neighbor using the following configuration parameters: This option requires that the connected routing table is . Default: off. + allow local as [ + 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 enable route refresh When BGP speaker changes its import filter, it has to re-examine all routes received from its neighbor against the new filter. As these diff --git a/filter/filter.c b/filter/filter.c index b01933f7..a28de5df 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -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); diff --git a/nest/a-path.c b/nest/a-path.c index b1812981..dc36e653 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -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 (pcf->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 diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 77a36715..bcbdf2cc 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -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; diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index d5e5aaca..f4b2c5fe 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -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; } ; -- cgit v1.2.3