Commit 2a40efa5 authored by Pavel Machek's avatar Pavel Machek
Browse files

as_path_match moved to a-path.c

parent 684c6f5a
......@@ -61,7 +61,7 @@ int
val_simple_in_range(struct f_val v1, struct f_val v2)
{
if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK))
return path_match(v1.val.ad->data, v1.val.ad->length, v2.val.path_mask);
return as_path_match(v1.val.ad, v2.val.path_mask);
if ((v1.type == T_IP) && (v2.type == T_PREFIX))
return !(ipa_compare(ipa_and(v2.val.px.ip, ipa_mkmask(v2.val.px.len)), ipa_and(v1.val.px.ip, ipa_mkmask(v2.val.px.len))));
......@@ -620,72 +620,6 @@ filter_same(struct filter *new, struct filter *old)
* FIXME: It should take struct adata *, not u8 * + length; but that makes it a little more difficult to test.
* Or maybe both versions are usefull?
*/
#define MASK_PLUS do { mask = mask->next; if (!mask) return next == q; \
asterix = (mask->val == PM_ANY); \
if (asterix) { mask = mask->next; if (!mask) { return 1; } } \
} while(0)
int
path_match(u8 *p, int len, struct f_path_mask *mask)
{
int i;
int asterix = 0;
u8 *q = p+len;
u8 *next;
asterix = (mask->val == PM_ANY);
if (asterix) { mask = mask->next; if (!mask) { return 1; } }
while (p<q) {
switch (*p++) {
case 1: /* This is a set */
len = *p++;
{
u8 *p_save = p;
next = p_save + 2*len;
retry:
p = p_save;
for (i=0; i<len; i++) {
if (asterix && (get_u16(p) == mask->val)) {
MASK_PLUS;
goto retry;
}
if (!asterix && (get_u16(p) == mask->val)) {
p = next;
MASK_PLUS;
goto okay;
}
p+=2;
}
if (!asterix)
return 0;
okay:
}
break;
case 2: /* This is a sequence */
len = *p++;
for (i=0; i<len; i++) {
next = p+2;
if (asterix && (get_u16(p) == mask->val))
MASK_PLUS;
else if (!asterix) {
if (get_u16(p) != mask->val)
return 0;
MASK_PLUS;
}
p+=2;
}
break;
default:
bug("This should not be in path");
}
}
return 0;
}
struct adata *
comlist_add(struct linpool *pool, struct adata *list, u32 val)
{
......
......@@ -99,3 +99,70 @@ as_path_getlen(struct adata *path)
}
return res;
}
#define MASK_PLUS do { mask = mask->next; if (!mask) return next == q; \
asterix = (mask->val == PM_ANY); \
if (asterix) { mask = mask->next; if (!mask) { return 1; } } \
} while(0)
int
as_path_match(struct adata *path, struct f_path_mask *mask)
{
int i;
int asterix = 0;
u8 *p = path->data;
u8 *q = p+path->length;
int len;
u8 *next;
asterix = (mask->val == PM_ANY);
if (asterix) { mask = mask->next; if (!mask) { return 1; } }
while (p<q) {
switch (*p++) {
case 1: /* This is a set */
len = *p++;
{
u8 *p_save = p;
next = p_save + 2*len;
retry:
p = p_save;
for (i=0; i<len; i++) {
if (asterix && (get_u16(p) == mask->val)) {
MASK_PLUS;
goto retry;
}
if (!asterix && (get_u16(p) == mask->val)) {
p = next;
MASK_PLUS;
goto okay;
}
p+=2;
}
if (!asterix)
return 0;
okay:
}
break;
case 2: /* This is a sequence */
len = *p++;
for (i=0; i<len; i++) {
next = p+2;
if (asterix && (get_u16(p) == mask->val))
MASK_PLUS;
else if (!asterix) {
if (get_u16(p) != mask->val)
return 0;
MASK_PLUS;
}
p+=2;
}
break;
default:
bug("This should not be in path");
}
}
return 0;
}
......@@ -18,6 +18,14 @@ struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, int as);
void as_path_format(struct adata *path, byte *buf, unsigned int size);
int as_path_getlen(struct adata *path);
struct f_path_mask {
struct f_path_mask *next;
int val;
};
#define PM_ANY -1
int as_path_match(struct adata *path, struct f_path_mask *mask);
/* a-set.c */
void int_set_format(struct adata *set, byte *buf, unsigned int size);
......
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