On Tue, Apr 22, 2014 at 6:59 AM, Jamal Hadi Salim <[email protected]
<mailto:[email protected]>> wrote:
Sorry Andy - trying to catchup with the threads (and busy elsewhere at
the moment)
so fast forwarding to this email. I will try to come back later and
answer each
of your questions probably in a separate email
To provide an example to what Joel said:
You can augment/extend in two ways.
a) Take an existing LFB - keep the name change the class version.
Take an existing data structure within that class and extend it.
Example (straight out of our regression tests, simplified for clarity):
I will try to relate this back to the RFC.
The real syntax is XML and does not look anything like your examples.
(If XML was that readable, perhaps you would use the real syntax).
I do not understand the conformance model. Does the server claim
conformance to a set of { class, version } tuples? How does the
client know what versions to expect?
ForCES is not really extensible if multiple vendors are defining data
because
there is 1 giant flat namespace so all data naming has to globally
coordinated, or naming collisions can occur:
mod1:
container foo { }
mod2:
augment /mod1:foo {
leaf X { type string }
}
mod3:
augment /mod1:foo {
leaf X { type string }
}
This is not an error in YANG.
It can't be because mod2 and mod3 are from 2 different vendors
and they both want to augment the standard module (mod1).
Clients that use /mod1:foo/mod2:X do not collide with clients
that are using /mod1:foo/mod3:X.
Without namespaces, even vendor modules would need to go
through a central naming authority like IANA.
Andy
struct foobartype {
id 1, foo, uint32;
id 2, bar, uint32;
}
class MyUpgrade id 667
{
version 1.0
components {
id 1, cbogtabl, array of foobartype;
}
events {
id 1, CBogChanged ... reports cbogtable changes with row
}
}
And later you decide you want to add some new field to foobartype.
struct foobartype {
id 1, foo, uint32;
id 2, bar, uint32;
id 3, goo, uint32;
}
class MyUpgrade id 667
{
version 1.1
components {
id 1, cbogtable, array of foobartype;
}
events {
id 1, CBogChanged ... reports table changes with new foobartype
}
}
In field upgrades, typically i see that the control piece is first
upgraded.
The data path follows next incrementally on different nodes.
The datapath ignores and logs what it doesnt understand. i.e in such
a case,
an app sends cbogtable row with goo to version 1 datapath.
On inheritance, here's an example of what a linux port would look like:
struct portinfo {
id 1, name, string[16]
id 2, ifindex, uint32
..
..
id 23, ethinfo, struct ethparams
}
class Port, id 6113
{
version 1.0
components {
id 1, ports, array of portinfo;
}
events {
... link, port creation etc ..
}
capabilities {
.........
}
}
So if i wanted to define a tunnel device, then i take that
portinfo struct and derive from it then i create a new class.
As an example for tuntap port on Linux:
struct tunport {
<derivedFrom>PortInfo</derivedFrom>
id 24,tunflags, uint32, optional
id 25, userid, uint32, optional
id 26, groupid, uint32, optiona
}
class tuntap, id 6119
{
version 1.0
<derivedFrom>Port</derivedFrom>
components {
id 1, ports, array of tunport;
}
events {
... link, port creation etc ..
}
capabilities {
.........
}
}
The XML is reduced greatly.
Not sure if i answered the specific question
I will respond to your other questions later..
cheers,
jamal
On Mon, Apr 21, 2014 at 11:48 PM, Joel M. Halpern
<[email protected] <mailto:[email protected]>> wrote:
> As a minor point, I consider the embedding of file management and
business
> logic into the core of NetConf was probably a mistake.
> ForCES does have version numbers on classes, so if you change an
LFB class
> definition, you increase the revision.
> It also has inheritance, which provides an effective way to define a
> coherent extension of a class.
> And it explicitly includes indications of which items are
required. As well
> as providing mechanisms for a controller to determine on a fine
grained
> basis what an FE actually supports. So we do not have to guess
what the
> right groupings are for unknown users down the road.
>
> Yours,
> Joel
>
> On 4/21/14, 6:21 PM, Andy Bierman wrote:
>>
>> Hi,
>>
>> Forgot life-cycle issues....
>> There does not appear to be any notion of a module revision in
ForCES.
>> There does not seem to be any way to identify a particular
definition
>> as either current, deprecated, or obsolete.
>>
>> Is a library used with the <load> element ever allowed to change?
>> If so, how are new revisions identified?
>>
>> Is there any text explaining how these modules are allowed to change
>> over time?
>> Was this considered by the WG?
>>
>> Andy
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> On Mon, Apr 21, 2014 at 2:44 PM, Andy Bierman
<[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>>
>> Hi,
>>
>>
>> On Mon, Apr 21, 2014 at 8:10 AM, Jamal Hadi Salim
<[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>>
>> On Mon, Apr 21, 2014 at 10:54 AM, Andy Bierman
>> <[email protected] <mailto:[email protected]>
<mailto:[email protected] <mailto:[email protected]>>> wrote:
>> >
>> > I think Jan and others have explained why they think
they can
>> leverage
>> > the NC/RC/YANG technology to implement I2RS. There
are tool
>> > and data model management requirements in addition to the
>> protocol
>> > in order to have a workable solution.
>> >
>> > Unless the RIB data is one monolithic blob
implemented without
>> > variation on every router, then issues such as
modularity,
>> conformance
>> > model, data lifecycle, distributed naming authority, data
>> augmentation,
>> > and language extensibility are going to matter.
>> >
>>
>> So lets put all that in a requirement list somewhere and
work
>> around a gap
>> analysis.
>>
>>
>> So how does ForCES support these things?
>> Where is the language specification in RFC 5812?
>> Section 4 describes LFB classes, which appear to represent
the only
>> supported data
>> for the protocol. Is the entire normative language specification
>> contained in the XSD in sec. 4.9?
>>
>> What happens if multiple <load> elements pull in definitions
with the
>> same local name? The examples do not show any use of prefixes
>> and the <load> element has no prefix mapping.
>>
>> <load library="a_library"/>
>> <load library="another_library" location="another_lib.xml"/>
>> <load library="yetanother_library"
>>
location="http://www.example.com/forces/1.0/lfbmodel/lpm.xml"/>
>>
>>
>> There does not appear to be any conformance information like
what is
>> mandatory or conditional on a user-defined feature. How are
logical
>> groups
>> of conditional objects defined and advertised in the protocol?
>> (e.g., YANG features)
>>
>> Are there examples of the augmentation described in sec. 4.5.7?
>> There does not appear to be any way for 1 module to add
elements to
>> another
>> <dataTypeDef> without controlling the naming for all modules.
>>
>> How does a vendor implement the unique naming requirements
in ForCES
>> without controlling the names of all possible ForCES files? Are
>> they supposed to
>> rewrite modules when a naming collision occurs because
modules X and
>> Y are being loaded
>> into module Z, which causes a new naming collision that did not
>> occur before?
>>
>> YANG supports groupings that can be refined in each
use/expansion.
>> How are complex <dataTypeDef> statements reused and refined?
>> Where are examples of that in the RFC?
>>
>>
>>
>> How would I2RS use <frameDefs>?
>>
>> <frameDefs>
>> <frameDef>
>> <name>ipv4</name>
>> <synopsis>IPv4 packet</synopsis>
>> <description>
>> This frame type refers to an IPv4 packet.
>> </description>
>> </frameDef>
>> <frameDef>
>> <name>ipv6</name>
>> <synopsis>IPv6 packet</synopsis>
>> <description>
>> This frame type refers to an IPv6 packet.
>> </description>
>> </frameDef>
>> ...
>> </frameDefs>
>>
>>
>> Is this like a YANG identity statement, except this causes
naming
>> collisions,
>> so it is more like a specialized distributed enumeration type?
>>
>>
>> To compare readability, here are the same type definitions
in ForCES
>> and YANG:
>>
>> ForCES: (RFC 5812, pg. 80)
>>
>> <dataTypeDef>
>> <name>accessPermissionValues</name>
>> <synopsis>
>> The possible values of component access
>> permission
>> </synopsis>
>> <atomic>
>> <baseType>uchar</baseType>
>> <specialValues>
>> <specialValue value="0">
>> <name>None</name>
>> <synopsis>Access is
prohibited</synopsis>
>> </specialValue>
>> <specialValue value="1">
>> <name> Read-Only </name>
>> <synopsis>
>> Access to the component is read only
>> </synopsis>
>> </specialValue>
>> <specialValue value="2">
>> <name>Write-Only</name>
>> <synopsis>
>> The component MAY be written, but
not read
>> </synopsis>
>> </specialValue>
>> <specialValue value="3">
>> <name>Read-Write</name>
>> <synopsis>
>> The component MAY be read or written
>> </synopsis>
>> </specialValue>
>> </specialValues>
>> </atomic>
>> </dataTypeDef>
>>
>>
>> YANG:
>>
>>
>> typedef accessPermissionValues {
>>
>> description
>>
>> "The possible values of component access permission";
>>
>> type enumeration {
>>
>> enum None {
>>
>> value 0;
>>
>> description "Access is prohibited";
>>
>> }
>>
>> enum Read-Only {
>>
>> value 1;
>>
>>
>> description "Access to the component is
read only";
>>
>>
>> }
>>
>> enum Write-Only {
>>
>>
>> value 2;
>>
>> description "The component MAY be written,
but not
>> read";
>>
>>
>> }
>>
>> enum Read-Write {
>>
>> value 3;
>>
>>
>> description "The component MAY be read or
written";
>>
>>
>> }
>>
>> }
>>
>>
>>
>> }
>>
>>
>>
>>
>>
>>
>> How are new protocol operations defined? Are they part of the
>> language.
>>
>>
>> How are language extensions done? This does not appear to be
>> supported.
>>
>> How are existence constraints between objects expressed? (e.g.,
>> must/when/unique)
>>
>> How does a vendor add arbitrary data to notification events?
>> Can event definitions be augmented?
>> If so, how is this done so nodes can be conditional? (e.g.,
>> if-feature, when)
>>
>> The <eventCondition> element is one of many that seems very
ForCES
>> specific.
>> How are new events added?
>>
>> I don't see an event definition for the "Goof1changed" example:
>>
>>
>> </xsd:complexType>
>> <!-- the substitution group for the event conditions -->
>> <xsd:element name="eventCondition" abstract="true"/>
>> <xsd:element name="eventCreated"
>> substitutionGroup="eventCondition"/>
>> <xsd:element name="eventDeleted"
>> substitutionGroup="eventCondition"/>
>> <xsd:element name="eventChanged"
>> substitutionGroup="eventCondition"/>
>> <xsd:element name="eventGreaterThan"
>> substitutionGroup="eventCondition"/>
>> <xsd:element name="eventLessThan"
>> substitutionGroup="eventCondition"/>
>> <xsd:complexType name="eventPathType">
>> <xsd:sequence>
>> <xsd:element ref="eventPathPart"
maxOccurs="unbounded"/>
>> </xsd:sequence>
>> </xsd:complexType>
>> <!-- the substitution group for the event path parts -->
>> <xsd:element name="eventPathPart" type="xsd:string"
>> abstract="true"/>
>> <xsd:element name="eventField" type="xsd:string"
>> substitutionGroup="eventPathPart"/>
>> <xsd:element name="eventSubscript" type="xsd:string"
>> substitutionGroup="eventPathPart"/>
>> <xsd:complexType name="eventReportsType">
>> <xsd:sequence>
>> <xsd:element name="eventReport" type="eventPathType"
>> maxOccurs="unbounded"/>
>> </xsd:sequence>
>> </xsd:complexType>
>>
>>
>> <event eventID="8">
>> <name>Goof1changed</name>
>> <synopsis>
>> An example event for a complex structure
>> </synopsis>
>> <eventTarget>
>> <!-- target is goo.f1 -->
>> <eventField>goo</eventField>
>> <eventField>f1</eventField>
>> </eventTarget>
>> <eventChanged/>
>> <eventReports>
>> <!-- report the new state of goo.f1 -->
>> <eventReport>
>> <eventField>goo</eventField>
>> <eventField>f1</eventField>
>> </eventReport>
>> </eventReports>
>> </event>
>>
>>
>> I am still confused about the <metadataDefs> general
applicability.
>> E.g., how are <inputPorts>, <outputPorts> used in I2RS?
>>
>> cheers,
>> jamal
>>
>>
>>
>> Andy
>>
>>
>