Subject: An approach to modeling ForCES events

From: "Joel M. Halpern" <[email-masked]>
Date: Wed, 13 Apr 2005 07:44:08 -0400

Below is a proposal for event modeling, including defining the paths for 
registering and reporting events in the protocol.
Here is a sample XML for event declaration in an LFB Class definition, 
followed by some description and question.
Assume that the LFB include a foo and bar elements.  foo is an array whose 
contents are a structure with fields baz, caz, daz where daz is in turn an 
array of uint32.
oddity is an array indexed by the same idex as the daz entires.

I have not defined any specific semantics for the objects because it would 
take a lot of text.  These are simply examples of things which can change, 
and which teh CE wants to know about.

<events eventBaseID="7" registerBaseID="8">
    <event eventID="1">
       <target> bar </target>
       <change/>
       <synopsis> report if bar changes </synopsis>
       <reports>
          <report> bar </report>
       </reports>
    </event>
    <event eventID="2">
       <target> foo.$1.baz </target>
       <exceed> 75 </exceed>
       <synopsis> report if any baz in foo gets above 75 </synopsis>
       <reports>
          <report> foo.$1.baz </report>
          <report> foo.$1.caz </report>
          <!-- no need to report the index $1, as that will be in the event 
path ID -->
       </reports>
    </event>
    <event eventID="3">
       <target> foo.$1.daz.$2 </target>
       <fallsbelow> 3 </fallsbelow>
       <reports>
          <report> foo.$1.daz.$2 </report>
          <report> foo.$1.caz </report>
          <report> oddity.$2.state </report>
       </reports>
    </event>
    <event eventID="4">
       <target> oddity </target>
       <change/>
       <reports>
          <report-cause/>
          <report> bar </report>
       </reports>
    </event>
</events>

