moving developers-guide to developer-guide for consistency
[docs.git] / manuals / developer-guide / src / main / asciidoc / ttp.adoc
1 == Table Type Patterns
2
3 IMPORTANT: This section assumes you have already downloaded the Karaf
4            distribution of OpenDaylight Helium and followed the
5            instructions in the Table Type Patterns section of the
6            Installation guide. If not, do that first.
7
8 === Introduction
9
10 Table Type Patterns are a specification developed by the
11 https://www.opennetworking.org/[Open Networking Foundation] to enable
12 the description and negotiation of subsets of the OpenFlow protocol.
13 This is particularly useful for hardware switches that support OpenFlow
14 as it enables the to describe what features they do (and thus also what
15 features they do not) support. More details can be found in the full
16 specification listed on the
17 https://www.opennetworking.org/sdn-resources/onf-specifications/openflow[OpenFlow
18 specifications page].
19 // for reasons that baffle me, I cannot link to:
20 // https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/OpenFlow%20Table%20Type%20Patterns%20v1.0.pdf
21 // it renders it as a link to a file ignoring the https part
22
23 ==== Support in Helium
24 In the Helium release, Table Type Patterns (TTPs) are exposed as a YANG
25 model for TTPs themselves which can be loaded into the MD-SAL Data
26 Store in three places:
27 // link to the MD-SAL Data Store docs?
28
29 . As one of a list of TTPs in the +opendaylight-ttps+ top-level
30   container.
31 . Attached to a +node+ in the +opendaylight-inventory+ model as an
32   +active_ttp+ via the +ttp-capable-node+ augmentation.
33 . Attached to a +node+ in the +opendaylight-inventory+ model as one of
34   a list of +supported_ttps+ via the +ttp-capable-node+ augmentation.
35 // link to the inventory docs somehow?
36
37 Each of these points can be accessed either through the RESTCONF-based
38 REST APIs or via the Java interface to the MD-SAL Data Store. This
39 discussion will focus on the REST APIs.
40
41 [NOTE]
42 ===============================
43 Developers who wish to use the Java interfaces are encouraged to to
44 first read and understand using the MD-SAL Data Store's APIs including
45 importing the appropriate bundles for to get models, dealing with
46 transactions, and constructing instance identifiers.
47
48 After that, it should be somewhat straightforward to translate the REST
49 API calls here into appropriate instance identifiers which can be used
50 in MD-SAL Data Store transactions.
51 ===============================
52
53 === Using The REST APIs
54
55 As stated above there are 3 locations where a Table Type Patter can be
56 placed into the MD-SAL Data Store. They correspond to 3 different REST
57 API URIs:
58
59 . +restconf/config/onf-ttp:opendaylight-ttps/onf-ttp:table-type-patterns/+
60 . +restconf/config/opendaylight-inventory:nodes/node/{id}/ttp-inventory-node:active_ttp/+
61 . +restconf/config/opendaylight-inventory:nodes/node/{id}/ttp-inventory-node:supported_ttps/+
62
63 [NOTE]
64 ===============================
65 Typically, these URIs are running on the machine the controller is on
66 at port 8181. If you are on the same machine they can thus be accessed
67 at +http://localhost:8181/<uri>+
68 ===============================
69
70 ==== Setting REST HTTP Headers
71
72 ===== Authentication
73
74 The REST API calls require authentication by default. The default
75 method is to use basic auth with a user name and password of `admin'.
76
77 ===== Content-Type and Accept
78
79 RESTCONF supports both xml and json. This example focuses on JSON, but
80 xml can be used just as easily. When doing a PUT or POST be sure to
81 specify the appropriate +Conetnt-Type+ header: either
82 +application/json+ or +application/xml+.
83
84 When doing a GET be sure to specify the appropriate +Accept+ header:
85 again, either +application/json+ or +application/xml+.
86
87 ==== Content
88
89 The contents of a PUT or POST should be a OpenDaylight Table Type
90 Pattern. An example of one is provided below. The example can also be
91 found at https://git.opendaylight.org/gerrit/gitweb?p=ttp.git;a=blob;f=parser/sample-TTP-from-tests.ttp;h=45130949b25c6f86b750959d27d04ec2208935fb;hb=HEAD[+parser/sample-TTP-from-tests.ttp+ in the TTP git repository].
92
93 .Sample Table Type Pattern (json)
94 -----------------------------------------------------
95 {
96     "table-type-patterns": {
97         "table-type-pattern": [
98             {
99                 "security": {
100                     "doc": [
101                         "This TTP is not published for use by ONF. It is an example and for",
102                         "illustrative purposes only.",
103                         "If this TTP were published for use it would include",
104                         "guidance as to any security considerations in this doc member."
105                     ]
106                 },
107                 "NDM_metadata": {
108                     "authority": "org.opennetworking.fawg",
109                     "OF_protocol_version": "1.3.3",
110                     "version": "1.0.0",
111                     "type": "TTPv1",
112                     "doc": [
113                         "Example of a TTP supporting L2 (unicast, multicast, flooding), L3 (unicast only),",
114                         "and an ACL table."
115                     ],
116                     "name": "L2-L3-ACLs"
117                 },
118                 "identifiers": [
119                     {
120                         "doc": [
121                             "The VLAN ID of a locally attached L2 subnet on a Router."
122                         ],
123                         "var": "<subnet_VID>"
124                     },
125                     {
126                         "doc": [
127                             "An OpenFlow group identifier (integer) identifying a group table entry",
128                             "of the type indicated by the variable name"
129                         ],
130                         "var": "<<group_entry_types/name>>"
131                     }
132                 ],
133                 "features": [
134                     {
135                         "doc": [
136                             "Flow entry notification Extension – notification of changes in flow entries"
137                         ],
138                         "feature": "ext187"
139                     },
140                     {
141                         "doc": [
142                             "Group notifications Extension – notification of changes in group or meter entries"
143                         ],
144                         "feature": "ext235"
145                     }
146                 ],
147                 "meter_table": {
148                     "meter_types": [
149                         {
150                             "name": "ControllerMeterType",
151                             "bands": [
152                                 {
153                                     "type": "DROP",
154                                     "rate": "1000..10000",
155                                     "burst": "50..200"
156                                 }
157                             ]
158                         },
159                         {
160                             "name": "TrafficMeter",
161                             "bands": [
162                                 {
163                                     "type": "DSCP_REMARK",
164                                     "rate": "10000..500000",
165                                     "burst": "50..500"
166                                 },
167                                 {
168                                     "type": "DROP",
169                                     "rate": "10000..500000",
170                                     "burst": "50..500"
171                                 }
172                             ]
173                         }
174                     ],
175                     "built_in_meters": [
176                         {
177                             "name": "ControllerMeter",
178                             "meter_id": 1,
179                             "type": "ControllerMeterType",
180                             "bands": [
181                                 {
182                                     "rate": 2000,
183                                     "burst": 75
184                                 }
185                             ]
186                         },
187                         {
188                             "name": "AllArpMeter",
189                             "meter_id": 2,
190                             "type": "ControllerMeterType",
191                             "bands": [
192                                 {
193                                     "rate": 1000,
194                                     "burst": 50
195                                 }
196                             ]
197                         }
198                     ]
199                 },
200                 "table_map": [
201                     {
202                         "name": "ControlFrame",
203                         "number": 0
204                     },
205                     {
206                         "name": "IngressVLAN",
207                         "number": 10
208                     },
209                     {
210                         "name": "MacLearning",
211                         "number": 20
212                     },
213                     {
214                         "name": "ACL",
215                         "number": 30
216                     },
217                     {
218                         "name": "L2",
219                         "number": 40
220                     },
221                     {
222                         "name": "ProtoFilter",
223                         "number": 50
224                     },
225                     {
226                         "name": "IPv4",
227                         "number": 60
228                     },
229                     {
230                         "name": "IPv6",
231                         "number": 80
232                     }
233                 ],
234                 "parameters": [
235                     {
236                         "doc": [
237                             "documentation"
238                         ],
239                         "name": "Showing-curt-how-this-works",
240                         "type": "type1"
241                     }
242                 ],
243                 "flow_tables": [
244                     {
245                         "doc": [
246                             "Filters L2 control reserved destination addresses and",
247                             "may forward control packets to the controller.",
248                             "Directs all other packets to the Ingress VLAN table."
249                         ],
250                         "name": "ControlFrame",
251                         "flow_mod_types": [
252                             {
253                                 "doc": [
254                                     "This match/action pair allows for flow_mods that match on either",
255                                     "ETH_TYPE or ETH_DST (or both) and send the packet to the",
256                                     "controller, subject to metering."
257                                 ],
258                                 "name": "Frame-To-Controller",
259                                 "match_set": [
260                                     {
261                                         "field": "ETH_TYPE",
262                                         "match_type": "all_or_exact"
263                                     },
264                                     {
265                                         "field": "ETH_DST",
266                                         "match_type": "exact"
267                                     }
268                                 ],
269                                 "instruction_set": [
270                                     {
271                                         "doc": [
272                                             "This meter may be used to limit the rate of PACKET_IN frames",
273                                             "sent to the controller"
274                                         ],
275                                         "instruction": "METER",
276                                         "meter_name": "ControllerMeter"
277                                     },
278                                     {
279                                         "instruction": "APPLY_ACTIONS",
280                                         "actions": [
281                                             {
282                                                 "action": "OUTPUT",
283                                                 "port": "CONTROLLER"
284                                             }
285                                         ]
286                                     }
287                                 ]
288                             }
289                         ],
290                         "built_in_flow_mods": [
291                             {
292                                 "doc": [
293                                     "Mandatory filtering of control frames with C-VLAN Bridge reserved DA."
294                                 ],
295                                 "name": "Control-Frame-Filter",
296                                 "priority": "1",
297                                 "match_set": [
298                                     {
299                                         "field": "ETH_DST",
300                                         "mask": "0xfffffffffff0",
301                                         "value": "0x0180C2000000"
302                                     }
303                                 ]
304                             },
305                             {
306                                 "doc": [
307                                     "Mandatory miss flow_mod, sends packets to IngressVLAN table."
308                                 ],
309                                 "name": "Non-Control-Frame",
310                                 "priority": "0",
311                                 "instruction_set": [
312                                     {
313                                         "instruction": "GOTO_TABLE",
314                                         "table": "IngressVLAN"
315                                     }
316                                 ]
317                             }
318                         ]
319                     }
320                 ],
321                 "group_entry_types": [
322                     {
323                         "doc": [
324                             "Output to a port, removing VLAN tag if needed.",
325                             "Entry per port, plus entry per untagged VID per port."
326                         ],
327                         "name": "EgressPort",
328                         "group_type": "INDIRECT",
329                         "bucket_types": [
330                             {
331                                 "name": "OutputTagged",
332                                 "action_set": [
333                                     {
334                                         "action": "OUTPUT",
335                                         "port": "<port_no>"
336                                     }
337                                 ]
338                             },
339                             {
340                                 "name": "OutputUntagged",
341                                 "action_set": [
342                                     {
343                                         "action": "POP_VLAN"
344                                     },
345                                     {
346                                         "action": "OUTPUT",
347                                         "port": "<port_no>"
348                                     }
349                                 ]
350                             },
351                             {
352                                 "opt_tag": "VID-X",
353                                 "name": "OutputVIDTranslate",
354                                 "action_set": [
355                                     {
356                                         "action": "SET_FIELD",
357                                         "field": "VLAN_VID",
358                                         "value": "<local_vid>"
359                                     },
360                                     {
361                                         "action": "OUTPUT",
362                                         "port": "<port_no>"
363                                     }
364                                 ]
365                             }
366                         ]
367                     }
368                 ],
369                 "flow_paths": [
370                     {
371                         "doc": [
372                             "This object contains just a few examples of flow paths, it is not",
373                             "a comprehensive list of the flow paths required for this TTP.  It is",
374                             "intended that the flow paths array could include either a list of",
375                             "required flow paths or a list of specific flow paths that are not",
376                             "required (whichever is more concise or more useful."
377                         ],
378                         "name": "L2-2",
379                         "path": [
380                             "Non-Control-Frame",
381                             "IV-pass",
382                             "Known-MAC",
383                             "ACLskip",
384                             "L2-Unicast",
385                             "EgressPort"
386                         ]
387                     },
388                     {
389                         "name": "L2-3",
390                         "path": [
391                             "Non-Control-Frame",
392                             "IV-pass",
393                             "Known-MAC",
394                             "ACLskip",
395                             "L2-Multicast",
396                             "L2Mcast",
397                             "[EgressPort]"
398                         ]
399                     },
400                     {
401                         "name": "L2-4",
402                         "path": [
403                             "Non-Control-Frame",
404                             "IV-pass",
405                             "Known-MAC",
406                             "ACL-skip",
407                             "VID-flood",
408                             "VIDflood",
409                             "[EgressPort]"
410                         ]
411                     },
412                     {
413                         "name": "L2-5",
414                         "path": [
415                             "Non-Control-Frame",
416                             "IV-pass",
417                             "Known-MAC",
418                             "ACLskip",
419                             "L2-Drop"
420                         ]
421                     },
422                     {
423                         "name": "v4-1",
424                         "path": [
425                             "Non-Control-Frame",
426                             "IV-pass",
427                             "Known-MAC",
428                             "ACLskip",
429                             "L2-Router-MAC",
430                             "IPv4",
431                             "v4-Unicast",
432                             "NextHop",
433                             "EgressPort"
434                         ]
435                     },
436                     {
437                         "name": "v4-2",
438                         "path": [
439                             "Non-Control-Frame",
440                             "IV-pass",
441                             "Known-MAC",
442                             "ACLskip",
443                             "L2-Router-MAC",
444                             "IPv4",
445                             "v4-Unicast-ECMP",
446                             "L3ECMP",
447                             "NextHop",
448                             "EgressPort"
449                         ]
450                     }
451                 ]
452             }
453         ]
454     }
455 }
456 -----------------------------------------------------
457
458 ==== Making a REST Call
459
460 In this example we'll do a PUT to install the sample TTP from above
461 into OpenDaylight and then retrieve it both as json and as xml. We'll
462 use the https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm[
463 Postman - REST Client] for Chrome in the examples, but any method of
464 accessing REST should work.
465
466 First, we'll fill in the basic information:
467
468 .Filling in URL, content, Content-Type and basic auth
469 image::ttp-screen1-basic-auth.png[width=500]
470
471 . Set the URL to +http://localhost:8181/restconf/config/onf-ttp:opendaylight-ttps/onf-ttp:table-type-patterns/+
472 . Set the action to +PUT+
473 . Click Headers and
474 . Set a header for +Content-Type+ to +application/json+
475 . Make sure the content is set to raw and
476 . Copy the sample TTP from above into the content
477 . Click the Basic Auth tab and
478 . Set the username and password to admin
479 . Click Refresh headers
480
481 .Refreshing basic auth headers
482 image::ttp-screen2-applied-basic-auth.png[width=500]
483
484 After clicking Refresh headers, we can see that a new header
485 (+Authorization+) has been created and this will allow us to
486 authenticate to make the rest call.
487
488 .PUTting a TTP
489 image::ttp-screen3-sent-put.png[width=500]
490
491 At this point, clicking send should result in a Status response of +200
492 OK+ indicating we've successfully PUT the TTP into OpenDaylight.
493
494 .Retrieving the TTP as json via a GET
495 image::ttp-screen4-get-json.png[width=500]
496
497 We can now retrieve the TTP by:
498
499 . Changing the action to +GET+
500 . Setting an +Accept+ header to +application/json+ and
501 . Pressing send
502
503 .Retrieving the TTP as xml via a GET
504 image::ttp-screen5-get-xml.png[width=500]
505
506 The same process can retrieve the content as xml by setting the
507 +Accept+ header to +application/xml+.
508
509 === Limitations
510
511 ==== Differences between OpenDaylight TTP and ONF TTP
512
513 The OpenDaylight YANG specification for TTPs differs from the ONF's
514 specification in a few areas. These differences are due to limitations
515 in the subsets of JSON that YANG schemas can be used to describe.
516
517 * *+doc+ members must always be lists and cannot be just a string*
518
519 For example, this is not allowed:
520
521 ----
522 "doc": "The VLAN ID of a locally attached L2 subnet on a Router."
523 ----
524
525 While this is:
526
527 ----
528 "doc": ["The VLAN ID of a locally attached L2 subnet on a Router."]
529 ----
530
531 [start=2]
532 * *+table_map+ formats differ*
533
534 In the ONF spec, the table_map looks like this
535
536 ----
537 "table_map": {
538   "ControlFrame": 0,
539   "IngressVLAN": 1,
540   "MacLearning": 2,
541   "L2": 3
542 },
543 ----
544
545 In the ODL TTP YANG definition, it would instead look like this:
546
547 ----
548 "table_map": [
549     { "name": "ControlFrame", "number": 0 },
550     { "name": "IngressVLAN",  "number": 1 },
551     { "name": "MacLearning",  "number": 2 },
552     { "name": "L2",           "number": 3 },
553 ],
554 ----
555
556 [start=3]
557 * *Limited meta member keywords*
558
559 The meta member keywords (+all+, +one_or_more+, +zero_or_more+,
560 +exactly_one+, and +zero_or_one+) are allowed anywhere in a TTP
561 according to the ONF specification, but they are only allowed in
562 specific locations in the ODL YANG schema. Specifically:
563
564 .. +all+, +one_or_more+, and +zero_or_more+ are allowed in the +flow_mod_types+ member
565 .. +exactly_one+ and +zero_or_one+ are allowed in the +match_set+ and
566    +instruction_set+ members as well as in in lists of actions.
567
568 [start=4]
569 * *+flow_paths+ repeated table syntax differs*
570
571 In the ONF TTP specification, the ability to repeat a table in a path
572 traversal of the tables is done by having the table be a list
573 containing the table name as a string. Like this:
574
575 ----
576 "flow_paths": ["path": ["table1", ["table2"] ] ]
577 ----
578
579 In the ODL YANG schema this is instead represented by moving the square
580 brackets inside the string as follows:
581
582 ----
583 flow_paths": ["path": ["table1", "[table2]" ] ]
584 ----
585
586 [start=5]
587 * *+priority+ and +priority_rank+ must be strings and can't be numbers.
588
589 The +priority+ and +priority_rank+ members are allowed to be either
590 strings or numbers in the ONF specification, but must be strings in the
591 ODL YANG schema.
592
593 * *Empty lists must be omitted*
594
595 Lists like this:
596
597 ----
598 "match_set": []
599 ----
600
601 must instead be omitted from the TTP.
602
603 ==== Strictly Informational
604
605 At this point in time the only operations available with TTPs are
606 storing and retrieving TTPs from the data store in the three previously
607 mentioned places.
608
609 Additional features that make use of and populate this information are
610 planned for future releases.
611
612 ==== Known issues
613
614 . Strings containing some special characters result in REST calls
615   returning a +400 Bad Request+ code. A string that contains both an
616   opening angle bracket (<) and a colon (:) with the angle bracket
617   appearing first is known to trigger this behavior.
618
619 For example this is known to break RESTCONF:
620
621 ----
622 "var": "<<group_entry_types:name>>"
623 ----
624
625 While these two work
626
627 ----
628 "var": "group_entry_types:name"
629 ----
630
631 ----
632 "var": "<<group_entry_types/name>>"
633 ----