mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Add AS# ranges to bgpmask.
This commit is contained in:
parent
90dc0f0843
commit
a0fe1944d1
@ -1165,8 +1165,10 @@ foot).
|
|||||||
is 4 3 2 1, then: <tt>bgp_path ˜ [= * 4 3 * =]</tt> is true,
|
is 4 3 2 1, then: <tt>bgp_path ˜ [= * 4 3 * =]</tt> is true,
|
||||||
but <tt>bgp_path ˜ [= * 4 5 * =]</tt> is false. BGP mask
|
but <tt>bgp_path ˜ [= * 4 5 * =]</tt> is false. BGP mask
|
||||||
expressions can also contain integer expressions enclosed in parenthesis
|
expressions can also contain integer expressions enclosed in parenthesis
|
||||||
and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. There is
|
and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. You can
|
||||||
also old syntax that uses / .. / instead of [= .. =] and ? instead of *.
|
also use ranges, for example <tt>[= * 3..5 2 100..200 * =]</tt>.
|
||||||
|
There is also old (deprecated) syntax that uses / .. / instead of [= .. =]
|
||||||
|
and ? instead of *.
|
||||||
|
|
||||||
<tag/clist/
|
<tag/clist/
|
||||||
Clist is similar to a set, except that unlike other sets, it can be
|
Clist is similar to a set, except that unlike other sets, it can be
|
||||||
|
@ -627,6 +627,7 @@ bgp_path:
|
|||||||
|
|
||||||
bgp_path_tail1:
|
bgp_path_tail1:
|
||||||
NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
|
NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
|
||||||
|
| NUM DDOT NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE; $$->val = $1; $$->val2 = $3; }
|
||||||
| '*' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; }
|
| '*' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; }
|
||||||
| '?' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; $$->val = 0; }
|
| '?' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; $$->val = 0; }
|
||||||
| bgp_path_expr bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; }
|
| bgp_path_expr bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; }
|
||||||
|
@ -79,6 +79,10 @@ pm_format(struct f_path_mask *p, buffer *buf)
|
|||||||
buffer_puts(buf, "* ");
|
buffer_puts(buf, "* ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PM_ASN_RANGE:
|
||||||
|
buffer_print(buf, "%u..%u ", p->val, p->val2);
|
||||||
|
break;
|
||||||
|
|
||||||
case PM_ASN_EXPR:
|
case PM_ASN_EXPR:
|
||||||
buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
|
buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
|
||||||
break;
|
break;
|
||||||
|
@ -90,20 +90,23 @@ clist l2;
|
|||||||
eclist el;
|
eclist el;
|
||||||
eclist el2;
|
eclist el2;
|
||||||
{
|
{
|
||||||
|
print "Entering path test...";
|
||||||
pm1 = / 4 3 2 1 /;
|
pm1 = / 4 3 2 1 /;
|
||||||
pm2 = [= 4 3 2 1 =];
|
pm2 = [= 3..6 3 2 1..2 =];
|
||||||
print "Testing path masks: ", pm1, " ", pm2;
|
print "Testing path masks: ", pm1, " ", pm2;
|
||||||
p2 = prepend( + empty +, 1 );
|
p2 = prepend( + empty +, 1 );
|
||||||
p2 = prepend( p2, 2 );
|
p2 = prepend( p2, 2 );
|
||||||
p2 = prepend( p2, 3 );
|
p2 = prepend( p2, 3 );
|
||||||
p2 = prepend( p2, 4 );
|
p2 = prepend( p2, 4 );
|
||||||
print "Testing paths: ", p2;
|
print "Testing path: (4 3 2 1) = ", p2;
|
||||||
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
|
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
|
||||||
print "4 = ", p2.len;
|
print "4 = ", p2.len;
|
||||||
p2 = prepend( p2, 5 );
|
p2 = prepend( p2, 5 );
|
||||||
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)];
|
print "Testing path: (5 4 3 2 1) = ", p2;
|
||||||
|
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)], " ", p2 ~ [= 1..4 4 3 2 1 =], " ", p2 ~ [= 5 4 4..100 2 1 =];
|
||||||
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
|
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
|
||||||
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
|
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
|
||||||
|
print "Should be true: ", p2 ~ [= 5..6 4..10 1..3 1..3 1..65536 =];
|
||||||
print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);
|
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 "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1;
|
||||||
print "5 = ", p2.len;
|
print "5 = ", p2.len;
|
||||||
|
@ -435,18 +435,23 @@ parse_path(struct adata *path, struct pm_pos *pos)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pm_match(struct pm_pos *pos, u32 asn)
|
pm_match(struct pm_pos *pos, u32 asn, u32 asn2)
|
||||||
{
|
{
|
||||||
|
u32 gas;
|
||||||
if (! pos->set)
|
if (! pos->set)
|
||||||
return pos->val.asn == asn;
|
return ((pos->val.asn >= asn) && (pos->val.asn <= asn2));
|
||||||
|
|
||||||
u8 *p = pos->val.sp;
|
u8 *p = pos->val.sp;
|
||||||
int len = *p++;
|
int len = *p++;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
if (get_as(p + i * BS) == asn)
|
{
|
||||||
|
gas = get_as(p + i * BS);
|
||||||
|
|
||||||
|
if ((gas >= asn) && (gas <= asn2))
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -490,7 +495,7 @@ pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
|
|||||||
* next part of mask, we advance each marked state.
|
* next part of mask, we advance each marked state.
|
||||||
* We start with marked first position, when we
|
* We start with marked first position, when we
|
||||||
* run out of marked positions, we reject. When
|
* run out of marked positions, we reject. When
|
||||||
* we process the whole mask, we accept iff final position
|
* we process the whole mask, we accept if final position
|
||||||
* (auxiliary position after last real position in AS path)
|
* (auxiliary position after last real position in AS path)
|
||||||
* is marked.
|
* is marked.
|
||||||
*/
|
*/
|
||||||
@ -502,6 +507,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
|
|||||||
int plen = parse_path(path, pos);
|
int plen = parse_path(path, pos);
|
||||||
int l, h, i, nh, nl;
|
int l, h, i, nh, nl;
|
||||||
u32 val = 0;
|
u32 val = 0;
|
||||||
|
u32 val2 = 0;
|
||||||
|
|
||||||
/* l and h are bound of interval of positions where
|
/* l and h are bound of interval of positions where
|
||||||
are marked states */
|
are marked states */
|
||||||
@ -525,11 +531,15 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
|
|||||||
h = plen;
|
h = plen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PM_ASN:
|
case PM_ASN: /* Define single ASN as ASN..ASN - very narrow interval */
|
||||||
val = mask->val;
|
val2 = val = mask->val;
|
||||||
goto step;
|
goto step;
|
||||||
case PM_ASN_EXPR:
|
case PM_ASN_EXPR:
|
||||||
val = f_eval_asn((struct f_inst *) mask->val);
|
val2 = val = f_eval_asn((struct f_inst *) mask->val);
|
||||||
|
goto step;
|
||||||
|
case PM_ASN_RANGE:
|
||||||
|
val = mask->val;
|
||||||
|
val2 = mask->val2;
|
||||||
goto step;
|
goto step;
|
||||||
case PM_QUESTION:
|
case PM_QUESTION:
|
||||||
step:
|
step:
|
||||||
@ -538,7 +548,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
|
|||||||
if (pos[i].mark)
|
if (pos[i].mark)
|
||||||
{
|
{
|
||||||
pos[i].mark = 0;
|
pos[i].mark = 0;
|
||||||
if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val))
|
if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val, val2))
|
||||||
pm_mark(pos, i, plen, &nl, &nh);
|
pm_mark(pos, i, plen, &nl, &nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +45,13 @@ struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_
|
|||||||
#define PM_QUESTION 1
|
#define PM_QUESTION 1
|
||||||
#define PM_ASTERISK 2
|
#define PM_ASTERISK 2
|
||||||
#define PM_ASN_EXPR 3
|
#define PM_ASN_EXPR 3
|
||||||
|
#define PM_ASN_RANGE 4
|
||||||
|
|
||||||
struct f_path_mask {
|
struct f_path_mask {
|
||||||
struct f_path_mask *next;
|
struct f_path_mask *next;
|
||||||
int kind;
|
int kind;
|
||||||
uintptr_t val;
|
uintptr_t val;
|
||||||
|
uintptr_t val2;
|
||||||
};
|
};
|
||||||
|
|
||||||
int as_path_match(struct adata *path, struct f_path_mask *mask);
|
int as_path_match(struct adata *path, struct f_path_mask *mask);
|
||||||
|
Loading…
Reference in New Issue
Block a user