This declares that paths within this LFB that start with 7 reference 
events, and paths that start with 8 are for the boolean variables that 
represent registration state for the events.  Paths starting with 7 will 
appear only in notifications.
Q: I could have used a single path starting point, and simply had different 
meanings for its use in SET / GET (where it would reference the boolean 
variable) and in NOTIFICATIONS (where it would mean the event itself and 
the associated reporting type.  I thought this was a bad idea.

Each even then has an ID which is concatenated with the base paths to start 
building the notification and registration paths.  For event 1 (changes to 
bar) the paths are simply 7.1 for the notification and 8.1 for registering.
Events 2 and 3 are events about array elements inside the LFB.  Thus the 
path to a specific event is the base, the eventid, and the subscript.  So a 
specific occurrence (say in the fourth daz entry in the second foo entry) 
of event 3 would be reported with the path 7.3.2.4.
Q: We have been asked to support registering for events on a whole 
table.  Currently, set 8.3.2 would be setting teh table of boolean 
variables.  However, it is not legal to directly create or delete entries 
in this table (Since it mirrors the foo[]daz table structure.)  So we could 
declare that a reference to the entire array is in this case a reference to 
a single boolean that covers the array.  It seems useful to have that.  But 
allowing that will seriously complicate the type determination logic.

Each event includes a target variable (with subscripts if the target is in 
an array.)  The subscripts are named so they can be referenced in the 
reports clause.  The subscripts themselves will appear in the event 
notification.
Each event then includes a condition.  I have not tried to enumerate all 
the conditions yet, but some of them are shown above.
Q: Should we directly put the different condition tags, as I have done 
above, or should we use:
    <condition>
      <cond-kind-tag/>
      <!-- optional -->
      <condition-value> value </condition-value>
    </condition>

The target variable can be an array, rather than its entries.  In that 
case, the change trigger would mean the deletion or creation of any 
entry.  (We will probably have separate deletion and creation triggers as 
well.)  In that case, the event path will include the subscript of the 
entry being created or deleted.  the <report-cause> in the reports will 
cause a scalar to be included indicating what event has occurred.  (This is 
legal with any report, but is likely most useful with arrays.)

The reports element indicates what information to send along with the 
notification.  It can select any elements from the LFB Class.  It can use 
any of the subscripts in the trigger path.  Essentially, it defines the 
data type and contents for the data portion of the notification TLV.

One additional question that occurred to me later is, if a change is made 
by the CE, and the CE is registered for an event triggered by the 
change,  should the notification be generated?  Should we have a flag in 
the SET request to suppress such notifications?  My first reaction is that 
it should be generated even for changes by the CE, but I am not sure.

Is this sufficiently ugly to prompt someone to do a better job?

Thank you,
Joel

---

From: Jamal Hadi Salim <[email-masked]>
Date: Wed, 13 Apr 2005 10:13:15 -0400

Joel,

Good - lets have some activity on the list; hopefully this discussion
doesnt turn out into you and I batting a ball at each other(trying to
guilt other people ;-> We can make good progress if people understand
whats being said now as opposed to spending many hours later rehashing
the same things again)

I have a small variation to your approach further below. It wouldnt be
fun otherwise ;->

On Wed, 2005-04-13 at 07:44, Joel M. Halpern wrote:
> Assume that the LFB include a foo and bar elements. foo is an array 
> whose contents are a structure with fields baz, caz, daz where daz 
> is in turn an array of uint32.

Does oddity make sense the way you described it? If i read correctly, 
there will be many daz "tables" but only one oddity.

> and which teh CE wants to know about.

Didnt quiet follow:
Are you talking about registration? Or how things will be laid out in
the LFB text? 

>        <synopsis> report if bar changes </synopsis>

I am assuming the target is going to be a path syntax i.e you just have
it above for illustratation purposes.

>        <target> oddity </target>

I think you have all the needed constructs above. Good stuff.

The triggers that cause events as you have them right now may not be
universal; example fallsbelow or exceeds makes sense only if you have
counters. I think this can be revisted later, but let me just digress a
little:
I may also be interested in getting a synchronous event ("send me 
bar every 30 seconds") or even more interesting async ones perhaps
driven by some packet arrival  like "notify me about bar when you
receive ICMPs from Joel". I am not sure the second one fits well, but
certainly the first one does. 
Also additional semantics like "let me know if it changes X times" which
could be viewed as a superset of </change> where X=1

> the associated reporting type.  I thought this was a bad idea.

I think your approach of the subscription being a different scope than
notification is better.
Related:
The event subscribe/unsubscribe are essentially SETs. GET "all events"
or "all event to do with foo" doesnt exist at the moment.

> bar) the paths are simply 7.1 for the notification and 8.1 for registering.

Makes sense.

> of event 3 would be reported with the path 7.3.2.4

Q. How does an FE LFB say "I can support foo.$1.daz.$2" as a event
target?
If you decide to describe it in english in some text - does that limit
things? Or do we let the CE register and have the FE reject when it cant
do it.

Heres where i think i should mention the variation i have over what you
present, the other way to do this is to say:

If i subscribe to event path 8.X <target>foo</target> it would mean I am
interested in anything that happens in foo. 
If i subscribe to target foo.$1.baz then i am interested in column baz
of table foo.
If i subscribe to target bar then i am only interested in that scalar.

In other words theres a hierachical connotation to event targets. i.e
if i say target "foo" then that implies "foo.$1.baz" and
"foo.$1.caz" and "foo.$1.daz.$2"
The only issue with above is conflict resolution which is resolvable.

The <report> construct still is the one that defines the verbosity of
what gets reported back.
In other words, even on the <report> you could have different syntatic
sugar; verbosity levels are:
3)  "tell me what exactly changed".
The notify will have to give you the path and new target values.
2) "tell me the path of what changed" as well under event id 30.
1) "dont bother telling me what exactly changed - all i need to know is
event 3 happened"

> variables. 

Refer to my comments above.

> However, it is not legal to directly create or delete entries 

Seems like it will be ok to subscribe/unsubscribe though. In other words
if i subscribe for event 3 - that is something that will exist in the
FEs LFB state information i.e i can query it; if i unsubscribe then i
cant query for that event.

> the conditions yet, but some of them are shown above.

The conditions are essentially triggers for the events - I think we can
probably say there exist only a handful of those.

> Is this sufficiently ugly to prompt someone to do a better job?

Look at my comments on more genericity of subscription;
I think the constructs needed are all there in what you define.

Hopefully the other folks in the protocol and model would chip in as
well in this discussion.

cheers,
jamal

---

From: "Joel M. Halpern" <[email-masked]>
Date: Wed, 13 Apr 2005 10:28:55 -0400

I considered an approach like the one you suggest below.  It may be the 
right answer.  I have some concerns, lfollowing the coied portion of your 
comment.

>1) "dont bother telling me what exactly changed - all i need to know is

Given a table with fields a, b, and c, it does not seem obvious to me that 
being interested in all changes to fields anywhere in the table implies any 
likelihood of the CE being interested in notification of changes to b or c.
As a simple example, the "a" field might be status, which the CE needs to 
know about changes to, while the "b" and "c" fields are statistical (change 
all the time, but the CE will get the fields when he needs the value.)
Also, it does not seem that being interested in creation and deletion of 
entries in the table means that the CE is interested in notifications of 
changes to field values of existing elements. (Again, the existence entries 
may reflect interfaces or signaling events, while the contents may be 
statistical.)

Yours,
Joel

---

From: "Joel M. Halpern" <[email-masked]>
Date: Wed, 13 Apr 2005 10:36:07 -0400

A couple of comments in line.
Yours,
Joel

>there will be many daz "tables" but only one oddity.

This construction of interacting tables is not common, but it can 
occur.  The oddity table might be a table of DSCPs.  The foo table might be 
a microflow (4-tuple) table which can include traffic with differing 
DSCPs.  One can imagine other cases.  I included this mainly to show that 
the indexing is not confined to the table where the event is detected.

>Are you talking about registration? Or how things will be laid out in

I hope we can craft a better example for the model document, so that folks 
will know how to write event sections for their LFB class definitions.

>it above for illustratation purposes.

My current thinking is that the LFB class definition event declaration can 
use field names (like bar) and field name sequences 
(p-struct.p-field-struct.q-field) with array subscript indications (the 
dollar sign variables) rather than using the numeric values of the path. 
(The first field by definition must be a top level element of the LFB 
inside which this event declaration appears.)  After all, this path appears 
in the class definition.  Humans will find the field names easier to deal 
with than the numbers.  And the XML parser can figure out what field is 
being referred to using either syntax.  This applies to both the 
declaration of the field that is triggering the event, and the declarations 
of fields to be reported in the event notification.

Thanks,
Joel

---

From: Jamal Hadi Salim <[email-masked]>
Date: Wed, 13 Apr 2005 11:15:56 -0400

> likelihood of the CE being interested in notification of changes to b or c.

Agreed. 
It may make sense to have ability to have multiple targets specified
such as specifying interest only in changes to a and c:
<target> foo.$1.a</target>
<target> foo.$1.c</target>
<change/>
maybe a & or || relationship to the two as well (dont wanna complicate
this)

> all the time, but the CE will get the fields when he needs the value.)
 
I think the granularity is what matters. As an example, I would be
interested in a stateful classifier table whenever it adds a new entry
to its tracking table or it deletes an existing entry for whatever
reason to be the trigger for notification.
But it still does make sense for me to be interested in the statistics
of a specific entry when the received packets exceed a threshold for
example.
This is a conflict resolution problem. Three solutions:

1) You could say in simple terms that the more fine grained event
subscribed to is should be used as a trigger in case of conflict. i.e if
i subsribe to changes in table foo
and foo.$1.a then foo.$1.a is used in case its the one that changes.

2) You could also be explicit from CE and give the events priorities so
the FE knows which one to use a s a trigger in case of conflicts. 

3) Or you could say just send "event ID 10: something happened to table
foo" in addition to "event ID 500: receive packet count stats on foo.1
exceeded 75"

> may reflect interfaces or signaling events, while the contents may be 

The delienation of <report> from <target> seems to solve this already,
no?

BTW, I am looking at the construct you have (we should discuss the wire
format at some point) - and i think you have all the verbosity levels:
You could send to the CE the event without the <report>. You could also
send the event with <report> which contains the new values etc.

Again, I dont want to complicate things on this first stage.
The end goal should be to reduce the amount of info to be sent on the
wire (read: info to be processed by CE) if possible and
being very specific on what nodes change. The later part we achieve
already from what you posted.
I think the only difference you and i have at the moment is the hierachy
implications and conflict resolution is something that needs to be
resolved regardless.

cheers,
jamal

---

From: Jamal Hadi Salim <[email-masked]>
Date: Wed, 13 Apr 2005 11:25:58 -0400

> of fields to be reported in the event notification.

Ok, makes sense. At some point we should correlate with a wire format
(thats the angle i was coming from).

cheers,
jamal

---

From: "Joel M. Halpern" <[email-masked]>
Date: Wed, 13 Apr 2005 12:13:03 -0400

The on-the-wire format to report an event is, I think, quite simple.

OP-TLV, code = notification
    path-data-tlv
           path = flags, length = 2, path = notification base | event id
           data = encoded format of fields defined in the reports clause of 
the event

Thus, the actual paths to the trigger and the report fields do not even 
need to appear in the notification, since they are implied by the 
notification ID.

Yours,
Joel

---

From: "Joel M. Halpern" <[email-masked]>
Date: Wed, 13 Apr 2005 12:33:54 -0400

One case I forgot to mention.

At 12:13 PM 4/13/2005, Joel M. Halpern wrote:
>           data = encoded format of fields defined in the reports clause 
> of the event

If the event is triggered by an entry in a table, then the path is longer, 
with the relevant subscripts added to the path.  So if foo.2.bar.3 
triggered event ID 6, with event base ID of 11, then the path would be
     length = 4, IDs = 11, 6, 2, 3