mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 09:08:20 +00:00
Beginning implementation of &on_change for tables.
This commit is contained in:
parent
f6a1a7053b
commit
bf31587c2c
7 changed files with 92 additions and 2 deletions
65
src/Attr.cc
65
src/Attr.cc
|
@ -482,6 +482,71 @@ void Attributes::CheckAttr(Attr* a)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ATTR_ON_CHANGE:
|
||||||
|
{
|
||||||
|
if ( type->Tag() != TYPE_TABLE )
|
||||||
|
{
|
||||||
|
Error("&on_change only applicable to tables");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Expr *change_func = a->AttrExpr();
|
||||||
|
|
||||||
|
if ( change_func->Type()->Tag() != TYPE_FUNC || change_func->Type()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION )
|
||||||
|
Error("&on_change attribute is not a function");
|
||||||
|
|
||||||
|
const FuncType *c_ft = change_func->Type()->AsFuncType();
|
||||||
|
|
||||||
|
if ( c_ft->YieldType()->Tag() != TYPE_BOOL )
|
||||||
|
{
|
||||||
|
Error("&on_change must yield a value of type bool");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TableType *the_table = type->AsTableType();
|
||||||
|
|
||||||
|
if (the_table->IsUnspecifiedTable())
|
||||||
|
break;
|
||||||
|
|
||||||
|
const type_list* args = c_ft->ArgTypes()->Types();
|
||||||
|
const type_list* t_indexes = the_table->IndexTypes();
|
||||||
|
if ( args->length() != 3 + t_indexes->length() )
|
||||||
|
{
|
||||||
|
Error("&on_change function has incorrect number of arguments");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! same_type((*args)[0], the_table->AsTableType()) )
|
||||||
|
{
|
||||||
|
Error("&on_change: first argument must be of same type as table");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't check exact type here yet - the data structures don't exist yet.
|
||||||
|
if ( (*args)[1]->Tag() != TYPE_ENUM )
|
||||||
|
{
|
||||||
|
Error("&on_change: second argument must be a TableChange enum");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool indexmatch = true;
|
||||||
|
for ( int i = 0; i < t_indexes->length(); i++ )
|
||||||
|
{
|
||||||
|
if ( ! same_type((*args)[2+i], (*t_indexes)[i]) )
|
||||||
|
{
|
||||||
|
Error("&on_change: index types do not match table");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! same_type((*args)[2+t_indexes->length()], the_table->YieldType()) )
|
||||||
|
{
|
||||||
|
Error("&on_change: value type does not match table");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ATTR_TRACKED:
|
case ATTR_TRACKED:
|
||||||
// FIXME: Check here for global ID?
|
// FIXME: Check here for global ID?
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,6 +27,7 @@ typedef enum {
|
||||||
ATTR_ERROR_HANDLER,
|
ATTR_ERROR_HANDLER,
|
||||||
ATTR_TYPE_COLUMN, // for input framework
|
ATTR_TYPE_COLUMN, // for input framework
|
||||||
ATTR_TRACKED, // hidden attribute, tracked by NotifierRegistry
|
ATTR_TRACKED, // hidden attribute, tracked by NotifierRegistry
|
||||||
|
ATTR_ON_CHANGE, // for table change tracking
|
||||||
ATTR_DEPRECATED,
|
ATTR_DEPRECATED,
|
||||||
#define NUM_ATTRS (int(ATTR_DEPRECATED) + 1)
|
#define NUM_ATTRS (int(ATTR_DEPRECATED) + 1)
|
||||||
} attr_tag;
|
} attr_tag;
|
||||||
|
|
14
src/Val.cc
14
src/Val.cc
|
@ -1340,6 +1340,7 @@ TableVal::~TableVal()
|
||||||
Unref(def_val);
|
Unref(def_val);
|
||||||
Unref(expire_func);
|
Unref(expire_func);
|
||||||
Unref(expire_time);
|
Unref(expire_time);
|
||||||
|
Unref(change_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::RemoveAll()
|
void TableVal::RemoveAll()
|
||||||
|
@ -1391,6 +1392,12 @@ void TableVal::SetAttrs(Attributes* a)
|
||||||
expire_func = ef->AttrExpr();
|
expire_func = ef->AttrExpr();
|
||||||
expire_func->Ref();
|
expire_func->Ref();
|
||||||
}
|
}
|
||||||
|
auto cf = attrs->FindAttr(ATTR_ON_CHANGE);
|
||||||
|
if ( cf )
|
||||||
|
{
|
||||||
|
change_func = cf->AttrExpr();
|
||||||
|
change_func->Ref();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::CheckExpireAttr(attr_tag at)
|
void TableVal::CheckExpireAttr(attr_tag at)
|
||||||
|
@ -1926,6 +1933,13 @@ ListVal* TableVal::RecoverIndex(const HashKey* k) const
|
||||||
Val* TableVal::Delete(const Val* index)
|
Val* TableVal::Delete(const Val* index)
|
||||||
{
|
{
|
||||||
HashKey* k = ComputeHash(index);
|
HashKey* k = ComputeHash(index);
|
||||||
|
if ( k && change_func )
|
||||||
|
{
|
||||||
|
auto el = AsTable()->Lookup(k);
|
||||||
|
if ( el )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
TableEntryVal* v = k ? AsNonConstTable()->RemoveEntry(k) : 0;
|
TableEntryVal* v = k ? AsNonConstTable()->RemoveEntry(k) : 0;
|
||||||
Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0;
|
Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0;
|
||||||
|
|
||||||
|
|
|
@ -933,6 +933,7 @@ protected:
|
||||||
IterCookie* expire_cookie;
|
IterCookie* expire_cookie;
|
||||||
PrefixTable* subnets;
|
PrefixTable* subnets;
|
||||||
Val* def_val;
|
Val* def_val;
|
||||||
|
Expr* change_func = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecordVal : public Val, public notifier::Modifiable {
|
class RecordVal : public Val, public notifier::Modifiable {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// Switching parser table type fixes ambiguity problems.
|
// Switching parser table type fixes ambiguity problems.
|
||||||
%define lr.type ielr
|
%define lr.type ielr
|
||||||
|
|
||||||
%expect 105
|
%expect 111
|
||||||
|
|
||||||
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
|
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
|
||||||
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
|
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
%token TOK_ATTR_ADD_FUNC TOK_ATTR_DEFAULT TOK_ATTR_OPTIONAL TOK_ATTR_REDEF
|
%token TOK_ATTR_ADD_FUNC TOK_ATTR_DEFAULT TOK_ATTR_OPTIONAL TOK_ATTR_REDEF
|
||||||
%token TOK_ATTR_DEL_FUNC TOK_ATTR_EXPIRE_FUNC
|
%token TOK_ATTR_DEL_FUNC TOK_ATTR_EXPIRE_FUNC
|
||||||
%token TOK_ATTR_EXPIRE_CREATE TOK_ATTR_EXPIRE_READ TOK_ATTR_EXPIRE_WRITE
|
%token TOK_ATTR_EXPIRE_CREATE TOK_ATTR_EXPIRE_READ TOK_ATTR_EXPIRE_WRITE
|
||||||
%token TOK_ATTR_RAW_OUTPUT
|
%token TOK_ATTR_RAW_OUTPUT TOK_ATTR_ON_CHANGE
|
||||||
%token TOK_ATTR_PRIORITY TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER
|
%token TOK_ATTR_PRIORITY TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER
|
||||||
%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED
|
%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED
|
||||||
|
|
||||||
|
@ -1327,6 +1327,8 @@ attr:
|
||||||
{ $$ = new Attr(ATTR_ADD_FUNC, $3); }
|
{ $$ = new Attr(ATTR_ADD_FUNC, $3); }
|
||||||
| TOK_ATTR_DEL_FUNC '=' expr
|
| TOK_ATTR_DEL_FUNC '=' expr
|
||||||
{ $$ = new Attr(ATTR_DEL_FUNC, $3); }
|
{ $$ = new Attr(ATTR_DEL_FUNC, $3); }
|
||||||
|
| TOK_ATTR_ON_CHANGE '=' expr
|
||||||
|
{ $$ = new Attr(ATTR_ON_CHANGE, $3); }
|
||||||
| TOK_ATTR_EXPIRE_FUNC '=' expr
|
| TOK_ATTR_EXPIRE_FUNC '=' expr
|
||||||
{ $$ = new Attr(ATTR_EXPIRE_FUNC, $3); }
|
{ $$ = new Attr(ATTR_EXPIRE_FUNC, $3); }
|
||||||
| TOK_ATTR_EXPIRE_CREATE '=' expr
|
| TOK_ATTR_EXPIRE_CREATE '=' expr
|
||||||
|
|
|
@ -298,6 +298,7 @@ when return TOK_WHEN;
|
||||||
&read_expire return TOK_ATTR_EXPIRE_READ;
|
&read_expire return TOK_ATTR_EXPIRE_READ;
|
||||||
&redef return TOK_ATTR_REDEF;
|
&redef return TOK_ATTR_REDEF;
|
||||||
&write_expire return TOK_ATTR_EXPIRE_WRITE;
|
&write_expire return TOK_ATTR_EXPIRE_WRITE;
|
||||||
|
&on_change return TOK_ATTR_ON_CHANGE;
|
||||||
|
|
||||||
@deprecated.* {
|
@deprecated.* {
|
||||||
auto num_files = file_stack.length();
|
auto num_files = file_stack.length();
|
||||||
|
|
|
@ -225,6 +225,12 @@ type gtp_qos_profile: record;
|
||||||
type gtp_private_extension: record;
|
type gtp_private_extension: record;
|
||||||
type gtp_gsn_addr: record;
|
type gtp_gsn_addr: record;
|
||||||
|
|
||||||
|
enum TableChange %{
|
||||||
|
TABLE_ELEMENT_NEW,
|
||||||
|
TABLE_ELEMENT_CHANGED,
|
||||||
|
TABLE_ELEMENT_REMOVED,
|
||||||
|
%}
|
||||||
|
|
||||||
module Reporter;
|
module Reporter;
|
||||||
|
|
||||||
enum Level %{
|
enum Level %{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue