Subject: [Diffserv] Re: MIB draft [Kwok's Rvw Result #2]

From: Fred Baker <[email-masked]>
Date: Fri, 20 Jul 2001 11:15:12 -0700

At 04:24 AM 7/12/2001, Kwok-Ho Chan wrote:
>As for the diffServClfrTable/Entry issue: Based on no agreement with 
>Removal of diffServClfrTable/Entry, I think we should add 
>diffServClfrTable/Entry back into the MIB (this was not one of the agreed 
>changes when we were at Minniapolis) and create an open issue for removing it.

A few observations...

Let's presume that ClfrNextFree counts and ClfrElementNextFree counts. Now 
I go to create three classifiers, each of which gets one element put into 
it, and then one of which gets two more. Consider the behavior:

Assume that clfrNextFree and clfrElementNextFree each initially have the 
value 1.

1) read clfrnextfree (1) and clfrelementnextfree (1)
2) create clfrEntry[1] by writing createAndGo to ClfrStatus[1]
3) create clfrSixTypleEntry[1][1] by writing <something> and
          createAndGo to ClfrSixTupleStatus[1][1]
4) create clfrElementEntry[1][1] by writing
          ^ClfrSixTupleEntry[1][1] to ClfrElementSpecific[1][1]
          and createAndGo to ClfrElementStatus[1][1]

This took four round trips.

New we create the second and third entries:

5) read clfrnextfree (2) and clfrelementnextfree (2)
6) create clfrEntry[1] by writing createAndGo to ClfrStatus[2]
7) create clfrSixTypleEntry[2][2] by writing <something> and
          createAndGo to ClfrSixTupleStatus[2][2]
8) create clfrElementEntry[2][2] by writing
          ^ClfrSixTupleEntry[2][2] to ClfrElementSpecific[2][2]
          and createAndGo to ClfrElementStatus[2][2]
9) read clfrnextfree (3) and clfrelementnextfree (3)
10) create clfrEntry[3] by writing createAndGo to ClfrStatus[3]
11) create clfrSixTypleEntry[1][1] by writing <something> and
          createAndGo to ClfrSixTupleStatus[3][3]
12) create clfrElementEntry[3][3] by writing
          ^ClfrSixTupleEntry[3][3] to ClfrElementSpecific[3][3]
          and createAndGo to ClfrElementStatus[3][3]

We now have:
         ClfrEntry[1], ClfrSixTupleEntry[1][1], ClfrElementEntry[1][1]
         ClfrEntry[2], ClfrSixTupleEntry[2][2], ClfrElementEntry[2][2]
         ClfrEntry[3], ClfrSixTupleEntry[3][3], ClfrElementEntry[3][3]
Each Classifier took four round trips to build

New we create the second and third elements of the first classifier:

5) read clfrelementnextfree (4)
6) create clfrSixTypleEntry[1][4] by writing <something> and
          createAndGo to ClfrSixTupleStatus[1][4]
7) create clfrElementEntry[1][4] by writing
           ^ClfrElementENtry[1][4] to ClfrElementNext[1][1]
          ^ClfrSixTupleEntry[1][4] to ClfrElementSpecific[1][4]
          and createAndGo to ClfrElementStatus[1][4]
8) link to ClfrEntry[1] by writing
           ^ClfrElementENtry[1][4] to ClfrElementNext[1][1]
9) read clfrelementnextfree (5)
10) create clfrSixTypleEntry[1][5] by writing <something> and
          createAndGo to ClfrSixTupleStatus[1][5]
11) create clfrElementEntry[1][5] by writing
          ^ClfrSixTupleEntry[1][5] to ClfrElementSpecific[1][5]
          and createAndGo to ClfrElementStatus[1][5]
12) link to ClfrEntry[1] by writing
           ^ClfrElementENtry[1][5] to ClfrElementNext[1][4]

We now have:
         ClfrEntry[1], ClfrSixTupleEntry[1][1], ClfrElementEntry[1][1]
                       ClfrSixTupleEntry[1][4], ClfrElementEntry[1][4]
                       ClfrSixTupleEntry[1][5], ClfrElementEntry[1][5]
         ClfrEntry[2], ClfrSixTupleEntry[2][2], ClfrElementEntry[2][2]
         ClfrEntry[3], ClfrSixTupleEntry[3][3], ClfrElementEntry[3][3]
Each new Classifier element took four round trips to build

Notice, first, that the second index of the classifier element was 
completely sufficient to make these unambiguous. Notice that apart from the 
DataPath Table (which I neglected to mention) we have no record of the 
start of any classifier.

Now, let two NMS's simultaneously try to create a new classifier, and have 
to collide and recover. Call them A and B.

1) A and B each read clfrnextfree (4) and clfrelementnextfree (6)
2) A and B create clfrEntry[4] by writing createAndGo to ClfrStatus[4]
           A gets an acknowledgement
           B gets a failure
3a) A creates clfrSixTypleEntry[4][6] by writing <something> and
          createAndGo to ClfrSixTupleStatus[4][6]
4a) A creates clfrElementEntry[4][6] by writing
          ^ClfrSixTupleEntry[4][6] to ClfrElementSpecific[4][6]
          and createAndGo to ClfrElementStatus[4][6]

meanwhile,

3b) B reads clfrnextfree (5) and clfrelementnextfree (6)
4b) B creates clfrEntry[5] by writing createAndGo to ClfrStatus[5]
5b) B creates clfrSixTypleEntry[5][6] by writing <something> and
          createAndGo to ClfrSixTupleStatus[5][6]
7b) B creates clfrSixTypleEntry[5][6] by writing <something> and
          createAndGo to ClfrSixTupleStatus[5][6]
8b) A creates clfrElementEntry[5][6] by writing
          ^ClfrSixTupleEntry[5][6] to ClfrElementSpecific[5][6]
          and createAndGo to ClfrElementStatus[5][6]

In this case, the classifier Id disambiguates two instances of 
classifierElementId=6.

Now, let's redo that sequence assuming that the classifier table doesn't 
exist, and only the classifier element table exists. Again, two NMS's (A 
and B) simultaneously try to create a new classifier, and have to collide 
and recover.

1) A and B each read clfrnextfree (4) and clfrelementnextfree (6)
2) A and B each attempt to create clfrSixTupleEntry[4][6] by
           writing <something>, and createAndGo to ClfrSixTupleStatus[4][6]
         A gets an acknowledge
         B gets a failure
3a) A creates clfrElementEntry[4][6] by writing
          ^ClfrSixTupleEntry[4][6] to ClfrElementSpecific[4][6]
          and createAndGo to ClfrElementStatus[4][6]
3b) B reads clfrnextfree (5) and clfrelementnextfree (7)
4b) B creates clfrSixTypleEntry[5][7] by writing <something>,
         and createAndGo to ClfrSixTupleStatus[5][7]
5b) B creates clfrElementEntry[5][7] by writing
          ^ClfrSixTupleEntry[5][7] to ClfrElementSpecific[5][7]
          and createAndGo to ClfrElementStatus[5][7]

There are several differences between the two cases:

a) with the classifier table, it is possible to have an error condition in 
which a classifier exists but contains no elements; if the classifier table 
does not exist, this is not possible
b) with the classifier table, the recovering system took eight round trips 
to create a classifier; without it, the recovering system took only five.
c) with the classifier table, any classifier creation takes four round 
trips, but without it such a thing only takes three.
d) with the classifier table, in the special case that two NMS's try to 
configure the device simultaneously, the classifier Id disambiguates the 
classifier element Id. However, without the classifier table, the ambiguity 
doesn't exist and so does not need to be disambiguated.

I now go on to mention the other things that bother me.

In draft 9, the only readable attribute in the classifier table is the 
RowStatus variable; the classifier entry can be used to create or delate a 
classifier, and if you read the RowStatus variables I suppose that you can 
determine what classifiers exist. Each of these things can be done using 
the classifier element table. Therefore, the complexity I have described 
the classifier table as creating comes with no redeeming value in terms of 
something that cannot be done by another part of the MIB.

I noted earlier that clfrElementId is sufficient to disambiguate 
classifiers; the classifier number itself contributed nothing to making the 
structure unambiguous. If we keep the classifier ID at all, that argues 
that it should be an attribute of the classifier element ("I am a member of 
this classifier") rather than an integer extending the name (an index of) 
of the classifier element. I'm easily argued into keeping it as an 
attribute; I'm far less sure of it as a reasonable index.

If instead of creating
         ClfrEntry[1], ClfrSixTupleEntry[1][1], ClfrElementEntry[1][1]
                       ClfrSixTupleEntry[1][4], ClfrElementEntry[1][4]
                       ClfrSixTupleEntry[1][5], ClfrElementEntry[1][5]
         ClfrEntry[2], ClfrSixTupleEntry[2][2], ClfrElementEntry[2][2]
         ClfrEntry[3], ClfrSixTupleEntry[3][3], ClfrElementEntry[3][3]

we wanted to create
         ClfrEntry[1], ClfrSixTupleEntry[1][1], ClfrElementEntry[1][1]
                       ClfrSixTupleEntry[1][2], ClfrElementEntry[1][2]
                       ClfrSixTupleEntry[1][3], ClfrElementEntry[1][3]
         ClfrEntry[2], ClfrSixTupleEntry[2][1], ClfrElementEntry[2][1]
         ClfrEntry[3], ClfrSixTupleEntry[3][1], ClfrElementEntry[3][1]

then we need to have a clfrElementNextFree instance per classifier; this 
would require that clfrElementNextFree become an attribute of the 
classifier (an object in the clfrEntry). It would also mean that we cannot 
read clfrNextFree and clfrElementNextFree in the same read; we would either 
read clfrNextFree and then read clfrElementNextFree[clfrNextFree] (an extra 
round trip) or read clfrNextFree and assume that 
clfrElementNextFree[clfrNextFree] could be assumed to be one.

Leaving that by the side, I observed that we have the DataPathStartTable to 
tell us where a given data path starts, but we don't have a corresponding 
attribute that tells us what the first element in any given classifier is. 
This can be deduced, so it is not a showstopper, but deducing it requires 
some effort. One could argue that there should exist a ClfrDataPathStart 
object to indicate this head-of-list.

What I have done is left the classifier table in, which I think adds a huge 
amount of gratuitous complexity. My conscience will not let me visit this 
on the world without any redeeming social value, so I have added a 
clfrDataPathStart attribute. Whether that actually justifies the gratuitous 
complexity or not is a judgement call that I'm not prepared to make.

_______________________________________________
diffserv mailing list
[email-masked]
http://www1.ietf.org/mailman/listinfo/diffserv
Archive: http://www2.ietf.org/mail-archive/working-groups/diffserv/current/maillist.html