Filter: Allow to use sets in path masks
This commit is contained in:
parent
e2b530aa72
commit
ef113c6f72
4 changed files with 38 additions and 2 deletions
|
@ -801,6 +801,10 @@ bgp_path:
|
||||||
bgp_path_tail:
|
bgp_path_tail:
|
||||||
NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); $$->next = $2; }
|
NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); $$->next = $2; }
|
||||||
| NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); $$->next = $4; }
|
| NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); $$->next = $4; }
|
||||||
|
| '[' set_items ']' bgp_path_tail {
|
||||||
|
if ($2->from.type != T_INT) cf_error("Only integer sets allowed in path mask");
|
||||||
|
$$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .set = build_tree($2), .kind = PM_ASN_SET }, }); $$->next = $4;
|
||||||
|
}
|
||||||
| '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); $$->next = $2; }
|
| '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); $$->next = $2; }
|
||||||
| '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); $$->next = $2; }
|
| '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); $$->next = $2; }
|
||||||
| bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; }
|
| bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; }
|
||||||
|
|
|
@ -626,6 +626,7 @@ bgppath p2;
|
||||||
bt_assert(p2 !~ [8, ten..(2*ten)]);
|
bt_assert(p2 !~ [8, ten..(2*ten)]);
|
||||||
bt_assert(p2 ~ [= * 4 3 * 1 =]);
|
bt_assert(p2 ~ [= * 4 3 * 1 =]);
|
||||||
bt_assert(p2 ~ [= (3+2) (2*2) 3 2 1 =]);
|
bt_assert(p2 ~ [= (3+2) (2*2) 3 2 1 =]);
|
||||||
|
bt_assert(p2 ~ [= 5 [2, 4, 6] 3 [1..2] 1 =]);
|
||||||
bt_assert(p2 ~ mkpath(5, 4));
|
bt_assert(p2 ~ mkpath(5, 4));
|
||||||
|
|
||||||
bt_assert(p2.len = 5);
|
bt_assert(p2.len = 5);
|
||||||
|
|
|
@ -740,6 +740,31 @@ pm_match(struct pm_pos *pos, u32 asn, u32 asn2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pm_match_set(struct pm_pos *pos, struct f_tree *set)
|
||||||
|
{
|
||||||
|
struct f_val asn = { .type = T_INT };
|
||||||
|
|
||||||
|
if (! pos->set)
|
||||||
|
{
|
||||||
|
asn.val.i = pos->val.asn;
|
||||||
|
return !!find_tree(set, &asn);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 *p = pos->val.sp;
|
||||||
|
int len = *p++;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
asn.val.i = get_as(p + i * BS);
|
||||||
|
if (find_tree(set, &asn))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
|
pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
|
||||||
{
|
{
|
||||||
|
@ -824,13 +849,17 @@ as_path_match(const struct adata *path, const struct f_path_mask *mask)
|
||||||
val2 = mask->item[m].to;
|
val2 = mask->item[m].to;
|
||||||
goto step;
|
goto step;
|
||||||
case PM_QUESTION:
|
case PM_QUESTION:
|
||||||
|
case PM_ASN_SET:
|
||||||
step:
|
step:
|
||||||
nh = nl = -1;
|
nh = nl = -1;
|
||||||
for (i = h; i >= l; i--)
|
for (i = h; i >= l; i--)
|
||||||
if (pos[i].mark)
|
if (pos[i].mark)
|
||||||
{
|
{
|
||||||
pos[i].mark = 0;
|
pos[i].mark = 0;
|
||||||
if ((mask->item[m].kind == PM_QUESTION) || pm_match(pos + i, val, val2))
|
if ((mask->item[m].kind == PM_QUESTION) ||
|
||||||
|
((mask->item[m].kind != PM_ASN_SET) ?
|
||||||
|
pm_match(pos + i, val, val2) :
|
||||||
|
pm_match_set(pos + i, mask->item[m].set)))
|
||||||
pm_mark(pos, i, plen, &nl, &nh);
|
pm_mark(pos, i, plen, &nl, &nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,16 +60,18 @@ static inline struct adata *as_path_prepend(struct linpool *pool, const struct a
|
||||||
#define PM_ASTERISK 2
|
#define PM_ASTERISK 2
|
||||||
#define PM_ASN_EXPR 3
|
#define PM_ASN_EXPR 3
|
||||||
#define PM_ASN_RANGE 4
|
#define PM_ASN_RANGE 4
|
||||||
|
#define PM_ASN_SET 5
|
||||||
|
|
||||||
struct f_path_mask_item {
|
struct f_path_mask_item {
|
||||||
union {
|
union {
|
||||||
u32 asn; /* PM_ASN */
|
u32 asn; /* PM_ASN */
|
||||||
struct f_line *expr; /* PM_ASN_EXPR */
|
struct f_line *expr; /* PM_ASN_EXPR */
|
||||||
|
struct f_tree *set; /* PM_ASN_SET */
|
||||||
struct { /* PM_ASN_RANGE */
|
struct { /* PM_ASN_RANGE */
|
||||||
u32 from;
|
u32 from;
|
||||||
u32 to;
|
u32 to;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
int kind;
|
int kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue